|
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