1 // Copyright 2018 Amanieu d'Antras 2 // 3 // Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or 4 // http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or 5 // http://opensource.org/licenses/MIT>, at your option. This file may not be 6 // copied, modified, or distributed except according to those terms. 7 8 use core::cell::UnsafeCell; 9 use core::fmt; 10 use core::marker::PhantomData; 11 use core::mem; 12 use core::ops::{Deref, DerefMut}; 13 14 #[cfg(feature = "arc_lock")] 15 use alloc::sync::Arc; 16 #[cfg(feature = "arc_lock")] 17 use core::mem::ManuallyDrop; 18 #[cfg(feature = "arc_lock")] 19 use core::ptr; 20 21 #[cfg(feature = "owning_ref")] 22 use owning_ref::StableAddress; 23 24 #[cfg(feature = "serde")] 25 use serde::{Deserialize, Deserializer, Serialize, Serializer}; 26 27 /// Basic operations for a mutex. 28 /// 29 /// Types implementing this trait can be used by `Mutex` to form a safe and 30 /// fully-functioning mutex type. 31 /// 32 /// # Safety 33 /// 34 /// Implementations of this trait must ensure that the mutex is actually 35 /// exclusive: a lock can't be acquired while the mutex is already locked. 36 pub unsafe trait RawMutex { 37 /// Initial value for an unlocked mutex. 38 // A “non-constant” const item is a legacy way to supply an initialized value to downstream 39 // static items. Can hopefully be replaced with `const fn new() -> Self` at some point. 40 #[allow(clippy::declare_interior_mutable_const)] 41 const INIT: Self; 42 43 /// Marker type which determines whether a lock guard should be `Send`. Use 44 /// one of the `GuardSend` or `GuardNoSend` helper types here. 45 type GuardMarker; 46 47 /// Acquires this mutex, blocking the current thread until it is able to do so. lock(&self)48 fn lock(&self); 49 50 /// Attempts to acquire this mutex without blocking. Returns `true` 51 /// if the lock was successfully acquired and `false` otherwise. try_lock(&self) -> bool52 fn try_lock(&self) -> bool; 53 54 /// Unlocks this mutex. 55 /// 56 /// # Safety 57 /// 58 /// This method may only be called if the mutex is held in the current context, i.e. it must 59 /// be paired with a successful call to [`lock`], [`try_lock`], [`try_lock_for`] or [`try_lock_until`]. 60 /// 61 /// [`lock`]: #tymethod.lock 62 /// [`try_lock`]: #tymethod.try_lock 63 /// [`try_lock_for`]: trait.RawMutexTimed.html#tymethod.try_lock_for 64 /// [`try_lock_until`]: trait.RawMutexTimed.html#tymethod.try_lock_until unlock(&self)65 unsafe fn unlock(&self); 66 67 /// Checks whether the mutex is currently locked. 68 #[inline] is_locked(&self) -> bool69 fn is_locked(&self) -> bool { 70 let acquired_lock = self.try_lock(); 71 if acquired_lock { 72 // Safety: The lock has been successfully acquired above. 73 unsafe { 74 self.unlock(); 75 } 76 } 77 !acquired_lock 78 } 79 } 80 81 /// Additional methods for mutexes which support fair unlocking. 82 /// 83 /// Fair unlocking means that a lock is handed directly over to the next waiting 84 /// thread if there is one, without giving other threads the opportunity to 85 /// "steal" the lock in the meantime. This is typically slower than unfair 86 /// unlocking, but may be necessary in certain circumstances. 87 pub unsafe trait RawMutexFair: RawMutex { 88 /// Unlocks this mutex using a fair unlock protocol. 89 /// 90 /// # Safety 91 /// 92 /// This method may only be called if the mutex is held in the current context, see 93 /// the documentation of [`unlock`]. 94 /// 95 /// [`unlock`]: trait.RawMutex.html#tymethod.unlock unlock_fair(&self)96 unsafe fn unlock_fair(&self); 97 98 /// Temporarily yields the mutex to a waiting thread if there is one. 99 /// 100 /// This method is functionally equivalent to calling `unlock_fair` followed 101 /// by `lock`, however it can be much more efficient in the case where there 102 /// are no waiting threads. 103 /// 104 /// # Safety 105 /// 106 /// This method may only be called if the mutex is held in the current context, see 107 /// the documentation of [`unlock`]. 108 /// 109 /// [`unlock`]: trait.RawMutex.html#tymethod.unlock bump(&self)110 unsafe fn bump(&self) { 111 self.unlock_fair(); 112 self.lock(); 113 } 114 } 115 116 /// Additional methods for mutexes which support locking with timeouts. 117 /// 118 /// The `Duration` and `Instant` types are specified as associated types so that 119 /// this trait is usable even in `no_std` environments. 120 pub unsafe trait RawMutexTimed: RawMutex { 121 /// Duration type used for `try_lock_for`. 122 type Duration; 123 124 /// Instant type used for `try_lock_until`. 125 type Instant; 126 127 /// Attempts to acquire this lock until a timeout is reached. try_lock_for(&self, timeout: Self::Duration) -> bool128 fn try_lock_for(&self, timeout: Self::Duration) -> bool; 129 130 /// Attempts to acquire this lock until a timeout is reached. try_lock_until(&self, timeout: Self::Instant) -> bool131 fn try_lock_until(&self, timeout: Self::Instant) -> bool; 132 } 133 134 /// A mutual exclusion primitive useful for protecting shared data 135 /// 136 /// This mutex will block threads waiting for the lock to become available. The 137 /// mutex can also be statically initialized or created via a `new` 138 /// constructor. Each mutex has a type parameter which represents the data that 139 /// it is protecting. The data can only be accessed through the RAII guards 140 /// returned from `lock` and `try_lock`, which guarantees that the data is only 141 /// ever accessed when the mutex is locked. 142 pub struct Mutex<R, T: ?Sized> { 143 raw: R, 144 data: UnsafeCell<T>, 145 } 146 147 unsafe impl<R: RawMutex + Send, T: ?Sized + Send> Send for Mutex<R, T> {} 148 unsafe impl<R: RawMutex + Sync, T: ?Sized + Send> Sync for Mutex<R, T> {} 149 150 impl<R: RawMutex, T> Mutex<R, T> { 151 /// Creates a new mutex in an unlocked state ready for use. 152 #[cfg(has_const_fn_trait_bound)] 153 #[inline] new(val: T) -> Mutex<R, T>154 pub const fn new(val: T) -> Mutex<R, T> { 155 Mutex { 156 raw: R::INIT, 157 data: UnsafeCell::new(val), 158 } 159 } 160 161 /// Creates a new mutex in an unlocked state ready for use. 162 #[cfg(not(has_const_fn_trait_bound))] 163 #[inline] new(val: T) -> Mutex<R, T>164 pub fn new(val: T) -> Mutex<R, T> { 165 Mutex { 166 raw: R::INIT, 167 data: UnsafeCell::new(val), 168 } 169 } 170 171 /// Consumes this mutex, returning the underlying data. 172 #[inline] into_inner(self) -> T173 pub fn into_inner(self) -> T { 174 self.data.into_inner() 175 } 176 } 177 178 impl<R, T> Mutex<R, T> { 179 /// Creates a new mutex based on a pre-existing raw mutex. 180 /// 181 /// This allows creating a mutex in a constant context on stable Rust. 182 #[inline] const_new(raw_mutex: R, val: T) -> Mutex<R, T>183 pub const fn const_new(raw_mutex: R, val: T) -> Mutex<R, T> { 184 Mutex { 185 raw: raw_mutex, 186 data: UnsafeCell::new(val), 187 } 188 } 189 } 190 191 impl<R: RawMutex, T: ?Sized> Mutex<R, T> { 192 /// Creates a new `MutexGuard` without checking if the mutex is locked. 193 /// 194 /// # Safety 195 /// 196 /// This method must only be called if the thread logically holds the lock. 197 /// 198 /// Calling this function when a guard has already been produced is undefined behaviour unless 199 /// the guard was forgotten with `mem::forget`. 200 #[inline] make_guard_unchecked(&self) -> MutexGuard<'_, R, T>201 pub unsafe fn make_guard_unchecked(&self) -> MutexGuard<'_, R, T> { 202 MutexGuard { 203 mutex: self, 204 marker: PhantomData, 205 } 206 } 207 208 /// Acquires a mutex, blocking the current thread until it is able to do so. 209 /// 210 /// This function will block the local thread until it is available to acquire 211 /// the mutex. Upon returning, the thread is the only thread with the mutex 212 /// held. An RAII guard is returned to allow scoped unlock of the lock. When 213 /// the guard goes out of scope, the mutex will be unlocked. 214 /// 215 /// Attempts to lock a mutex in the thread which already holds the lock will 216 /// result in a deadlock. 217 #[inline] lock(&self) -> MutexGuard<'_, R, T>218 pub fn lock(&self) -> MutexGuard<'_, R, T> { 219 self.raw.lock(); 220 // SAFETY: The lock is held, as required. 221 unsafe { self.make_guard_unchecked() } 222 } 223 224 /// Attempts to acquire this lock. 225 /// 226 /// If the lock could not be acquired at this time, then `None` is returned. 227 /// Otherwise, an RAII guard is returned. The lock will be unlocked when the 228 /// guard is dropped. 229 /// 230 /// This function does not block. 231 #[inline] try_lock(&self) -> Option<MutexGuard<'_, R, T>>232 pub fn try_lock(&self) -> Option<MutexGuard<'_, R, T>> { 233 if self.raw.try_lock() { 234 // SAFETY: The lock is held, as required. 235 Some(unsafe { self.make_guard_unchecked() }) 236 } else { 237 None 238 } 239 } 240 241 /// Returns a mutable reference to the underlying data. 242 /// 243 /// Since this call borrows the `Mutex` mutably, no actual locking needs to 244 /// take place---the mutable borrow statically guarantees no locks exist. 245 #[inline] get_mut(&mut self) -> &mut T246 pub fn get_mut(&mut self) -> &mut T { 247 unsafe { &mut *self.data.get() } 248 } 249 250 /// Checks whether the mutex is currently locked. 251 #[inline] is_locked(&self) -> bool252 pub fn is_locked(&self) -> bool { 253 self.raw.is_locked() 254 } 255 256 /// Forcibly unlocks the mutex. 257 /// 258 /// This is useful when combined with `mem::forget` to hold a lock without 259 /// the need to maintain a `MutexGuard` object alive, for example when 260 /// dealing with FFI. 261 /// 262 /// # Safety 263 /// 264 /// This method must only be called if the current thread logically owns a 265 /// `MutexGuard` but that guard has been discarded using `mem::forget`. 266 /// Behavior is undefined if a mutex is unlocked when not locked. 267 #[inline] force_unlock(&self)268 pub unsafe fn force_unlock(&self) { 269 self.raw.unlock(); 270 } 271 272 /// Returns the underlying raw mutex object. 273 /// 274 /// Note that you will most likely need to import the `RawMutex` trait from 275 /// `lock_api` to be able to call functions on the raw mutex. 276 /// 277 /// # Safety 278 /// 279 /// This method is unsafe because it allows unlocking a mutex while 280 /// still holding a reference to a `MutexGuard`. 281 #[inline] raw(&self) -> &R282 pub unsafe fn raw(&self) -> &R { 283 &self.raw 284 } 285 286 /// Returns a raw pointer to the underlying data. 287 /// 288 /// This is useful when combined with `mem::forget` to hold a lock without 289 /// the need to maintain a `MutexGuard` object alive, for example when 290 /// dealing with FFI. 291 /// 292 /// # Safety 293 /// 294 /// You must ensure that there are no data races when dereferencing the 295 /// returned pointer, for example if the current thread logically owns 296 /// a `MutexGuard` but that guard has been discarded using `mem::forget`. 297 #[inline] data_ptr(&self) -> *mut T298 pub fn data_ptr(&self) -> *mut T { 299 self.data.get() 300 } 301 302 /// Creates a new `ArcMutexGuard` without checking if the mutex is locked. 303 /// 304 /// # Safety 305 /// 306 /// This method must only be called if the thread logically holds the lock. 307 /// 308 /// Calling this function when a guard has already been produced is undefined behaviour unless 309 /// the guard was forgotten with `mem::forget`. 310 #[cfg(feature = "arc_lock")] 311 #[inline] make_arc_guard_unchecked(self: &Arc<Self>) -> ArcMutexGuard<R, T>312 unsafe fn make_arc_guard_unchecked(self: &Arc<Self>) -> ArcMutexGuard<R, T> { 313 ArcMutexGuard { 314 mutex: self.clone(), 315 marker: PhantomData, 316 } 317 } 318 319 /// Acquires a lock through an `Arc`. 320 /// 321 /// This method is similar to the `lock` method; however, it requires the `Mutex` to be inside of an `Arc` 322 /// and the resulting mutex guard has no lifetime requirements. 323 #[cfg(feature = "arc_lock")] 324 #[inline] lock_arc(self: &Arc<Self>) -> ArcMutexGuard<R, T>325 pub fn lock_arc(self: &Arc<Self>) -> ArcMutexGuard<R, T> { 326 self.raw.lock(); 327 // SAFETY: the locking guarantee is upheld 328 unsafe { self.make_arc_guard_unchecked() } 329 } 330 331 /// Attempts to acquire a lock through an `Arc`. 332 /// 333 /// This method is similar to the `try_lock` method; however, it requires the `Mutex` to be inside of an 334 /// `Arc` and the resulting mutex guard has no lifetime requirements. 335 #[cfg(feature = "arc_lock")] 336 #[inline] try_lock_arc(self: &Arc<Self>) -> Option<ArcMutexGuard<R, T>>337 pub fn try_lock_arc(self: &Arc<Self>) -> Option<ArcMutexGuard<R, T>> { 338 if self.raw.try_lock() { 339 // SAFETY: locking guarantee is upheld 340 Some(unsafe { self.make_arc_guard_unchecked() }) 341 } else { 342 None 343 } 344 } 345 } 346 347 impl<R: RawMutexFair, T: ?Sized> Mutex<R, T> { 348 /// Forcibly unlocks the mutex using a fair unlock procotol. 349 /// 350 /// This is useful when combined with `mem::forget` to hold a lock without 351 /// the need to maintain a `MutexGuard` object alive, for example when 352 /// dealing with FFI. 353 /// 354 /// # Safety 355 /// 356 /// This method must only be called if the current thread logically owns a 357 /// `MutexGuard` but that guard has been discarded using `mem::forget`. 358 /// Behavior is undefined if a mutex is unlocked when not locked. 359 #[inline] force_unlock_fair(&self)360 pub unsafe fn force_unlock_fair(&self) { 361 self.raw.unlock_fair(); 362 } 363 } 364 365 impl<R: RawMutexTimed, T: ?Sized> Mutex<R, T> { 366 /// Attempts to acquire this lock until a timeout is reached. 367 /// 368 /// If the lock could not be acquired before the timeout expired, then 369 /// `None` is returned. Otherwise, an RAII guard is returned. The lock will 370 /// be unlocked when the guard is dropped. 371 #[inline] try_lock_for(&self, timeout: R::Duration) -> Option<MutexGuard<'_, R, T>>372 pub fn try_lock_for(&self, timeout: R::Duration) -> Option<MutexGuard<'_, R, T>> { 373 if self.raw.try_lock_for(timeout) { 374 // SAFETY: The lock is held, as required. 375 Some(unsafe { self.make_guard_unchecked() }) 376 } else { 377 None 378 } 379 } 380 381 /// Attempts to acquire this lock until a timeout is reached. 382 /// 383 /// If the lock could not be acquired before the timeout expired, then 384 /// `None` is returned. Otherwise, an RAII guard is returned. The lock will 385 /// be unlocked when the guard is dropped. 386 #[inline] try_lock_until(&self, timeout: R::Instant) -> Option<MutexGuard<'_, R, T>>387 pub fn try_lock_until(&self, timeout: R::Instant) -> Option<MutexGuard<'_, R, T>> { 388 if self.raw.try_lock_until(timeout) { 389 // SAFETY: The lock is held, as required. 390 Some(unsafe { self.make_guard_unchecked() }) 391 } else { 392 None 393 } 394 } 395 396 /// Attempts to acquire this lock through an `Arc` until a timeout is reached. 397 /// 398 /// This method is similar to the `try_lock_for` method; however, it requires the `Mutex` to be inside of an 399 /// `Arc` and the resulting mutex guard has no lifetime requirements. 400 #[cfg(feature = "arc_lock")] 401 #[inline] try_lock_arc_for(self: &Arc<Self>, timeout: R::Duration) -> Option<ArcMutexGuard<R, T>>402 pub fn try_lock_arc_for(self: &Arc<Self>, timeout: R::Duration) -> Option<ArcMutexGuard<R, T>> { 403 if self.raw.try_lock_for(timeout) { 404 // SAFETY: locking guarantee is upheld 405 Some(unsafe { self.make_arc_guard_unchecked() }) 406 } else { 407 None 408 } 409 } 410 411 /// Attempts to acquire this lock through an `Arc` until a timeout is reached. 412 /// 413 /// This method is similar to the `try_lock_until` method; however, it requires the `Mutex` to be inside of 414 /// an `Arc` and the resulting mutex guard has no lifetime requirements. 415 #[cfg(feature = "arc_lock")] 416 #[inline] try_lock_arc_until( self: &Arc<Self>, timeout: R::Instant, ) -> Option<ArcMutexGuard<R, T>>417 pub fn try_lock_arc_until( 418 self: &Arc<Self>, 419 timeout: R::Instant, 420 ) -> Option<ArcMutexGuard<R, T>> { 421 if self.raw.try_lock_until(timeout) { 422 // SAFETY: locking guarantee is upheld 423 Some(unsafe { self.make_arc_guard_unchecked() }) 424 } else { 425 None 426 } 427 } 428 } 429 430 impl<R: RawMutex, T: ?Sized + Default> Default for Mutex<R, T> { 431 #[inline] default() -> Mutex<R, T>432 fn default() -> Mutex<R, T> { 433 Mutex::new(Default::default()) 434 } 435 } 436 437 impl<R: RawMutex, T> From<T> for Mutex<R, T> { 438 #[inline] from(t: T) -> Mutex<R, T>439 fn from(t: T) -> Mutex<R, T> { 440 Mutex::new(t) 441 } 442 } 443 444 impl<R: RawMutex, T: ?Sized + fmt::Debug> fmt::Debug for Mutex<R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result445 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 446 match self.try_lock() { 447 Some(guard) => f.debug_struct("Mutex").field("data", &&*guard).finish(), 448 None => { 449 struct LockedPlaceholder; 450 impl fmt::Debug for LockedPlaceholder { 451 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 452 f.write_str("<locked>") 453 } 454 } 455 456 f.debug_struct("Mutex") 457 .field("data", &LockedPlaceholder) 458 .finish() 459 } 460 } 461 } 462 } 463 464 // Copied and modified from serde 465 #[cfg(feature = "serde")] 466 impl<R, T> Serialize for Mutex<R, T> 467 where 468 R: RawMutex, 469 T: Serialize + ?Sized, 470 { serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,471 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 472 where 473 S: Serializer, 474 { 475 self.lock().serialize(serializer) 476 } 477 } 478 479 #[cfg(feature = "serde")] 480 impl<'de, R, T> Deserialize<'de> for Mutex<R, T> 481 where 482 R: RawMutex, 483 T: Deserialize<'de> + ?Sized, 484 { deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,485 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 486 where 487 D: Deserializer<'de>, 488 { 489 Deserialize::deserialize(deserializer).map(Mutex::new) 490 } 491 } 492 493 /// An RAII implementation of a "scoped lock" of a mutex. When this structure is 494 /// dropped (falls out of scope), the lock will be unlocked. 495 /// 496 /// The data protected by the mutex can be accessed through this guard via its 497 /// `Deref` and `DerefMut` implementations. 498 #[clippy::has_significant_drop] 499 #[must_use = "if unused the Mutex will immediately unlock"] 500 pub struct MutexGuard<'a, R: RawMutex, T: ?Sized> { 501 mutex: &'a Mutex<R, T>, 502 marker: PhantomData<(&'a mut T, R::GuardMarker)>, 503 } 504 505 unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync for MutexGuard<'a, R, T> {} 506 507 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> { 508 /// Returns a reference to the original `Mutex` object. mutex(s: &Self) -> &'a Mutex<R, T>509 pub fn mutex(s: &Self) -> &'a Mutex<R, T> { 510 s.mutex 511 } 512 513 /// Makes a new `MappedMutexGuard` for a component of the locked data. 514 /// 515 /// This operation cannot fail as the `MutexGuard` passed 516 /// in already locked the mutex. 517 /// 518 /// This is an associated function that needs to be 519 /// used as `MutexGuard::map(...)`. A method would interfere with methods of 520 /// the same name on the contents of the locked data. 521 #[inline] map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> where F: FnOnce(&mut T) -> &mut U,522 pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> 523 where 524 F: FnOnce(&mut T) -> &mut U, 525 { 526 let raw = &s.mutex.raw; 527 let data = f(unsafe { &mut *s.mutex.data.get() }); 528 mem::forget(s); 529 MappedMutexGuard { 530 raw, 531 data, 532 marker: PhantomData, 533 } 534 } 535 536 /// Attempts to make a new `MappedMutexGuard` for a component of the 537 /// locked data. The original guard is returned if the closure returns `None`. 538 /// 539 /// This operation cannot fail as the `MutexGuard` passed 540 /// in already locked the mutex. 541 /// 542 /// This is an associated function that needs to be 543 /// used as `MutexGuard::try_map(...)`. A method would interfere with methods of 544 /// the same name on the contents of the locked data. 545 #[inline] try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> where F: FnOnce(&mut T) -> Option<&mut U>,546 pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> 547 where 548 F: FnOnce(&mut T) -> Option<&mut U>, 549 { 550 let raw = &s.mutex.raw; 551 let data = match f(unsafe { &mut *s.mutex.data.get() }) { 552 Some(data) => data, 553 None => return Err(s), 554 }; 555 mem::forget(s); 556 Ok(MappedMutexGuard { 557 raw, 558 data, 559 marker: PhantomData, 560 }) 561 } 562 563 /// Temporarily unlocks the mutex to execute the given function. 564 /// 565 /// This is safe because `&mut` guarantees that there exist no other 566 /// references to the data protected by the mutex. 567 #[inline] unlocked<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,568 pub fn unlocked<F, U>(s: &mut Self, f: F) -> U 569 where 570 F: FnOnce() -> U, 571 { 572 // Safety: A MutexGuard always holds the lock. 573 unsafe { 574 s.mutex.raw.unlock(); 575 } 576 defer!(s.mutex.raw.lock()); 577 f() 578 } 579 580 /// Leaks the mutex guard and returns a mutable reference to the data 581 /// protected by the mutex. 582 /// 583 /// This will leave the `Mutex` in a locked state. 584 #[inline] leak(s: Self) -> &'a mut T585 pub fn leak(s: Self) -> &'a mut T { 586 let r = unsafe { &mut *s.mutex.data.get() }; 587 mem::forget(s); 588 r 589 } 590 } 591 592 impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> { 593 /// Unlocks the mutex using a fair unlock protocol. 594 /// 595 /// By default, mutexes are unfair and allow the current thread to re-lock 596 /// the mutex before another has the chance to acquire the lock, even if 597 /// that thread has been blocked on the mutex for a long time. This is the 598 /// default because it allows much higher throughput as it avoids forcing a 599 /// context switch on every mutex unlock. This can result in one thread 600 /// acquiring a mutex many more times than other threads. 601 /// 602 /// However in some cases it can be beneficial to ensure fairness by forcing 603 /// the lock to pass on to a waiting thread if there is one. This is done by 604 /// using this method instead of dropping the `MutexGuard` normally. 605 #[inline] unlock_fair(s: Self)606 pub fn unlock_fair(s: Self) { 607 // Safety: A MutexGuard always holds the lock. 608 unsafe { 609 s.mutex.raw.unlock_fair(); 610 } 611 mem::forget(s); 612 } 613 614 /// Temporarily unlocks the mutex to execute the given function. 615 /// 616 /// The mutex is unlocked using a fair unlock protocol. 617 /// 618 /// This is safe because `&mut` guarantees that there exist no other 619 /// references to the data protected by the mutex. 620 #[inline] unlocked_fair<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,621 pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U 622 where 623 F: FnOnce() -> U, 624 { 625 // Safety: A MutexGuard always holds the lock. 626 unsafe { 627 s.mutex.raw.unlock_fair(); 628 } 629 defer!(s.mutex.raw.lock()); 630 f() 631 } 632 633 /// Temporarily yields the mutex to a waiting thread if there is one. 634 /// 635 /// This method is functionally equivalent to calling `unlock_fair` followed 636 /// by `lock`, however it can be much more efficient in the case where there 637 /// are no waiting threads. 638 #[inline] bump(s: &mut Self)639 pub fn bump(s: &mut Self) { 640 // Safety: A MutexGuard always holds the lock. 641 unsafe { 642 s.mutex.raw.bump(); 643 } 644 } 645 } 646 647 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MutexGuard<'a, R, T> { 648 type Target = T; 649 #[inline] deref(&self) -> &T650 fn deref(&self) -> &T { 651 unsafe { &*self.mutex.data.get() } 652 } 653 } 654 655 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MutexGuard<'a, R, T> { 656 #[inline] deref_mut(&mut self) -> &mut T657 fn deref_mut(&mut self) -> &mut T { 658 unsafe { &mut *self.mutex.data.get() } 659 } 660 } 661 662 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MutexGuard<'a, R, T> { 663 #[inline] drop(&mut self)664 fn drop(&mut self) { 665 // Safety: A MutexGuard always holds the lock. 666 unsafe { 667 self.mutex.raw.unlock(); 668 } 669 } 670 } 671 672 impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MutexGuard<'a, R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result673 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 674 fmt::Debug::fmt(&**self, f) 675 } 676 } 677 678 impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display for MutexGuard<'a, R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result679 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 680 (**self).fmt(f) 681 } 682 } 683 684 #[cfg(feature = "owning_ref")] 685 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MutexGuard<'a, R, T> {} 686 687 /// An RAII mutex guard returned by the `Arc` locking operations on `Mutex`. 688 /// 689 /// This is similar to the `MutexGuard` struct, except instead of using a reference to unlock the `Mutex` it 690 /// uses an `Arc<Mutex>`. This has several advantages, most notably that it has an `'static` lifetime. 691 #[cfg(feature = "arc_lock")] 692 #[clippy::has_significant_drop] 693 #[must_use = "if unused the Mutex will immediately unlock"] 694 pub struct ArcMutexGuard<R: RawMutex, T: ?Sized> { 695 mutex: Arc<Mutex<R, T>>, 696 marker: PhantomData<*const ()>, 697 } 698 699 #[cfg(feature = "arc_lock")] 700 unsafe impl<R: RawMutex + Send + Sync, T: Send + ?Sized> Send for ArcMutexGuard<R, T> where 701 R::GuardMarker: Send 702 { 703 } 704 #[cfg(feature = "arc_lock")] 705 unsafe impl<R: RawMutex + Sync, T: Sync + ?Sized> Sync for ArcMutexGuard<R, T> where 706 R::GuardMarker: Sync 707 { 708 } 709 710 #[cfg(feature = "arc_lock")] 711 impl<R: RawMutex, T: ?Sized> ArcMutexGuard<R, T> { 712 /// Returns a reference to the `Mutex` this is guarding, contained in its `Arc`. 713 #[inline] mutex(s: &Self) -> &Arc<Mutex<R, T>>714 pub fn mutex(s: &Self) -> &Arc<Mutex<R, T>> { 715 &s.mutex 716 } 717 718 /// Unlocks the mutex and returns the `Arc` that was held by the [`ArcMutexGuard`]. 719 #[inline] into_arc(s: Self) -> Arc<Mutex<R, T>>720 pub fn into_arc(s: Self) -> Arc<Mutex<R, T>> { 721 // Safety: Skip our Drop impl and manually unlock the mutex. 722 let arc = unsafe { ptr::read(&s.mutex) }; 723 mem::forget(s); 724 unsafe { 725 arc.raw.unlock(); 726 } 727 arc 728 } 729 730 /// Temporarily unlocks the mutex to execute the given function. 731 /// 732 /// This is safe because `&mut` guarantees that there exist no other 733 /// references to the data protected by the mutex. 734 #[inline] unlocked<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,735 pub fn unlocked<F, U>(s: &mut Self, f: F) -> U 736 where 737 F: FnOnce() -> U, 738 { 739 // Safety: A MutexGuard always holds the lock. 740 unsafe { 741 s.mutex.raw.unlock(); 742 } 743 defer!(s.mutex.raw.lock()); 744 f() 745 } 746 } 747 748 #[cfg(feature = "arc_lock")] 749 impl<R: RawMutexFair, T: ?Sized> ArcMutexGuard<R, T> { 750 /// Unlocks the mutex using a fair unlock protocol. 751 /// 752 /// This is functionally identical to the `unlock_fair` method on [`MutexGuard`]. 753 #[inline] unlock_fair(s: Self)754 pub fn unlock_fair(s: Self) { 755 // Safety: A MutexGuard always holds the lock. 756 unsafe { 757 s.mutex.raw.unlock_fair(); 758 } 759 760 // SAFETY: make sure the Arc gets it reference decremented 761 let mut s = ManuallyDrop::new(s); 762 unsafe { ptr::drop_in_place(&mut s.mutex) }; 763 } 764 765 /// Temporarily unlocks the mutex to execute the given function. 766 /// 767 /// This is functionally identical to the `unlocked_fair` method on [`MutexGuard`]. 768 #[inline] unlocked_fair<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,769 pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U 770 where 771 F: FnOnce() -> U, 772 { 773 // Safety: A MutexGuard always holds the lock. 774 unsafe { 775 s.mutex.raw.unlock_fair(); 776 } 777 defer!(s.mutex.raw.lock()); 778 f() 779 } 780 781 /// Temporarily yields the mutex to a waiting thread if there is one. 782 /// 783 /// This is functionally identical to the `bump` method on [`MutexGuard`]. 784 #[inline] bump(s: &mut Self)785 pub fn bump(s: &mut Self) { 786 // Safety: A MutexGuard always holds the lock. 787 unsafe { 788 s.mutex.raw.bump(); 789 } 790 } 791 } 792 793 #[cfg(feature = "arc_lock")] 794 impl<R: RawMutex, T: ?Sized> Deref for ArcMutexGuard<R, T> { 795 type Target = T; 796 #[inline] deref(&self) -> &T797 fn deref(&self) -> &T { 798 unsafe { &*self.mutex.data.get() } 799 } 800 } 801 802 #[cfg(feature = "arc_lock")] 803 impl<R: RawMutex, T: ?Sized> DerefMut for ArcMutexGuard<R, T> { 804 #[inline] deref_mut(&mut self) -> &mut T805 fn deref_mut(&mut self) -> &mut T { 806 unsafe { &mut *self.mutex.data.get() } 807 } 808 } 809 810 #[cfg(feature = "arc_lock")] 811 impl<R: RawMutex, T: ?Sized> Drop for ArcMutexGuard<R, T> { 812 #[inline] drop(&mut self)813 fn drop(&mut self) { 814 // Safety: A MutexGuard always holds the lock. 815 unsafe { 816 self.mutex.raw.unlock(); 817 } 818 } 819 } 820 821 /// An RAII mutex guard returned by `MutexGuard::map`, which can point to a 822 /// subfield of the protected data. 823 /// 824 /// The main difference between `MappedMutexGuard` and `MutexGuard` is that the 825 /// former doesn't support temporarily unlocking and re-locking, since that 826 /// could introduce soundness issues if the locked object is modified by another 827 /// thread. 828 #[clippy::has_significant_drop] 829 #[must_use = "if unused the Mutex will immediately unlock"] 830 pub struct MappedMutexGuard<'a, R: RawMutex, T: ?Sized> { 831 raw: &'a R, 832 data: *mut T, 833 marker: PhantomData<&'a mut T>, 834 } 835 836 unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync 837 for MappedMutexGuard<'a, R, T> 838 { 839 } 840 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + Send + 'a> Send for MappedMutexGuard<'a, R, T> where 841 R::GuardMarker: Send 842 { 843 } 844 845 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> { 846 /// Makes a new `MappedMutexGuard` for a component of the locked data. 847 /// 848 /// This operation cannot fail as the `MappedMutexGuard` passed 849 /// in already locked the mutex. 850 /// 851 /// This is an associated function that needs to be 852 /// used as `MappedMutexGuard::map(...)`. A method would interfere with methods of 853 /// the same name on the contents of the locked data. 854 #[inline] map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> where F: FnOnce(&mut T) -> &mut U,855 pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> 856 where 857 F: FnOnce(&mut T) -> &mut U, 858 { 859 let raw = s.raw; 860 let data = f(unsafe { &mut *s.data }); 861 mem::forget(s); 862 MappedMutexGuard { 863 raw, 864 data, 865 marker: PhantomData, 866 } 867 } 868 869 /// Attempts to make a new `MappedMutexGuard` for a component of the 870 /// locked data. The original guard is returned if the closure returns `None`. 871 /// 872 /// This operation cannot fail as the `MappedMutexGuard` passed 873 /// in already locked the mutex. 874 /// 875 /// This is an associated function that needs to be 876 /// used as `MappedMutexGuard::try_map(...)`. A method would interfere with methods of 877 /// the same name on the contents of the locked data. 878 #[inline] try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> where F: FnOnce(&mut T) -> Option<&mut U>,879 pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> 880 where 881 F: FnOnce(&mut T) -> Option<&mut U>, 882 { 883 let raw = s.raw; 884 let data = match f(unsafe { &mut *s.data }) { 885 Some(data) => data, 886 None => return Err(s), 887 }; 888 mem::forget(s); 889 Ok(MappedMutexGuard { 890 raw, 891 data, 892 marker: PhantomData, 893 }) 894 } 895 } 896 897 impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> { 898 /// Unlocks the mutex using a fair unlock protocol. 899 /// 900 /// By default, mutexes are unfair and allow the current thread to re-lock 901 /// the mutex before another has the chance to acquire the lock, even if 902 /// that thread has been blocked on the mutex for a long time. This is the 903 /// default because it allows much higher throughput as it avoids forcing a 904 /// context switch on every mutex unlock. This can result in one thread 905 /// acquiring a mutex many more times than other threads. 906 /// 907 /// However in some cases it can be beneficial to ensure fairness by forcing 908 /// the lock to pass on to a waiting thread if there is one. This is done by 909 /// using this method instead of dropping the `MutexGuard` normally. 910 #[inline] unlock_fair(s: Self)911 pub fn unlock_fair(s: Self) { 912 // Safety: A MutexGuard always holds the lock. 913 unsafe { 914 s.raw.unlock_fair(); 915 } 916 mem::forget(s); 917 } 918 } 919 920 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MappedMutexGuard<'a, R, T> { 921 type Target = T; 922 #[inline] deref(&self) -> &T923 fn deref(&self) -> &T { 924 unsafe { &*self.data } 925 } 926 } 927 928 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MappedMutexGuard<'a, R, T> { 929 #[inline] deref_mut(&mut self) -> &mut T930 fn deref_mut(&mut self) -> &mut T { 931 unsafe { &mut *self.data } 932 } 933 } 934 935 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MappedMutexGuard<'a, R, T> { 936 #[inline] drop(&mut self)937 fn drop(&mut self) { 938 // Safety: A MappedMutexGuard always holds the lock. 939 unsafe { 940 self.raw.unlock(); 941 } 942 } 943 } 944 945 impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MappedMutexGuard<'a, R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result946 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 947 fmt::Debug::fmt(&**self, f) 948 } 949 } 950 951 impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display 952 for MappedMutexGuard<'a, R, T> 953 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result954 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 955 (**self).fmt(f) 956 } 957 } 958 959 #[cfg(feature = "owning_ref")] 960 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MappedMutexGuard<'a, R, T> {} 961