|
15 | 15 |
|
16 | 16 | use std::int; |
17 | 17 | use std::sync::atomics; |
18 | | -use sync::mutex::{StaticMutex, MUTEX_INIT}; |
| 18 | + |
| 19 | +use mutex::{StaticMutex, MUTEX_INIT}; |
19 | 20 |
|
20 | 21 | /// A type which can be used to run a one-time global initialization. This type |
21 | 22 | /// is *unsafe* to use because it is built on top of the `Mutex` in this module. |
@@ -62,7 +63,7 @@ impl Once { |
62 | 63 | /// |
63 | 64 | /// When this function returns, it is guaranteed that some initialization |
64 | 65 | /// has run and completed (it may not be the closure specified). |
65 | | - pub fn doit(&mut self, f: ||) { |
| 66 | + pub fn doit(&self, f: ||) { |
66 | 67 | // Implementation-wise, this would seem like a fairly trivial primitive. |
67 | 68 | // The stickler part is where our mutexes currently require an |
68 | 69 | // allocation, and usage of a `Once` should't leak this allocation. |
@@ -101,14 +102,13 @@ impl Once { |
101 | 102 | // If the count is negative, then someone else finished the job, |
102 | 103 | // otherwise we run the job and record how many people will try to grab |
103 | 104 | // this lock |
104 | | - { |
105 | | - let _guard = self.mutex.lock(); |
106 | | - if self.cnt.load(atomics::SeqCst) > 0 { |
107 | | - f(); |
108 | | - let prev = self.cnt.swap(int::MIN, atomics::SeqCst); |
109 | | - self.lock_cnt.store(prev, atomics::SeqCst); |
110 | | - } |
| 105 | + let guard = self.mutex.lock(); |
| 106 | + if self.cnt.load(atomics::SeqCst) > 0 { |
| 107 | + f(); |
| 108 | + let prev = self.cnt.swap(int::MIN, atomics::SeqCst); |
| 109 | + self.lock_cnt.store(prev, atomics::SeqCst); |
111 | 110 | } |
| 111 | + drop(guard); |
112 | 112 |
|
113 | 113 | // Last one out cleans up after everyone else, no leaks! |
114 | 114 | if self.lock_cnt.fetch_add(-1, atomics::SeqCst) == 1 { |
|
0 commit comments