]> git.lizzy.rs Git - rust.git/blob - src/libstd/sync/mutex.rs
docs: Standardize on 'Errors' header in std docs
[rust.git] / src / libstd / sync / mutex.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use prelude::v1::*;
12
13 use cell::UnsafeCell;
14 use fmt;
15 use marker;
16 use mem;
17 use ops::{Deref, DerefMut};
18 use ptr;
19 use sys_common::mutex as sys;
20 use sys_common::poison::{self, TryLockError, TryLockResult, LockResult};
21
22 /// A mutual exclusion primitive useful for protecting shared data
23 ///
24 /// This mutex will block threads waiting for the lock to become available. The
25 /// mutex can also be statically initialized or created via a `new`
26 /// constructor. Each mutex has a type parameter which represents the data that
27 /// it is protecting. The data can only be accessed through the RAII guards
28 /// returned from `lock` and `try_lock`, which guarantees that the data is only
29 /// ever accessed when the mutex is locked.
30 ///
31 /// # Poisoning
32 ///
33 /// The mutexes in this module implement a strategy called "poisoning" where a
34 /// mutex is considered poisoned whenever a thread panics while holding the
35 /// lock. Once a mutex is poisoned, all other threads are unable to access the
36 /// data by default as it is likely tainted (some invariant is not being
37 /// upheld).
38 ///
39 /// For a mutex, this means that the `lock` and `try_lock` methods return a
40 /// `Result` which indicates whether a mutex has been poisoned or not. Most
41 /// usage of a mutex will simply `unwrap()` these results, propagating panics
42 /// among threads to ensure that a possibly invalid invariant is not witnessed.
43 ///
44 /// A poisoned mutex, however, does not prevent all access to the underlying
45 /// data. The `PoisonError` type has an `into_inner` method which will return
46 /// the guard that would have otherwise been returned on a successful lock. This
47 /// allows access to the data, despite the lock being poisoned.
48 ///
49 /// # Examples
50 ///
51 /// ```
52 /// use std::sync::{Arc, Mutex};
53 /// use std::thread;
54 /// use std::sync::mpsc::channel;
55 ///
56 /// const N: usize = 10;
57 ///
58 /// // Spawn a few threads to increment a shared variable (non-atomically), and
59 /// // let the main thread know once all increments are done.
60 /// //
61 /// // Here we're using an Arc to share memory among threads, and the data inside
62 /// // the Arc is protected with a mutex.
63 /// let data = Arc::new(Mutex::new(0));
64 ///
65 /// let (tx, rx) = channel();
66 /// for _ in 0..10 {
67 ///     let (data, tx) = (data.clone(), tx.clone());
68 ///     thread::spawn(move || {
69 ///         // The shared state can only be accessed once the lock is held.
70 ///         // Our non-atomic increment is safe because we're the only thread
71 ///         // which can access the shared state when the lock is held.
72 ///         //
73 ///         // We unwrap() the return value to assert that we are not expecting
74 ///         // threads to ever fail while holding the lock.
75 ///         let mut data = data.lock().unwrap();
76 ///         *data += 1;
77 ///         if *data == N {
78 ///             tx.send(()).unwrap();
79 ///         }
80 ///         // the lock is unlocked here when `data` goes out of scope.
81 ///     });
82 /// }
83 ///
84 /// rx.recv().unwrap();
85 /// ```
86 ///
87 /// To recover from a poisoned mutex:
88 ///
89 /// ```
90 /// use std::sync::{Arc, Mutex};
91 /// use std::thread;
92 ///
93 /// let lock = Arc::new(Mutex::new(0_u32));
94 /// let lock2 = lock.clone();
95 ///
96 /// let _ = thread::spawn(move || -> () {
97 ///     // This thread will acquire the mutex first, unwrapping the result of
98 ///     // `lock` because the lock has not been poisoned.
99 ///     let _lock = lock2.lock().unwrap();
100 ///
101 ///     // This panic while holding the lock (`_guard` is in scope) will poison
102 ///     // the mutex.
103 ///     panic!();
104 /// }).join();
105 ///
106 /// // The lock is poisoned by this point, but the returned result can be
107 /// // pattern matched on to return the underlying guard on both branches.
108 /// let mut guard = match lock.lock() {
109 ///     Ok(guard) => guard,
110 ///     Err(poisoned) => poisoned.into_inner(),
111 /// };
112 ///
113 /// *guard += 1;
114 /// ```
115 #[stable(feature = "rust1", since = "1.0.0")]
116 pub struct Mutex<T: ?Sized> {
117     // Note that this static mutex is in a *box*, not inlined into the struct
118     // itself. Once a native mutex has been used once, its address can never
119     // change (it can't be moved). This mutex type can be safely moved at any
120     // time, so to ensure that the native mutex is used correctly we box the
121     // inner lock to give it a constant address.
122     inner: Box<StaticMutex>,
123     data: UnsafeCell<T>,
124 }
125
126 // these are the only places where `T: Send` matters; all other
127 // functionality works fine on a single thread.
128 #[stable(feature = "rust1", since = "1.0.0")]
129 unsafe impl<T: ?Sized + Send> Send for Mutex<T> { }
130 #[stable(feature = "rust1", since = "1.0.0")]
131 unsafe impl<T: ?Sized + Send> Sync for Mutex<T> { }
132
133 /// The static mutex type is provided to allow for static allocation of mutexes.
134 ///
135 /// Note that this is a separate type because using a Mutex correctly means that
136 /// it needs to have a destructor run. In Rust, statics are not allowed to have
137 /// destructors. As a result, a `StaticMutex` has one extra method when compared
138 /// to a `Mutex`, a `destroy` method. This method is unsafe to call, and
139 /// documentation can be found directly on the method.
140 ///
141 /// # Examples
142 ///
143 /// ```
144 /// #![feature(static_mutex)]
145 ///
146 /// use std::sync::{StaticMutex, MUTEX_INIT};
147 ///
148 /// static LOCK: StaticMutex = MUTEX_INIT;
149 ///
150 /// {
151 ///     let _g = LOCK.lock().unwrap();
152 ///     // do some productive work
153 /// }
154 /// // lock is unlocked here.
155 /// ```
156 #[unstable(feature = "static_mutex",
157            reason = "may be merged with Mutex in the future",
158            issue = "27717")]
159 pub struct StaticMutex {
160     lock: sys::Mutex,
161     poison: poison::Flag,
162 }
163
164 /// An RAII implementation of a "scoped lock" of a mutex. When this structure is
165 /// dropped (falls out of scope), the lock will be unlocked.
166 ///
167 /// The data protected by the mutex can be access through this guard via its
168 /// `Deref` and `DerefMut` implementations
169 #[must_use]
170 #[stable(feature = "rust1", since = "1.0.0")]
171 pub struct MutexGuard<'a, T: ?Sized + 'a> {
172     // funny underscores due to how Deref/DerefMut currently work (they
173     // disregard field privacy).
174     __lock: &'a StaticMutex,
175     __data: &'a UnsafeCell<T>,
176     __poison: poison::Guard,
177 }
178
179 #[stable(feature = "rust1", since = "1.0.0")]
180 impl<'a, T: ?Sized> !marker::Send for MutexGuard<'a, T> {}
181
182 /// Static initialization of a mutex. This constant can be used to initialize
183 /// other mutex constants.
184 #[unstable(feature = "static_mutex",
185            reason = "may be merged with Mutex in the future",
186            issue = "27717")]
187 pub const MUTEX_INIT: StaticMutex = StaticMutex::new();
188
189 impl<T> Mutex<T> {
190     /// Creates a new mutex in an unlocked state ready for use.
191     #[stable(feature = "rust1", since = "1.0.0")]
192     pub fn new(t: T) -> Mutex<T> {
193         Mutex {
194             inner: box StaticMutex::new(),
195             data: UnsafeCell::new(t),
196         }
197     }
198 }
199
200 impl<T: ?Sized> Mutex<T> {
201     /// Acquires a mutex, blocking the current thread until it is able to do so.
202     ///
203     /// This function will block the local thread until it is available to acquire
204     /// the mutex. Upon returning, the thread is the only thread with the mutex
205     /// held. An RAII guard is returned to allow scoped unlock of the lock. When
206     /// the guard goes out of scope, the mutex will be unlocked.
207     ///
208     /// # Errors
209     ///
210     /// If another user of this mutex panicked while holding the mutex, then
211     /// this call will return an error once the mutex is acquired.
212     #[stable(feature = "rust1", since = "1.0.0")]
213     pub fn lock(&self) -> LockResult<MutexGuard<T>> {
214         unsafe { self.inner.lock.lock() }
215         MutexGuard::new(&*self.inner, &self.data)
216     }
217
218     /// Attempts to acquire this lock.
219     ///
220     /// If the lock could not be acquired at this time, then `Err` is returned.
221     /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
222     /// guard is dropped.
223     ///
224     /// This function does not block.
225     ///
226     /// # Errors
227     ///
228     /// If another user of this mutex panicked while holding the mutex, then
229     /// this call will return failure if the mutex would otherwise be
230     /// acquired.
231     #[stable(feature = "rust1", since = "1.0.0")]
232     pub fn try_lock(&self) -> TryLockResult<MutexGuard<T>> {
233         if unsafe { self.inner.lock.try_lock() } {
234             Ok(try!(MutexGuard::new(&*self.inner, &self.data)))
235         } else {
236             Err(TryLockError::WouldBlock)
237         }
238     }
239
240     /// Determines whether the lock is poisoned.
241     ///
242     /// If another thread is active, the lock can still become poisoned at any
243     /// time.  You should not trust a `false` value for program correctness
244     /// without additional synchronization.
245     #[inline]
246     #[stable(feature = "sync_poison", since = "1.2.0")]
247     pub fn is_poisoned(&self) -> bool {
248         self.inner.poison.get()
249     }
250
251     /// Consumes this mutex, returning the underlying data.
252     ///
253     /// # Errors
254     ///
255     /// If another user of this mutex panicked while holding the mutex, then
256     /// this call will return an error instead.
257     #[stable(feature = "mutex_into_inner", since = "1.6.0")]
258     pub fn into_inner(self) -> LockResult<T> where T: Sized {
259         // We know statically that there are no outstanding references to
260         // `self` so there's no need to lock the inner StaticMutex.
261         //
262         // To get the inner value, we'd like to call `data.into_inner()`,
263         // but because `Mutex` impl-s `Drop`, we can't move out of it, so
264         // we'll have to destructure it manually instead.
265         unsafe {
266             // Like `let Mutex { inner, data } = self`.
267             let (inner, data) = {
268                 let Mutex { ref inner, ref data } = self;
269                 (ptr::read(inner), ptr::read(data))
270             };
271             mem::forget(self);
272             inner.lock.destroy();  // Keep in sync with the `Drop` impl.
273
274             poison::map_result(inner.poison.borrow(), |_| data.into_inner())
275         }
276     }
277
278     /// Returns a mutable reference to the underlying data.
279     ///
280     /// Since this call borrows the `Mutex` mutably, no actual locking needs to
281     /// take place---the mutable borrow statically guarantees no locks exist.
282     ///
283     /// # Errors
284     ///
285     /// If another user of this mutex panicked while holding the mutex, then
286     /// this call will return an error instead.
287     #[stable(feature = "mutex_get_mut", since = "1.6.0")]
288     pub fn get_mut(&mut self) -> LockResult<&mut T> {
289         // We know statically that there are no other references to `self`, so
290         // there's no need to lock the inner StaticMutex.
291         let data = unsafe { &mut *self.data.get() };
292         poison::map_result(self.inner.poison.borrow(), |_| data )
293     }
294 }
295
296 #[stable(feature = "rust1", since = "1.0.0")]
297 impl<T: ?Sized> Drop for Mutex<T> {
298     #[unsafe_destructor_blind_to_params]
299     fn drop(&mut self) {
300         // This is actually safe b/c we know that there is no further usage of
301         // this mutex (it's up to the user to arrange for a mutex to get
302         // dropped, that's not our job)
303         //
304         // IMPORTANT: This code must be kept in sync with `Mutex::into_inner`.
305         unsafe { self.inner.lock.destroy() }
306     }
307 }
308
309 #[stable(feature = "rust1", since = "1.0.0")]
310 impl<T: ?Sized + fmt::Debug + 'static> fmt::Debug for Mutex<T> {
311     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
312         match self.try_lock() {
313             Ok(guard) => write!(f, "Mutex {{ data: {:?} }}", &*guard),
314             Err(TryLockError::Poisoned(err)) => {
315                 write!(f, "Mutex {{ data: Poisoned({:?}) }}", &**err.get_ref())
316             },
317             Err(TryLockError::WouldBlock) => write!(f, "Mutex {{ <locked> }}")
318         }
319     }
320 }
321
322 struct Dummy(UnsafeCell<()>);
323 unsafe impl Sync for Dummy {}
324 static DUMMY: Dummy = Dummy(UnsafeCell::new(()));
325
326 #[unstable(feature = "static_mutex",
327            reason = "may be merged with Mutex in the future",
328            issue = "27717")]
329 impl StaticMutex {
330     /// Creates a new mutex in an unlocked state ready for use.
331     pub const fn new() -> StaticMutex {
332         StaticMutex {
333             lock: sys::Mutex::new(),
334             poison: poison::Flag::new(),
335         }
336     }
337
338     /// Acquires this lock, see `Mutex::lock`
339     #[inline]
340     pub fn lock(&'static self) -> LockResult<MutexGuard<()>> {
341         unsafe { self.lock.lock() }
342         MutexGuard::new(self, &DUMMY.0)
343     }
344
345     /// Attempts to grab this lock, see `Mutex::try_lock`
346     #[inline]
347     pub fn try_lock(&'static self) -> TryLockResult<MutexGuard<()>> {
348         if unsafe { self.lock.try_lock() } {
349             Ok(try!(MutexGuard::new(self, &DUMMY.0)))
350         } else {
351             Err(TryLockError::WouldBlock)
352         }
353     }
354
355     /// Deallocates resources associated with this static mutex.
356     ///
357     /// This method is unsafe because it provides no guarantees that there are
358     /// no active users of this mutex, and safety is not guaranteed if there are
359     /// active users of this mutex.
360     ///
361     /// This method is required to ensure that there are no memory leaks on
362     /// *all* platforms. It may be the case that some platforms do not leak
363     /// memory if this method is not called, but this is not guaranteed to be
364     /// true on all platforms.
365     pub unsafe fn destroy(&'static self) {
366         self.lock.destroy()
367     }
368 }
369
370 impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
371
372     fn new(lock: &'mutex StaticMutex, data: &'mutex UnsafeCell<T>)
373            -> LockResult<MutexGuard<'mutex, T>> {
374         poison::map_result(lock.poison.borrow(), |guard| {
375             MutexGuard {
376                 __lock: lock,
377                 __data: data,
378                 __poison: guard,
379             }
380         })
381     }
382 }
383
384 #[stable(feature = "rust1", since = "1.0.0")]
385 impl<'mutex, T: ?Sized> Deref for MutexGuard<'mutex, T> {
386     type Target = T;
387
388     fn deref(&self) -> &T {
389         unsafe { &*self.__data.get() }
390     }
391 }
392
393 #[stable(feature = "rust1", since = "1.0.0")]
394 impl<'mutex, T: ?Sized> DerefMut for MutexGuard<'mutex, T> {
395     fn deref_mut(&mut self) -> &mut T {
396         unsafe { &mut *self.__data.get() }
397     }
398 }
399
400 #[stable(feature = "rust1", since = "1.0.0")]
401 impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> {
402     #[inline]
403     fn drop(&mut self) {
404         unsafe {
405             self.__lock.poison.done(&self.__poison);
406             self.__lock.lock.unlock();
407         }
408     }
409 }
410
411 pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex {
412     &guard.__lock.lock
413 }
414
415 pub fn guard_poison<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag {
416     &guard.__lock.poison
417 }
418
419 #[cfg(test)]
420 mod tests {
421     use prelude::v1::*;
422
423     use sync::mpsc::channel;
424     use sync::{Arc, Mutex, StaticMutex, Condvar};
425     use sync::atomic::{AtomicUsize, Ordering};
426     use thread;
427
428     struct Packet<T>(Arc<(Mutex<T>, Condvar)>);
429
430     #[derive(Eq, PartialEq, Debug)]
431     struct NonCopy(i32);
432
433     unsafe impl<T: Send> Send for Packet<T> {}
434     unsafe impl<T> Sync for Packet<T> {}
435
436     #[test]
437     fn smoke() {
438         let m = Mutex::new(());
439         drop(m.lock().unwrap());
440         drop(m.lock().unwrap());
441     }
442
443     #[test]
444     fn smoke_static() {
445         static M: StaticMutex = StaticMutex::new();
446         unsafe {
447             drop(M.lock().unwrap());
448             drop(M.lock().unwrap());
449             M.destroy();
450         }
451     }
452
453     #[test]
454     fn lots_and_lots() {
455         static M: StaticMutex = StaticMutex::new();
456         static mut CNT: u32 = 0;
457         const J: u32 = 1000;
458         const K: u32 = 3;
459
460         fn inc() {
461             for _ in 0..J {
462                 unsafe {
463                     let _g = M.lock().unwrap();
464                     CNT += 1;
465                 }
466             }
467         }
468
469         let (tx, rx) = channel();
470         for _ in 0..K {
471             let tx2 = tx.clone();
472             thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
473             let tx2 = tx.clone();
474             thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
475         }
476
477         drop(tx);
478         for _ in 0..2 * K {
479             rx.recv().unwrap();
480         }
481         assert_eq!(unsafe {CNT}, J * K * 2);
482         unsafe {
483             M.destroy();
484         }
485     }
486
487     #[test]
488     fn try_lock() {
489         let m = Mutex::new(());
490         *m.try_lock().unwrap() = ();
491     }
492
493     #[test]
494     fn test_into_inner() {
495         let m = Mutex::new(NonCopy(10));
496         assert_eq!(m.into_inner().unwrap(), NonCopy(10));
497     }
498
499     #[test]
500     fn test_into_inner_drop() {
501         struct Foo(Arc<AtomicUsize>);
502         impl Drop for Foo {
503             fn drop(&mut self) {
504                 self.0.fetch_add(1, Ordering::SeqCst);
505             }
506         }
507         let num_drops = Arc::new(AtomicUsize::new(0));
508         let m = Mutex::new(Foo(num_drops.clone()));
509         assert_eq!(num_drops.load(Ordering::SeqCst), 0);
510         {
511             let _inner = m.into_inner().unwrap();
512             assert_eq!(num_drops.load(Ordering::SeqCst), 0);
513         }
514         assert_eq!(num_drops.load(Ordering::SeqCst), 1);
515     }
516
517     #[test]
518     fn test_into_inner_poison() {
519         let m = Arc::new(Mutex::new(NonCopy(10)));
520         let m2 = m.clone();
521         let _ = thread::spawn(move || {
522             let _lock = m2.lock().unwrap();
523             panic!("test panic in inner thread to poison mutex");
524         }).join();
525
526         assert!(m.is_poisoned());
527         match Arc::try_unwrap(m).unwrap().into_inner() {
528             Err(e) => assert_eq!(e.into_inner(), NonCopy(10)),
529             Ok(x) => panic!("into_inner of poisoned Mutex is Ok: {:?}", x),
530         }
531     }
532
533     #[test]
534     fn test_get_mut() {
535         let mut m = Mutex::new(NonCopy(10));
536         *m.get_mut().unwrap() = NonCopy(20);
537         assert_eq!(m.into_inner().unwrap(), NonCopy(20));
538     }
539
540     #[test]
541     fn test_get_mut_poison() {
542         let m = Arc::new(Mutex::new(NonCopy(10)));
543         let m2 = m.clone();
544         let _ = thread::spawn(move || {
545             let _lock = m2.lock().unwrap();
546             panic!("test panic in inner thread to poison mutex");
547         }).join();
548
549         assert!(m.is_poisoned());
550         match Arc::try_unwrap(m).unwrap().get_mut() {
551             Err(e) => assert_eq!(*e.into_inner(), NonCopy(10)),
552             Ok(x) => panic!("get_mut of poisoned Mutex is Ok: {:?}", x),
553         }
554     }
555
556     #[test]
557     fn test_mutex_arc_condvar() {
558         let packet = Packet(Arc::new((Mutex::new(false), Condvar::new())));
559         let packet2 = Packet(packet.0.clone());
560         let (tx, rx) = channel();
561         let _t = thread::spawn(move|| {
562             // wait until parent gets in
563             rx.recv().unwrap();
564             let &(ref lock, ref cvar) = &*packet2.0;
565             let mut lock = lock.lock().unwrap();
566             *lock = true;
567             cvar.notify_one();
568         });
569
570         let &(ref lock, ref cvar) = &*packet.0;
571         let mut lock = lock.lock().unwrap();
572         tx.send(()).unwrap();
573         assert!(!*lock);
574         while !*lock {
575             lock = cvar.wait(lock).unwrap();
576         }
577     }
578
579     #[test]
580     fn test_arc_condvar_poison() {
581         let packet = Packet(Arc::new((Mutex::new(1), Condvar::new())));
582         let packet2 = Packet(packet.0.clone());
583         let (tx, rx) = channel();
584
585         let _t = thread::spawn(move || -> () {
586             rx.recv().unwrap();
587             let &(ref lock, ref cvar) = &*packet2.0;
588             let _g = lock.lock().unwrap();
589             cvar.notify_one();
590             // Parent should fail when it wakes up.
591             panic!();
592         });
593
594         let &(ref lock, ref cvar) = &*packet.0;
595         let mut lock = lock.lock().unwrap();
596         tx.send(()).unwrap();
597         while *lock == 1 {
598             match cvar.wait(lock) {
599                 Ok(l) => {
600                     lock = l;
601                     assert_eq!(*lock, 1);
602                 }
603                 Err(..) => break,
604             }
605         }
606     }
607
608     #[test]
609     fn test_mutex_arc_poison() {
610         let arc = Arc::new(Mutex::new(1));
611         assert!(!arc.is_poisoned());
612         let arc2 = arc.clone();
613         let _ = thread::spawn(move|| {
614             let lock = arc2.lock().unwrap();
615             assert_eq!(*lock, 2);
616         }).join();
617         assert!(arc.lock().is_err());
618         assert!(arc.is_poisoned());
619     }
620
621     #[test]
622     fn test_mutex_arc_nested() {
623         // Tests nested mutexes and access
624         // to underlying data.
625         let arc = Arc::new(Mutex::new(1));
626         let arc2 = Arc::new(Mutex::new(arc));
627         let (tx, rx) = channel();
628         let _t = thread::spawn(move|| {
629             let lock = arc2.lock().unwrap();
630             let lock2 = lock.lock().unwrap();
631             assert_eq!(*lock2, 1);
632             tx.send(()).unwrap();
633         });
634         rx.recv().unwrap();
635     }
636
637     #[test]
638     fn test_mutex_arc_access_in_unwind() {
639         let arc = Arc::new(Mutex::new(1));
640         let arc2 = arc.clone();
641         let _ = thread::spawn(move|| -> () {
642             struct Unwinder {
643                 i: Arc<Mutex<i32>>,
644             }
645             impl Drop for Unwinder {
646                 fn drop(&mut self) {
647                     *self.i.lock().unwrap() += 1;
648                 }
649             }
650             let _u = Unwinder { i: arc2 };
651             panic!();
652         }).join();
653         let lock = arc.lock().unwrap();
654         assert_eq!(*lock, 2);
655     }
656
657     #[test]
658     fn test_mutex_unsized() {
659         let mutex: &Mutex<[i32]> = &Mutex::new([1, 2, 3]);
660         {
661             let b = &mut *mutex.lock().unwrap();
662             b[0] = 4;
663             b[2] = 5;
664         }
665         let comp: &[i32] = &[4, 2, 5];
666         assert_eq!(&*mutex.lock().unwrap(), comp);
667     }
668 }