1#![allow(unsafe_code)]
4
5use core::cell::UnsafeCell;
6use core::error::Error;
7use core::fmt;
8use core::future::Future;
9use core::marker::PhantomData;
10use core::mem::ManuallyDrop;
11use core::ops::{Deref, DerefMut};
12use core::pin::Pin;
13use core::ptr;
14use core::task::{Context, Poll};
15use std::sync::Arc;
16
17use super::internal;
18use super::raw_semaphore::{PermitWait, RawSemaphore};
19
20#[derive(Debug)]
32pub struct TryLockError(pub(crate) ());
33
34impl fmt::Display for TryLockError {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 f.write_str("operation would block")
37 }
38}
39
40impl Error for TryLockError {}
41
42pub struct Mutex<T: ?Sized> {
64 sem: RawSemaphore,
65 value: UnsafeCell<T>,
66}
67
68unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
70unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
73
74impl<T> Mutex<T> {
75 loom_const_fn! {
76 pub fn new(value: T) -> Self {
78 Self { sem: RawSemaphore::new(1), value: UnsafeCell::new(value) }
79 }
80 }
81
82 loom_const_fn! {
83 pub fn const_new(value: T) -> Self {
85 Self { sem: RawSemaphore::new(1), value: UnsafeCell::new(value) }
86 }
87 }
88
89 loom_const_fn! {
90 #[cfg(test)]
95 pub(crate) fn new_without_spin(value: T) -> Self {
96 Self { sem: RawSemaphore::without_spin(1), value: UnsafeCell::new(value) }
97 }
98 }
99
100 pub fn into_inner(self) -> T {
102 self.value.into_inner()
103 }
104}
105
106#[cfg(all(test, not(loom)))]
107impl<T: ?Sized> Mutex<T> {
108 pub(crate) fn spin_rounds(&self) -> u32 {
110 use super::queue::Policy;
111 self.sem.queue().spin.rounds()
112 }
113}
114
115impl<T: ?Sized> Mutex<T> {
116 #[inline]
118 fn try_acquire(&self) -> bool {
119 match self.sem.take_one() {
120 Ok(()) => true,
121 Err(seen) => self.sem.try_acquire_one_from(seen),
122 }
123 }
124
125 #[inline]
131 pub fn try_lock(&self) -> Result<MutexGuard<'_, T>, TryLockError> {
132 if self.try_acquire() {
133 Ok(MutexGuard::new(self))
134 } else {
135 Err(TryLockError(()))
136 }
137 }
138
139 pub fn try_lock_owned(self: Arc<Self>) -> Result<OwnedMutexGuard<T>, TryLockError> {
146 if self.try_acquire() {
147 Ok(OwnedMutexGuard {
148 mutex: self,
149 _value: PhantomData,
150 })
151 } else {
152 Err(TryLockError(()))
153 }
154 }
155
156 #[inline]
165 pub fn lock(&self) -> Lock<'_, T> {
166 Lock {
167 mutex: self,
168 wait: PermitWait::new(),
169 }
170 }
171
172 pub fn lock_owned(self: Arc<Self>) -> LockOwned<T> {
175 LockOwned {
176 mutex: self,
177 wait: PermitWait::new(),
178 }
179 }
180
181 pub fn blocking_lock(&self) -> MutexGuard<'_, T> {
192 internal::blocking(self.lock())
193 }
194
195 pub fn blocking_lock_owned(self: Arc<Self>) -> OwnedMutexGuard<T> {
202 internal::blocking(self.lock_owned())
203 }
204
205 pub fn get_mut(&mut self) -> &mut T {
207 self.value.get_mut()
208 }
209}
210
211impl<T> From<T> for Mutex<T> {
212 fn from(value: T) -> Self {
213 Self::new(value)
214 }
215}
216
217impl<T: Default> Default for Mutex<T> {
218 fn default() -> Self {
219 Self::new(T::default())
220 }
221}
222
223impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> {
224 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
225 let mut d = f.debug_struct("Mutex");
226 match self.try_lock() {
227 Ok(inner) => d.field("data", &&*inner),
228 Err(_) => d.field("data", &format_args!("<locked>")),
229 };
230 d.finish()
231 }
232}
233
234#[must_use = "dropping the guard unlocks the mutex at once"]
241pub struct MutexGuard<'a, T: ?Sized> {
242 mutex: &'a Mutex<T>,
243 _value: PhantomData<&'a mut T>,
245}
246
247impl<'a, T: ?Sized> MutexGuard<'a, T> {
248 fn new(mutex: &'a Mutex<T>) -> Self {
249 Self {
250 mutex,
251 _value: PhantomData,
252 }
253 }
254
255 fn into_mutex(self) -> &'a Mutex<T> {
258 ManuallyDrop::new(self).mutex
259 }
260
261 #[inline]
267 pub fn map<U, F>(mut this: Self, f: F) -> MappedMutexGuard<'a, U>
268 where
269 U: ?Sized,
270 F: FnOnce(&mut T) -> &mut U,
271 {
272 let data = ptr::from_mut(f(&mut *this));
273 let mutex = this.into_mutex();
274 MappedMutexGuard {
275 sem: &mutex.sem,
276 data,
277 _value: PhantomData,
278 }
279 }
280
281 #[inline]
284 pub fn try_map<U, F>(mut this: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
285 where
286 U: ?Sized,
287 F: FnOnce(&mut T) -> Option<&mut U>,
288 {
289 let data = match f(&mut *this) {
290 Some(data) => ptr::from_mut(data),
291 None => return Err(this),
292 };
293 let mutex = this.into_mutex();
294 Ok(MappedMutexGuard {
295 sem: &mutex.sem,
296 data,
297 _value: PhantomData,
298 })
299 }
300
301 #[inline]
304 pub fn mutex(this: &Self) -> &'a Mutex<T> {
305 this.mutex
306 }
307}
308
309impl<T: ?Sized> Deref for MutexGuard<'_, T> {
310 type Target = T;
311
312 fn deref(&self) -> &T {
313 unsafe { &*self.mutex.value.get() }
315 }
316}
317
318impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
319 fn deref_mut(&mut self) -> &mut T {
320 unsafe { &mut *self.mutex.value.get() }
322 }
323}
324
325impl<T: ?Sized> Drop for MutexGuard<'_, T> {
326 #[inline]
327 fn drop(&mut self) {
328 self.mutex.sem.release(1);
329 }
330}
331
332impl<T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
333 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
334 fmt::Debug::fmt(&**self, f)
335 }
336}
337
338impl<T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'_, T> {
339 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
340 fmt::Display::fmt(&**self, f)
341 }
342}
343
344#[must_use = "dropping the guard unlocks the mutex at once"]
347pub struct OwnedMutexGuard<T: ?Sized> {
348 mutex: Arc<Mutex<T>>,
349 _value: PhantomData<UnsafeCell<T>>,
351}
352
353unsafe impl<T: ?Sized + Send + Sync> Sync for OwnedMutexGuard<T> {}
355
356impl<T: ?Sized> OwnedMutexGuard<T> {
357 fn into_arc(self) -> Arc<Mutex<T>> {
360 let spent = ManuallyDrop::new(self);
361 unsafe { ptr::read(&spent.mutex) }
364 }
365
366 #[inline]
372 pub fn map<U, F>(mut this: Self, f: F) -> OwnedMappedMutexGuard<T, U>
373 where
374 U: ?Sized,
375 F: FnOnce(&mut T) -> &mut U,
376 {
377 let data = ptr::from_mut(f(&mut *this));
378 OwnedMappedMutexGuard {
379 mutex: this.into_arc(),
380 data,
381 }
382 }
383
384 #[inline]
387 pub fn try_map<U, F>(mut this: Self, f: F) -> Result<OwnedMappedMutexGuard<T, U>, Self>
388 where
389 U: ?Sized,
390 F: FnOnce(&mut T) -> Option<&mut U>,
391 {
392 let data = match f(&mut *this) {
393 Some(data) => ptr::from_mut(data),
394 None => return Err(this),
395 };
396 Ok(OwnedMappedMutexGuard {
397 mutex: this.into_arc(),
398 data,
399 })
400 }
401
402 #[inline]
404 pub fn mutex(this: &Self) -> &Arc<Mutex<T>> {
405 &this.mutex
406 }
407}
408
409impl<T: ?Sized> Deref for OwnedMutexGuard<T> {
410 type Target = T;
411
412 fn deref(&self) -> &T {
413 unsafe { &*self.mutex.value.get() }
415 }
416}
417
418impl<T: ?Sized> DerefMut for OwnedMutexGuard<T> {
419 fn deref_mut(&mut self) -> &mut T {
420 unsafe { &mut *self.mutex.value.get() }
422 }
423}
424
425impl<T: ?Sized> Drop for OwnedMutexGuard<T> {
426 #[inline]
427 fn drop(&mut self) {
428 self.mutex.sem.release(1);
429 }
430}
431
432impl<T: ?Sized + fmt::Debug> fmt::Debug for OwnedMutexGuard<T> {
433 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
434 fmt::Debug::fmt(&**self, f)
435 }
436}
437
438impl<T: ?Sized + fmt::Display> fmt::Display for OwnedMutexGuard<T> {
439 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
440 fmt::Display::fmt(&**self, f)
441 }
442}
443
444#[must_use = "dropping the guard unlocks the mutex at once"]
448pub struct MappedMutexGuard<'a, T: ?Sized> {
449 sem: &'a RawSemaphore,
450 data: *mut T,
451 _value: PhantomData<&'a mut T>,
453}
454
455unsafe impl<T: ?Sized + Sync> Sync for MappedMutexGuard<'_, T> {}
459unsafe impl<T: ?Sized + Send> Send for MappedMutexGuard<'_, T> {}
461
462impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
463 fn into_sem(self) -> &'a RawSemaphore {
466 ManuallyDrop::new(self).sem
467 }
468
469 #[inline]
475 pub fn map<U, F>(mut this: Self, f: F) -> MappedMutexGuard<'a, U>
476 where
477 U: ?Sized,
478 F: FnOnce(&mut T) -> &mut U,
479 {
480 let data = ptr::from_mut(f(&mut *this));
481 MappedMutexGuard {
482 sem: this.into_sem(),
483 data,
484 _value: PhantomData,
485 }
486 }
487
488 #[inline]
491 pub fn try_map<U, F>(mut this: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
492 where
493 U: ?Sized,
494 F: FnOnce(&mut T) -> Option<&mut U>,
495 {
496 let data = match f(&mut *this) {
497 Some(data) => ptr::from_mut(data),
498 None => return Err(this),
499 };
500 Ok(MappedMutexGuard {
501 sem: this.into_sem(),
502 data,
503 _value: PhantomData,
504 })
505 }
506}
507
508impl<T: ?Sized> Deref for MappedMutexGuard<'_, T> {
509 type Target = T;
510
511 fn deref(&self) -> &T {
512 unsafe { &*self.data }
515 }
516}
517
518impl<T: ?Sized> DerefMut for MappedMutexGuard<'_, T> {
519 fn deref_mut(&mut self) -> &mut T {
520 unsafe { &mut *self.data }
522 }
523}
524
525impl<T: ?Sized> Drop for MappedMutexGuard<'_, T> {
526 #[inline]
527 fn drop(&mut self) {
528 self.sem.release(1);
529 }
530}
531
532impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedMutexGuard<'_, T> {
533 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
534 fmt::Debug::fmt(&**self, f)
535 }
536}
537
538impl<T: ?Sized + fmt::Display> fmt::Display for MappedMutexGuard<'_, T> {
539 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
540 fmt::Display::fmt(&**self, f)
541 }
542}
543
544#[must_use = "dropping the guard unlocks the mutex at once"]
548pub struct OwnedMappedMutexGuard<T: ?Sized, U: ?Sized = T> {
549 mutex: Arc<Mutex<T>>,
550 data: *mut U,
551}
552
553unsafe impl<T: ?Sized + Send + Sync, U: ?Sized + Send + Sync> Sync for OwnedMappedMutexGuard<T, U> {}
556unsafe impl<T: ?Sized + Send, U: ?Sized + Send> Send for OwnedMappedMutexGuard<T, U> {}
558
559impl<T: ?Sized, U: ?Sized> OwnedMappedMutexGuard<T, U> {
560 fn into_arc(self) -> Arc<Mutex<T>> {
563 let spent = ManuallyDrop::new(self);
564 unsafe { ptr::read(&spent.mutex) }
567 }
568
569 #[inline]
575 pub fn map<S, F>(mut this: Self, f: F) -> OwnedMappedMutexGuard<T, S>
576 where
577 S: ?Sized,
578 F: FnOnce(&mut U) -> &mut S,
579 {
580 let data = ptr::from_mut(f(&mut *this));
581 OwnedMappedMutexGuard {
582 mutex: this.into_arc(),
583 data,
584 }
585 }
586
587 #[inline]
590 pub fn try_map<S, F>(mut this: Self, f: F) -> Result<OwnedMappedMutexGuard<T, S>, Self>
591 where
592 S: ?Sized,
593 F: FnOnce(&mut U) -> Option<&mut S>,
594 {
595 let data = match f(&mut *this) {
596 Some(data) => ptr::from_mut(data),
597 None => return Err(this),
598 };
599 Ok(OwnedMappedMutexGuard {
600 mutex: this.into_arc(),
601 data,
602 })
603 }
604}
605
606impl<T: ?Sized, U: ?Sized> Deref for OwnedMappedMutexGuard<T, U> {
607 type Target = U;
608
609 fn deref(&self) -> &U {
610 unsafe { &*self.data }
613 }
614}
615
616impl<T: ?Sized, U: ?Sized> DerefMut for OwnedMappedMutexGuard<T, U> {
617 fn deref_mut(&mut self) -> &mut U {
618 unsafe { &mut *self.data }
620 }
621}
622
623impl<T: ?Sized, U: ?Sized> Drop for OwnedMappedMutexGuard<T, U> {
624 #[inline]
625 fn drop(&mut self) {
626 self.mutex.sem.release(1);
627 }
628}
629
630impl<T: ?Sized, U: ?Sized + fmt::Debug> fmt::Debug for OwnedMappedMutexGuard<T, U> {
631 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
632 fmt::Debug::fmt(&**self, f)
633 }
634}
635
636impl<T: ?Sized, U: ?Sized + fmt::Display> fmt::Display for OwnedMappedMutexGuard<T, U> {
637 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
638 fmt::Display::fmt(&**self, f)
639 }
640}
641
642#[must_use = "futures do nothing unless polled"]
644pub struct Lock<'a, T: ?Sized> {
645 mutex: &'a Mutex<T>,
646 wait: PermitWait,
647}
648
649impl<'a, T: ?Sized> Future for Lock<'a, T> {
650 type Output = MutexGuard<'a, T>;
651
652 #[inline]
653 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<MutexGuard<'a, T>> {
654 let this = self.get_mut();
655 this.wait
656 .poll_one(&this.mutex.sem, cx.waker())
657 .map(|()| MutexGuard::new(this.mutex))
658 }
659}
660
661impl<T: ?Sized> Drop for Lock<'_, T> {
662 #[inline]
663 fn drop(&mut self) {
664 self.wait.cancel(&self.mutex.sem, 1);
665 }
666}
667
668impl<T: ?Sized> fmt::Debug for Lock<'_, T> {
669 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
670 f.debug_struct("Lock").finish_non_exhaustive()
671 }
672}
673
674#[must_use = "futures do nothing unless polled"]
676pub struct LockOwned<T: ?Sized> {
677 mutex: Arc<Mutex<T>>,
678 wait: PermitWait,
679}
680
681impl<T: ?Sized> Future for LockOwned<T> {
682 type Output = OwnedMutexGuard<T>;
683
684 #[inline]
685 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<OwnedMutexGuard<T>> {
686 let this = self.get_mut();
687 this.wait
688 .poll_one(&this.mutex.sem, cx.waker())
689 .map(|()| OwnedMutexGuard {
690 mutex: Arc::clone(&this.mutex),
691 _value: PhantomData,
692 })
693 }
694}
695
696impl<T: ?Sized> Drop for LockOwned<T> {
697 #[inline]
698 fn drop(&mut self) {
699 self.wait.cancel(&self.mutex.sem, 1);
700 }
701}
702
703impl<T: ?Sized> fmt::Debug for LockOwned<T> {
704 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
705 f.debug_struct("LockOwned").finish_non_exhaustive()
706 }
707}
708
709#[cfg(all(test, not(loom)))]
710mod tests {
711 use super::*;
712 use crate::sync::test_support::{Polled, block_on};
713
714 const ITERATIONS: usize = if cfg!(miri) { 20 } else { 5_000 };
715
716 #[test]
721 fn a_mutex_built_without_spin_never_spins() {
722 assert!(Mutex::new(()).spin_rounds() > 0, "a plain mutex spins");
723 let mutex = Mutex::new_without_spin(0u8);
724 assert_eq!(mutex.spin_rounds(), 0);
725 let held = mutex.try_lock().expect("free");
726 let mut waiter = Polled::new(mutex.lock());
727 waiter.pending();
728 drop(held);
729 assert_eq!(waiter.wakes(), 1);
730 *waiter.ready() += 1;
731 assert_eq!(mutex.spin_rounds(), 0, "the mutex never spins");
732 }
733
734 #[test]
735 fn releases_wake_waiters_in_arrival_order() {
736 let mutex = Mutex::new(Vec::new());
737 let held = mutex.try_lock().expect("free");
738 let mut waiters: Vec<_> = (0..3).map(|_| Polled::new(mutex.lock())).collect();
739 for waiter in &mut waiters {
740 waiter.pending();
741 }
742 drop(held);
743 for (i, waiter) in waiters.iter_mut().enumerate() {
744 assert_eq!(
745 waiter.wakes(),
746 1,
747 "waiter {i} is woken by the release before it"
748 );
749 let mut guard = waiter.ready();
750 guard.push(i);
751 assert!(mutex.try_lock().is_err(), "the woken waiter holds it");
752 }
753 assert_eq!(*mutex.try_lock().expect("free"), vec![0, 1, 2]);
754 }
755
756 #[test]
757 fn a_waiter_that_never_saw_its_grant_passes_the_lock_on() {
758 let mutex = Mutex::new(());
759 let held = mutex.try_lock().expect("free");
760 let mut first = Polled::new(mutex.lock());
761 first.pending();
762 let mut second = Polled::new(mutex.lock());
763 second.pending();
764 drop(held);
765 drop(first);
766 drop(second.ready());
767 assert!(mutex.try_lock().is_ok());
768 }
769
770 #[test]
771 fn a_waker_changed_between_polls_is_the_one_woken() {
772 let mutex = Mutex::new(());
773 let held = mutex.try_lock().expect("free");
774 let mut lock = core::pin::pin!(mutex.lock());
775 let first = Polled::new(core::future::pending::<()>());
776 let second = Polled::new(core::future::pending::<()>());
777 let poll_with = |lock: &mut Pin<&mut Lock<'_, ()>>, waker: &core::task::Waker| {
778 lock.as_mut()
779 .poll(&mut Context::from_waker(waker))
780 .is_pending()
781 };
782 let (first_waker, second_waker) = (first.waker(), second.waker());
783 assert!(poll_with(&mut lock, &first_waker));
784 assert!(poll_with(&mut lock, &second_waker));
785 drop(held);
786 assert_eq!((first.wakes(), second.wakes()), (0, 1));
787 assert!(!poll_with(&mut lock, &second_waker));
788 }
789
790 #[test]
791 fn owned_guards_and_get_mut() {
792 let mut mutex = Mutex::new(1);
793 *mutex.get_mut() += 1;
794 let mutex = Arc::new(mutex);
795 let guard = block_on(Arc::clone(&mutex).lock_owned());
796 let mut next = Polled::new(Arc::clone(&mutex).lock_owned());
797 next.pending();
798 assert_eq!(*guard, 2);
799 drop(guard);
800 assert_eq!(*next.ready(), 2);
801 }
802
803 #[test]
804 fn a_failed_try_lock_reports_it_would_block() {
805 let mutex = Arc::new(Mutex::new(0));
806 let held = Arc::clone(&mutex).try_lock_owned().expect("free");
807 let err = mutex.try_lock().unwrap_err();
808 assert_eq!(err.to_string(), "operation would block");
809 assert_eq!(format!("{err:?}"), "TryLockError(())");
810 assert!(Arc::clone(&mutex).try_lock_owned().is_err());
811 drop(held);
812 assert!(mutex.try_lock().is_ok());
813 }
814
815 #[test]
816 fn a_mapped_guard_keeps_the_lock_until_it_drops() {
817 let mutex = Arc::new(Mutex::new((1, String::from("a"))));
818 let mut number = MutexGuard::map(block_on(mutex.lock()), |pair| &mut pair.0);
819 *number += 1;
820 assert!(mutex.try_lock().is_err(), "the mapped guard holds the lock");
821 let mut waiter = Polled::new(mutex.lock());
822 waiter.pending();
823 drop(number);
824 assert_eq!(waiter.wakes(), 1);
825 assert_eq!(waiter.ready().0, 2);
826
827 let owned = OwnedMutexGuard::map(block_on(Arc::clone(&mutex).lock_owned()), |pair| {
828 &mut pair.1
829 });
830 let mut tail = OwnedMappedMutexGuard::map(owned, |text| text.as_mut_str());
831 tail.make_ascii_uppercase();
832 assert_eq!(&*tail, "A");
833 assert!(mutex.try_lock().is_err());
834 drop(tail);
835 assert_eq!(mutex.try_lock().expect("unlocked").1, "A");
836 }
837
838 #[test]
839 fn try_map_gives_the_guard_back_when_nothing_is_found() {
840 let mutex = Mutex::new(Some(5));
841 let guard = mutex.try_lock().expect("free");
842 let guard = MutexGuard::try_map(guard, |value| value.as_mut().filter(|n| **n > 9))
843 .expect_err("nothing to map");
844 assert!(mutex.try_lock().is_err(), "the lock is still held");
845 let mut mapped =
846 MutexGuard::try_map(guard, |value| value.as_mut()).expect("a five is there");
847 *mapped += 1;
848 let mapped = MappedMutexGuard::try_map(mapped, |n| (*n > 100).then_some(n))
849 .expect_err("six is small");
850 let mut mapped = MappedMutexGuard::map(mapped, |n| n);
851 *mapped += 1;
852 drop(mapped);
853 assert_eq!(mutex.into_inner(), Some(7));
854 }
855
856 #[test]
857 fn a_guard_names_its_mutex() {
858 let mutex = Arc::new(Mutex::new(3));
859 let guard = block_on(mutex.lock());
860 let same = MutexGuard::mutex(&guard);
861 assert!(core::ptr::eq(same, &*mutex));
862 drop(guard);
863 let owned = block_on(Arc::clone(&mutex).lock_owned());
864 assert!(Arc::ptr_eq(OwnedMutexGuard::mutex(&owned), &mutex));
865 assert_eq!(format!("{owned} {owned:?}"), "3 3");
866 }
867
868 #[test]
869 fn blocking_locks_wait_for_the_holder_on_another_thread() {
870 let mutex = Arc::new(Mutex::new(0));
871 let held = mutex.blocking_lock();
872 let waiter = {
873 let mutex = Arc::clone(&mutex);
874 std::thread::spawn(move || {
875 *mutex.blocking_lock() += 1;
876 *Arc::clone(&mutex).blocking_lock_owned() += 1;
877 })
878 };
879 drop(held);
880 waiter.join().expect("waiter");
881 assert_eq!(*mutex.try_lock().expect("free"), 2);
882 }
883
884 #[test]
885 fn a_const_mutex_and_conversions() {
886 static COUNTER: Mutex<u32> = Mutex::const_new(5);
887 *COUNTER.try_lock().expect("free") += 1;
888 assert_eq!(*COUNTER.try_lock().expect("free"), 6);
889 let from: Mutex<u8> = 9.into();
890 assert_eq!(from.into_inner(), 9);
891 assert_eq!(Mutex::<u8>::default().into_inner(), 0);
892 let mutex = Mutex::new(vec![1]);
893 assert_eq!(format!("{mutex:?}"), "Mutex { data: [1] }");
894 let held = mutex.try_lock().expect("free");
895 assert_eq!(format!("{mutex:?}"), "Mutex { data: <locked> }");
896 drop(held);
897 }
898
899 #[test]
900 fn threads_never_overlap_inside_the_lock() {
901 let mutex = Arc::new(Mutex::new(0usize));
902 let threads: Vec<_> = (0..4)
903 .map(|_| {
904 let mutex = Arc::clone(&mutex);
905 std::thread::spawn(move || {
906 for _ in 0..ITERATIONS {
907 let mut guard = block_on(mutex.lock());
908 let seen = *guard;
909 std::hint::spin_loop();
910 *guard = seen + 1;
911 }
912 })
913 })
914 .collect();
915 for thread in threads {
916 thread.join().expect("worker");
917 }
918 assert_eq!(*mutex.try_lock().expect("free"), 4 * ITERATIONS);
919 }
920}