@@ -18,14 +18,18 @@ import unsafe::{Exclusive, exclusive};
18
18
* Internals
19
19
****************************************************************************/
20
20
21
- // Each waiting task receives on one of these. FIXME #3125 make these oneshot.
21
+ // Each waiting task receives on one of these.
22
+ #[ doc( hidden) ]
22
23
type wait_end = pipes:: port_one < ( ) > ;
24
+ #[ doc( hidden) ]
23
25
type signal_end = pipes:: chan_one < ( ) > ;
24
26
// A doubly-ended queue of waiting tasks.
27
+ #[ doc( hidden) ]
25
28
struct waitqueue { head : pipes:: port < signal_end > ;
26
29
tail: pipes:: chan<signal_end>; }
27
30
28
31
// Signals one live task from the queue.
32
+ #[ doc( hidden) ]
29
33
fn signal_waitqueue ( q : & waitqueue ) -> bool {
30
34
// The peek is mandatory to make sure recv doesn't block.
31
35
if q. head . peek ( ) {
@@ -41,6 +45,7 @@ fn signal_waitqueue(q: &waitqueue) -> bool {
41
45
}
42
46
}
43
47
48
+ #[ doc( hidden) ]
44
49
fn broadcast_waitqueue ( q : & waitqueue ) -> uint {
45
50
let mut count = 0 ;
46
51
while q. head . peek ( ) {
@@ -52,22 +57,26 @@ fn broadcast_waitqueue(q: &waitqueue) -> uint {
52
57
}
53
58
54
59
// The building-block used to make semaphores, mutexes, and rwlocks.
60
+ #[ doc( hidden) ]
55
61
struct sem_inner < Q > {
56
62
mut count : int ;
57
63
waiters: waitqueue;
58
64
// Can be either unit or another waitqueue. Some sems shouldn't come with
59
65
// a condition variable attached, others should.
60
66
blocked: Q ;
61
67
}
68
+ #[ doc( hidden) ]
62
69
enum sem< Q : send > = Exclusive < sem_inner<Q >>;
63
70
71
+ #[ doc( hidden) ]
64
72
fn new_sem<Q : send > ( count: int, +q: Q ) -> sem < Q > {
65
73
let ( wait_tail , wait_head ) = pipes:: stream ( ) ;
66
74
sem ( exclusive ( sem_inner {
67
75
mut count : count,
68
76
waiters : waitqueue { head : wait_head, tail : wait_tail } ,
69
77
blocked : q } ) )
70
78
}
79
+ #[ doc ( hidden) ]
71
80
fn new_sem_and_signal ( count : int , num_condvars : uint ) -> sem < ~[ waitqueue ] > {
72
81
let mut queues = ~[ ] ;
73
82
for num_condvars. times {
@@ -77,6 +86,7 @@ fn new_sem_and_signal(count: int, num_condvars: uint) -> sem<~[waitqueue]> {
77
86
new_sem( count, queues)
78
87
}
79
88
89
+ #[ doc( hidden) ]
80
90
impl < Q : send > & sem < Q > {
81
91
fn acquire( ) {
82
92
let mut waiter_nobe = none;
@@ -112,6 +122,7 @@ impl<Q: send> &sem<Q> {
112
122
}
113
123
}
114
124
// FIXME(#3154) move both copies of this into sem<Q>, and unify the 2 structs
125
+ #[ doc ( hidden ) ]
115
126
impl & sem < ( ) > {
116
127
fn access < U > ( blk : fn ( ) -> U ) -> U {
117
128
let mut release = none;
@@ -124,6 +135,7 @@ impl &sem<()> {
124
135
blk ( )
125
136
}
126
137
}
138
+ #[ doc ( hidden ) ]
127
139
impl & sem < ~[ waitqueue ] > {
128
140
fn access < U > ( blk : fn ( ) -> U ) -> U {
129
141
let mut release = none;
@@ -138,11 +150,13 @@ impl &sem<~[waitqueue]> {
138
150
}
139
151
140
152
// FIXME(#3136) should go inside of access()
153
+ #[ doc ( hidden ) ]
141
154
struct sem_release {
142
155
sem : & sem < ( ) > ;
143
156
new ( sem : & sem < ( ) > ) { self . sem = sem; }
144
157
drop { self . sem . release ( ) ; }
145
158
}
159
+ #[ doc( hidden) ]
146
160
struct sem_and_signal_release {
147
161
sem : & sem < ~[ waitqueue ] > ;
148
162
new ( sem : & sem < ~[ waitqueue ] > ) { self . sem = sem; }
@@ -153,7 +167,14 @@ struct sem_and_signal_release {
153
167
struct condvar { priv sem: & sem<~[ waitqueue] >; drop { } }
154
168
155
169
impl & condvar {
156
- /// Atomically drop the associated lock, and block until a signal is sent.
170
+ /**
171
+ * Atomically drop the associated lock, and block until a signal is sent.
172
+ *
173
+ * # Failure
174
+ * A task which is killed (i.e., by linked failure with another task)
175
+ * while waiting on a condition variable will wake up, fail, and unlock
176
+ * the associated lock as it unwinds.
177
+ */
157
178
fn wait( ) { self . wait_on( 0 ) }
158
179
/**
159
180
* As wait(), but can specify which of multiple condition variables to
@@ -267,6 +288,7 @@ impl &condvar {
267
288
// Checks whether a condvar ID was out of bounds, and fails if so, or does
268
289
// something else next on success.
269
290
#[ inline( always) ]
291
+ #[ doc( hidden) ]
270
292
fn check_cvar_bounds < U > ( out_of_bounds : option < uint > , id : uint , act : & str ,
271
293
blk : fn ( ) -> U ) -> U {
272
294
match out_of_bounds {
@@ -280,6 +302,7 @@ fn check_cvar_bounds<U>(out_of_bounds: option<uint>, id: uint, act: &str,
280
302
}
281
303
}
282
304
305
+ #[ doc( hidden) ]
283
306
impl & sem < ~[ waitqueue ] > {
284
307
// The only other place that condvars get built is rwlock_write_mode.
285
308
fn access_cond < U > ( blk : fn ( c : & condvar ) -> U ) -> U {
@@ -316,7 +339,6 @@ impl &semaphore {
316
339
fn release ( ) { ( & self . sem ) . release ( ) }
317
340
318
341
/// Run a function with ownership of one of the semaphore's resources.
319
- // FIXME(#3145): figure out whether or not this should get exported.
320
342
fn access < U > ( blk : fn ( ) -> U ) -> U { ( & self . sem ) . access ( blk) }
321
343
}
322
344
@@ -327,7 +349,10 @@ impl &semaphore {
327
349
/**
328
350
* A blocking, bounded-waiting, mutual exclusion lock with an associated
329
351
* FIFO condition variable.
330
- * FIXME(#3145): document killability
352
+ *
353
+ * # Failure
354
+ * A task which fails while holding a mutex will unlock the mutex as it
355
+ * unwinds.
331
356
*/
332
357
struct mutex { priv sem: sem < ~[ waitqueue ] > ; }
333
358
@@ -362,12 +387,19 @@ impl &mutex {
362
387
363
388
// NB: Uncyclopedia - Readers-writers_problem#The_third_readers-writers_problem
364
389
390
+ #[ doc( hidden) ]
365
391
struct rwlock_inner {
366
392
read_mode : bool ;
367
393
read_count: uint;
368
394
}
369
395
370
- /// A blocking, no-starvation, reader-writer lock with an associated condvar.
396
+ /**
397
+ * A blocking, no-starvation, reader-writer lock with an associated condvar.
398
+ *
399
+ * # Failure
400
+ * A task which fails while holding an rwlock will unlock the rwlock as it
401
+ * unwinds.
402
+ */
371
403
struct rwlock {
372
404
/* priv */ order_lock : semaphore ;
373
405
/* priv */ access_lock: sem < ~[ waitqueue ] > ;
@@ -527,6 +559,7 @@ impl &rwlock {
527
559
}
528
560
529
561
// FIXME(#3136) should go inside of read()
562
+ #[ doc( hidden) ]
530
563
struct rwlock_release_read {
531
564
lock: & rwlock;
532
565
new( lock: & rwlock) { self . lock = lock; }
@@ -550,6 +583,7 @@ struct rwlock_release_read {
550
583
}
551
584
552
585
// FIXME(#3136) should go inside of downgrade()
586
+ #[ doc( hidden) ]
553
587
struct rwlock_release_downgrade {
554
588
lock: & rwlock;
555
589
new( lock: & rwlock) { self . lock = lock; }
@@ -580,8 +614,7 @@ struct rwlock_release_downgrade {
580
614
}
581
615
582
616
/// The "write permission" token used for rwlock.write_downgrade().
583
- // FIXME(#3145): make lock priv somehow
584
- struct rwlock_write_mode { lock: & rwlock; drop { } }
617
+ struct rwlock_write_mode { /* priv */ lock: & rwlock; drop { } }
585
618
/// The "read permission" token used for rwlock.write_downgrade().
586
619
struct rwlock_read_mode { priv lock: & rwlock; drop { } }
587
620
0 commit comments