Skip to content

Commit 4c9f168

Browse files
committed
Convert sync to the new struct syntax
1 parent 770a212 commit 4c9f168

File tree

2 files changed

+51
-50
lines changed

2 files changed

+51
-50
lines changed

src/libcore/sync.rs

Lines changed: 50 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@
55
* in std.
66
*/
77

8-
export condvar;
9-
export semaphore, new_semaphore;
10-
export mutex, new_mutex;
11-
export rwlock;
8+
export condvar, semaphore, mutex, rwlock;
129

1310
// FIXME (#3119) This shouldn't be a thing exported from core.
1411
import arc::exclusive;
@@ -21,8 +18,8 @@ import arc::exclusive;
2118
type wait_end = pipes::port<()>;
2219
type signal_end = pipes::chan<()>;
2320
// A doubly-ended queue of waiting tasks.
24-
type waitqueue = { head: pipes::port<signal_end>,
25-
tail: pipes::chan<signal_end> };
21+
struct waitqueue { head: pipes::port<signal_end>;
22+
tail: pipes::chan<signal_end>; }
2623

2724
// Signals one live task from the queue.
2825
fn signal_waitqueue(q: &waitqueue) -> bool {
@@ -51,23 +48,25 @@ fn broadcast_waitqueue(q: &waitqueue) -> uint {
5148
}
5249

5350
// The building-block used to make semaphores, mutexes, and rwlocks.
54-
enum sem<Q: send> = exclusive<{
55-
mut count: int,
56-
waiters: waitqueue,
51+
struct sem_inner<Q> {
52+
mut count: int;
53+
waiters: waitqueue;
5754
// Can be either unit or another waitqueue. Some sems shouldn't come with
5855
// a condition variable attached, others should.
59-
blocked: Q,
60-
}>;
56+
blocked: Q;
57+
}
58+
enum sem<Q: send> = exclusive<sem_inner<Q>>;
6159

6260
fn new_sem<Q: send>(count: int, +q: Q) -> sem<Q> {
6361
let (wait_tail, wait_head) = pipes::stream();
64-
sem(exclusive({ mut count: count,
65-
waiters: { head: wait_head, tail: wait_tail },
66-
blocked: q }))
62+
sem(exclusive(sem_inner {
63+
mut count: count,
64+
waiters: waitqueue { head: wait_head, tail: wait_tail },
65+
blocked: q }))
6766
}
6867
fn new_sem_and_signal(count: int) -> sem<waitqueue> {
6968
let (block_tail, block_head) = pipes::stream();
70-
new_sem(count, { head: block_head, tail: block_tail })
69+
new_sem(count, waitqueue { head: block_head, tail: block_tail })
7170
}
7271

7372
impl<Q: send> &sem<Q> {
@@ -143,7 +142,7 @@ struct sem_and_signal_release {
143142
}
144143

145144
/// A mechanism for atomic-unlock-and-deschedule blocking and signalling.
146-
enum condvar = &sem<waitqueue>;
145+
struct condvar { priv sem: &sem<waitqueue>; }
147146

148147
impl condvar {
149148
/// Atomically drop the associated lock, and block until a signal is sent.
@@ -158,10 +157,10 @@ impl condvar {
158157
// killed before or after enqueueing. Deciding whether to
159158
// unkillably reacquire the lock needs to happen atomically
160159
// wrt enqueuing.
161-
reacquire = some(sem_and_signal_reacquire(*self));
160+
reacquire = some(sem_and_signal_reacquire(self.sem));
162161

163162
// Release lock, 'atomically' enqueuing ourselves in so doing.
164-
do (***self).with |state| {
163+
do (**self.sem).with |state| {
165164
// Drop the lock.
166165
// FIXME(#3145) investigate why factoring doesn't compile.
167166
state.count += 1;
@@ -196,7 +195,7 @@ impl condvar {
196195
/// Wake up a blocked task. Returns false if there was no blocked task.
197196
fn signal() -> bool {
198197
unsafe {
199-
do (***self).with |state| {
198+
do (**self.sem).with |state| {
200199
signal_waitqueue(&state.blocked)
201200
}
202201
}
@@ -205,7 +204,7 @@ impl condvar {
205204
/// Wake up all blocked tasks. Returns the number of tasks woken.
206205
fn broadcast() -> uint {
207206
unsafe {
208-
do (***self).with |state| {
207+
do (**self.sem).with |state| {
209208
// FIXME(#3145) fix :broadcast_heavy
210209
broadcast_waitqueue(&state.blocked)
211210
}
@@ -215,7 +214,7 @@ impl condvar {
215214

216215
impl &sem<waitqueue> {
217216
fn access_cond<U>(blk: fn(condvar) -> U) -> U {
218-
do self.access { blk(condvar(self)) }
217+
do self.access { blk(condvar { sem: self }) }
219218
}
220219
}
221220

@@ -224,30 +223,32 @@ impl &sem<waitqueue> {
224223
****************************************************************************/
225224

226225
/// A counting, blocking, bounded-waiting semaphore.
227-
enum semaphore = sem<()>;
226+
struct semaphore { priv sem: sem<()>; }
228227

229228
/// Create a new semaphore with the specified count.
230-
fn new_semaphore(count: int) -> semaphore { semaphore(new_sem(count, ())) }
229+
fn semaphore(count: int) -> semaphore {
230+
semaphore { sem: new_sem(count, ()) }
231+
}
231232

232233
impl &semaphore {
233234
/// Create a new handle to the semaphore.
234-
fn clone() -> semaphore { semaphore(sem((***self).clone())) }
235+
fn clone() -> semaphore { semaphore { sem: sem((*self.sem).clone()) } }
235236

236237
/**
237238
* Acquire a resource represented by the semaphore. Blocks if necessary
238239
* until resource(s) become available.
239240
*/
240-
fn acquire() { (&**self).acquire() }
241+
fn acquire() { (&self.sem).acquire() }
241242

242243
/**
243244
* Release a held resource represented by the semaphore. Wakes a blocked
244245
* contending task, if any exist. Won't block the caller.
245246
*/
246-
fn release() { (&**self).release() }
247+
fn release() { (&self.sem).release() }
247248

248249
/// Run a function with ownership of one of the semaphore's resources.
249250
// FIXME(#3145): figure out whether or not this should get exported.
250-
fn access<U>(blk: fn() -> U) -> U { (&**self).access(blk) }
251+
fn access<U>(blk: fn() -> U) -> U { (&self.sem).access(blk) }
251252
}
252253

253254
/****************************************************************************
@@ -259,21 +260,21 @@ impl &semaphore {
259260
* FIFO condition variable.
260261
* FIXME(#3145): document killability
261262
*/
262-
enum mutex = sem<waitqueue>;
263+
struct mutex { priv sem: sem<waitqueue>; }
263264

264265
/// Create a new mutex.
265-
fn new_mutex() -> mutex { mutex(new_sem_and_signal(1)) }
266+
fn mutex() -> mutex { mutex { sem: new_sem_and_signal(1) } }
266267

267268
impl &mutex {
268269
/// Create a new handle to the mutex.
269-
fn clone() -> mutex { mutex(sem((***self).clone())) }
270+
fn clone() -> mutex { mutex { sem: sem((*self.sem).clone()) } }
270271

271272
/// Run a function with ownership of the mutex.
272-
fn lock<U>(blk: fn() -> U) -> U { (&**self).access(blk) }
273+
fn lock<U>(blk: fn() -> U) -> U { (&self.sem).access(blk) }
273274

274275
/// Run a function with ownership of the mutex and a handle to a condvar.
275276
fn lock_cond<U>(blk: fn(condvar) -> U) -> U {
276-
(&**self).access_cond(blk)
277+
(&self.sem).access_cond(blk)
277278
}
278279
}
279280

@@ -290,14 +291,14 @@ struct rwlock_inner {
290291

291292
/// A blocking, no-starvation, reader-writer lock with an associated condvar.
292293
struct rwlock {
293-
order_lock: semaphore;
294-
access_lock: sem<waitqueue>;
295-
state: arc::exclusive<rwlock_inner>;
294+
/* priv */ order_lock: semaphore;
295+
/* priv */ access_lock: sem<waitqueue>;
296+
/* priv */ state: arc::exclusive<rwlock_inner>;
296297
}
297298

298299
/// Create a new rwlock.
299300
fn rwlock() -> rwlock {
300-
rwlock { order_lock: new_semaphore(1), access_lock: new_sem_and_signal(1),
301+
rwlock { order_lock: semaphore(1), access_lock: new_sem_and_signal(1),
301302
state: arc::exclusive(rwlock_inner { read_mode: false,
302303
read_count: 0 }) }
303304
}
@@ -399,19 +400,19 @@ mod tests {
399400
************************************************************************/
400401
#[test]
401402
fn test_sem_acquire_release() {
402-
let s = ~new_semaphore(1);
403+
let s = ~semaphore(1);
403404
s.acquire();
404405
s.release();
405406
s.acquire();
406407
}
407408
#[test]
408409
fn test_sem_basic() {
409-
let s = ~new_semaphore(1);
410+
let s = ~semaphore(1);
410411
do s.access { }
411412
}
412413
#[test]
413414
fn test_sem_as_mutex() {
414-
let s = ~new_semaphore(1);
415+
let s = ~semaphore(1);
415416
let s2 = ~s.clone();
416417
do task::spawn {
417418
do s2.access {
@@ -426,7 +427,7 @@ mod tests {
426427
fn test_sem_as_cvar() {
427428
/* Child waits and parent signals */
428429
let (c,p) = pipes::stream();
429-
let s = ~new_semaphore(0);
430+
let s = ~semaphore(0);
430431
let s2 = ~s.clone();
431432
do task::spawn {
432433
s2.acquire();
@@ -438,7 +439,7 @@ mod tests {
438439

439440
/* Parent waits and child signals */
440441
let (c,p) = pipes::stream();
441-
let s = ~new_semaphore(0);
442+
let s = ~semaphore(0);
442443
let s2 = ~s.clone();
443444
do task::spawn {
444445
for 5.times { task::yield(); }
@@ -452,7 +453,7 @@ mod tests {
452453
fn test_sem_multi_resource() {
453454
// Parent and child both get in the critical section at the same
454455
// time, and shake hands.
455-
let s = ~new_semaphore(2);
456+
let s = ~semaphore(2);
456457
let s2 = ~s.clone();
457458
let (c1,p1) = pipes::stream();
458459
let (c2,p2) = pipes::stream();
@@ -472,7 +473,7 @@ mod tests {
472473
// Force the runtime to schedule two threads on the same sched_loop.
473474
// When one blocks, it should schedule the other one.
474475
do task::spawn_sched(task::manual_threads(1)) {
475-
let s = ~new_semaphore(1);
476+
let s = ~semaphore(1);
476477
let s2 = ~s.clone();
477478
let (c,p) = pipes::stream();
478479
let child_data = ~mut some((s2,c));
@@ -497,7 +498,7 @@ mod tests {
497498
// Unsafely achieve shared state, and do the textbook
498499
// "load tmp <- ptr; inc tmp; store ptr <- tmp" dance.
499500
let (c,p) = pipes::stream();
500-
let m = ~new_mutex();
501+
let m = ~mutex();
501502
let m2 = ~m.clone();
502503
let sharedstate = ~0;
503504
let ptr = ptr::addr_of(*sharedstate);
@@ -523,7 +524,7 @@ mod tests {
523524
}
524525
#[test]
525526
fn test_mutex_cond_wait() {
526-
let m = ~new_mutex();
527+
let m = ~mutex();
527528

528529
// Child wakes up parent
529530
do m.lock_cond |cond| {
@@ -555,7 +556,7 @@ mod tests {
555556
}
556557
#[cfg(test)]
557558
fn test_mutex_cond_broadcast_helper(num_waiters: uint) {
558-
let m = ~new_mutex();
559+
let m = ~mutex();
559560
let mut ports = ~[];
560561

561562
for num_waiters.times {
@@ -590,7 +591,7 @@ mod tests {
590591
}
591592
#[test]
592593
fn test_mutex_cond_no_waiter() {
593-
let m = ~new_mutex();
594+
let m = ~mutex();
594595
let m2 = ~m.clone();
595596
do task::try {
596597
do m.lock_cond |_x| { }
@@ -602,7 +603,7 @@ mod tests {
602603
#[test] #[ignore(cfg(windows))]
603604
fn test_mutex_killed_simple() {
604605
// Mutex must get automatically unlocked if failed/killed within.
605-
let m = ~new_mutex();
606+
let m = ~mutex();
606607
let m2 = ~m.clone();
607608

608609
let result: result::result<(),()> = do task::try {
@@ -618,7 +619,7 @@ mod tests {
618619
fn test_mutex_killed_cond() {
619620
// Getting killed during cond wait must not corrupt the mutex while
620621
// unwinding (e.g. double unlock).
621-
let m = ~new_mutex();
622+
let m = ~mutex();
622623
let m2 = ~m.clone();
623624

624625
let result: result::result<(),()> = do task::try {

src/test/compile-fail/sync-cond-shouldnt-escape.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// error-pattern: reference is not valid outside of its lifetime
22
fn main() {
3-
let m = ~sync::new_mutex();
3+
let m = ~sync::mutex();
44
let mut cond = none;
55
do m.lock_cond |c| {
66
cond = some(c);

0 commit comments

Comments
 (0)