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(feature = "nightly")] 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(feature = "nightly"))] 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 /// # Safety 193 /// 194 /// The lock must be held when calling this method. 195 #[inline] guard(&self) -> MutexGuard<'_, R, T>196 unsafe fn guard(&self) -> MutexGuard<'_, R, T> { 197 MutexGuard { 198 mutex: self, 199 marker: PhantomData, 200 } 201 } 202 203 /// Acquires a mutex, blocking the current thread until it is able to do so. 204 /// 205 /// This function will block the local thread until it is available to acquire 206 /// the mutex. Upon returning, the thread is the only thread with the mutex 207 /// held. An RAII guard is returned to allow scoped unlock of the lock. When 208 /// the guard goes out of scope, the mutex will be unlocked. 209 /// 210 /// Attempts to lock a mutex in the thread which already holds the lock will 211 /// result in a deadlock. 212 #[inline] lock(&self) -> MutexGuard<'_, R, T>213 pub fn lock(&self) -> MutexGuard<'_, R, T> { 214 self.raw.lock(); 215 // SAFETY: The lock is held, as required. 216 unsafe { self.guard() } 217 } 218 219 /// Attempts to acquire this lock. 220 /// 221 /// If the lock could not be acquired at this time, then `None` is returned. 222 /// Otherwise, an RAII guard is returned. The lock will be unlocked when the 223 /// guard is dropped. 224 /// 225 /// This function does not block. 226 #[inline] try_lock(&self) -> Option<MutexGuard<'_, R, T>>227 pub fn try_lock(&self) -> Option<MutexGuard<'_, R, T>> { 228 if self.raw.try_lock() { 229 // SAFETY: The lock is held, as required. 230 Some(unsafe { self.guard() }) 231 } else { 232 None 233 } 234 } 235 236 /// Returns a mutable reference to the underlying data. 237 /// 238 /// Since this call borrows the `Mutex` mutably, no actual locking needs to 239 /// take place---the mutable borrow statically guarantees no locks exist. 240 #[inline] get_mut(&mut self) -> &mut T241 pub fn get_mut(&mut self) -> &mut T { 242 unsafe { &mut *self.data.get() } 243 } 244 245 /// Checks whether the mutex is currently locked. 246 #[inline] is_locked(&self) -> bool247 pub fn is_locked(&self) -> bool { 248 self.raw.is_locked() 249 } 250 251 /// Forcibly unlocks the mutex. 252 /// 253 /// This is useful when combined with `mem::forget` to hold a lock without 254 /// the need to maintain a `MutexGuard` object alive, for example when 255 /// dealing with FFI. 256 /// 257 /// # Safety 258 /// 259 /// This method must only be called if the current thread logically owns a 260 /// `MutexGuard` but that guard has be discarded using `mem::forget`. 261 /// Behavior is undefined if a mutex is unlocked when not locked. 262 #[inline] force_unlock(&self)263 pub unsafe fn force_unlock(&self) { 264 self.raw.unlock(); 265 } 266 267 /// Returns the underlying raw mutex object. 268 /// 269 /// Note that you will most likely need to import the `RawMutex` trait from 270 /// `lock_api` to be able to call functions on the raw mutex. 271 /// 272 /// # Safety 273 /// 274 /// This method is unsafe because it allows unlocking a mutex while 275 /// still holding a reference to a `MutexGuard`. 276 #[inline] raw(&self) -> &R277 pub unsafe fn raw(&self) -> &R { 278 &self.raw 279 } 280 281 /// Returns a raw pointer to the underlying data. 282 /// 283 /// This is useful when combined with `mem::forget` to hold a lock without 284 /// the need to maintain a `MutexGuard` object alive, for example when 285 /// dealing with FFI. 286 /// 287 /// # Safety 288 /// 289 /// You must ensure that there are no data races when dereferencing the 290 /// returned pointer, for example if the current thread logically owns 291 /// a `MutexGuard` but that guard has been discarded using `mem::forget`. 292 #[inline] data_ptr(&self) -> *mut T293 pub fn data_ptr(&self) -> *mut T { 294 self.data.get() 295 } 296 297 /// # Safety 298 /// 299 /// The lock needs to be held for the behavior of this function to be defined. 300 #[cfg(feature = "arc_lock")] 301 #[inline] guard_arc(self: &Arc<Self>) -> ArcMutexGuard<R, T>302 unsafe fn guard_arc(self: &Arc<Self>) -> ArcMutexGuard<R, T> { 303 ArcMutexGuard { 304 mutex: self.clone(), 305 marker: PhantomData, 306 } 307 } 308 309 /// Acquires a lock through an `Arc`. 310 /// 311 /// This method is similar to the `lock` method; however, it requires the `Mutex` to be inside of an `Arc` 312 /// and the resulting mutex guard has no lifetime requirements. 313 #[cfg(feature = "arc_lock")] 314 #[inline] lock_arc(self: &Arc<Self>) -> ArcMutexGuard<R, T>315 pub fn lock_arc(self: &Arc<Self>) -> ArcMutexGuard<R, T> { 316 self.raw.lock(); 317 // SAFETY: the locking guarantee is upheld 318 unsafe { self.guard_arc() } 319 } 320 321 /// Attempts to acquire a lock through an `Arc`. 322 /// 323 /// This method is similar to the `try_lock` method; however, it requires the `Mutex` to be inside of an 324 /// `Arc` and the resulting mutex guard has no lifetime requirements. 325 #[cfg(feature = "arc_lock")] 326 #[inline] try_lock_arc(self: &Arc<Self>) -> Option<ArcMutexGuard<R, T>>327 pub fn try_lock_arc(self: &Arc<Self>) -> Option<ArcMutexGuard<R, T>> { 328 if self.raw.try_lock() { 329 // SAFETY: locking guarantee is upheld 330 Some(unsafe { self.guard_arc() }) 331 } else { 332 None 333 } 334 } 335 } 336 337 impl<R: RawMutexFair, T: ?Sized> Mutex<R, T> { 338 /// Forcibly unlocks the mutex using a fair unlock procotol. 339 /// 340 /// This is useful when combined with `mem::forget` to hold a lock without 341 /// the need to maintain a `MutexGuard` object alive, for example when 342 /// dealing with FFI. 343 /// 344 /// # Safety 345 /// 346 /// This method must only be called if the current thread logically owns a 347 /// `MutexGuard` but that guard has be discarded using `mem::forget`. 348 /// Behavior is undefined if a mutex is unlocked when not locked. 349 #[inline] force_unlock_fair(&self)350 pub unsafe fn force_unlock_fair(&self) { 351 self.raw.unlock_fair(); 352 } 353 } 354 355 impl<R: RawMutexTimed, T: ?Sized> Mutex<R, T> { 356 /// Attempts to acquire this lock until a timeout is reached. 357 /// 358 /// If the lock could not be acquired before the timeout expired, then 359 /// `None` is returned. Otherwise, an RAII guard is returned. The lock will 360 /// be unlocked when the guard is dropped. 361 #[inline] try_lock_for(&self, timeout: R::Duration) -> Option<MutexGuard<'_, R, T>>362 pub fn try_lock_for(&self, timeout: R::Duration) -> Option<MutexGuard<'_, R, T>> { 363 if self.raw.try_lock_for(timeout) { 364 // SAFETY: The lock is held, as required. 365 Some(unsafe { self.guard() }) 366 } else { 367 None 368 } 369 } 370 371 /// Attempts to acquire this lock until a timeout is reached. 372 /// 373 /// If the lock could not be acquired before the timeout expired, then 374 /// `None` is returned. Otherwise, an RAII guard is returned. The lock will 375 /// be unlocked when the guard is dropped. 376 #[inline] try_lock_until(&self, timeout: R::Instant) -> Option<MutexGuard<'_, R, T>>377 pub fn try_lock_until(&self, timeout: R::Instant) -> Option<MutexGuard<'_, R, T>> { 378 if self.raw.try_lock_until(timeout) { 379 // SAFETY: The lock is held, as required. 380 Some(unsafe { self.guard() }) 381 } else { 382 None 383 } 384 } 385 386 /// Attempts to acquire this lock through an `Arc` until a timeout is reached. 387 /// 388 /// This method is similar to the `try_lock_for` method; however, it requires the `Mutex` to be inside of an 389 /// `Arc` and the resulting mutex guard has no lifetime requirements. 390 #[cfg(feature = "arc_lock")] 391 #[inline] try_lock_arc_for(self: &Arc<Self>, timeout: R::Duration) -> Option<ArcMutexGuard<R, T>>392 pub fn try_lock_arc_for(self: &Arc<Self>, timeout: R::Duration) -> Option<ArcMutexGuard<R, T>> { 393 if self.raw.try_lock_for(timeout) { 394 // SAFETY: locking guarantee is upheld 395 Some(unsafe { self.guard_arc() }) 396 } else { 397 None 398 } 399 } 400 401 /// Attempts to acquire this lock through an `Arc` until a timeout is reached. 402 /// 403 /// This method is similar to the `try_lock_until` method; however, it requires the `Mutex` to be inside of 404 /// an `Arc` and the resulting mutex guard has no lifetime requirements. 405 #[cfg(feature = "arc_lock")] 406 #[inline] try_lock_arc_until( self: &Arc<Self>, timeout: R::Instant, ) -> Option<ArcMutexGuard<R, T>>407 pub fn try_lock_arc_until( 408 self: &Arc<Self>, 409 timeout: R::Instant, 410 ) -> Option<ArcMutexGuard<R, T>> { 411 if self.raw.try_lock_until(timeout) { 412 // SAFETY: locking guarantee is upheld 413 Some(unsafe { self.guard_arc() }) 414 } else { 415 None 416 } 417 } 418 } 419 420 impl<R: RawMutex, T: ?Sized + Default> Default for Mutex<R, T> { 421 #[inline] default() -> Mutex<R, T>422 fn default() -> Mutex<R, T> { 423 Mutex::new(Default::default()) 424 } 425 } 426 427 impl<R: RawMutex, T> From<T> for Mutex<R, T> { 428 #[inline] from(t: T) -> Mutex<R, T>429 fn from(t: T) -> Mutex<R, T> { 430 Mutex::new(t) 431 } 432 } 433 434 impl<R: RawMutex, T: ?Sized + fmt::Debug> fmt::Debug for Mutex<R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result435 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 436 match self.try_lock() { 437 Some(guard) => f.debug_struct("Mutex").field("data", &&*guard).finish(), 438 None => { 439 struct LockedPlaceholder; 440 impl fmt::Debug for LockedPlaceholder { 441 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 442 f.write_str("<locked>") 443 } 444 } 445 446 f.debug_struct("Mutex") 447 .field("data", &LockedPlaceholder) 448 .finish() 449 } 450 } 451 } 452 } 453 454 // Copied and modified from serde 455 #[cfg(feature = "serde")] 456 impl<R, T> Serialize for Mutex<R, T> 457 where 458 R: RawMutex, 459 T: Serialize + ?Sized, 460 { serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,461 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 462 where 463 S: Serializer, 464 { 465 self.lock().serialize(serializer) 466 } 467 } 468 469 #[cfg(feature = "serde")] 470 impl<'de, R, T> Deserialize<'de> for Mutex<R, T> 471 where 472 R: RawMutex, 473 T: Deserialize<'de> + ?Sized, 474 { deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,475 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 476 where 477 D: Deserializer<'de>, 478 { 479 Deserialize::deserialize(deserializer).map(Mutex::new) 480 } 481 } 482 483 /// An RAII implementation of a "scoped lock" of a mutex. When this structure is 484 /// dropped (falls out of scope), the lock will be unlocked. 485 /// 486 /// The data protected by the mutex can be accessed through this guard via its 487 /// `Deref` and `DerefMut` implementations. 488 #[must_use = "if unused the Mutex will immediately unlock"] 489 pub struct MutexGuard<'a, R: RawMutex, T: ?Sized> { 490 mutex: &'a Mutex<R, T>, 491 marker: PhantomData<(&'a mut T, R::GuardMarker)>, 492 } 493 494 unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync for MutexGuard<'a, R, T> {} 495 496 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> { 497 /// Returns a reference to the original `Mutex` object. mutex(s: &Self) -> &'a Mutex<R, T>498 pub fn mutex(s: &Self) -> &'a Mutex<R, T> { 499 s.mutex 500 } 501 502 /// Makes a new `MappedMutexGuard` for a component of the locked data. 503 /// 504 /// This operation cannot fail as the `MutexGuard` passed 505 /// in already locked the mutex. 506 /// 507 /// This is an associated function that needs to be 508 /// used as `MutexGuard::map(...)`. A method would interfere with methods of 509 /// the same name on the contents of the locked data. 510 #[inline] map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> where F: FnOnce(&mut T) -> &mut U,511 pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> 512 where 513 F: FnOnce(&mut T) -> &mut U, 514 { 515 let raw = &s.mutex.raw; 516 let data = f(unsafe { &mut *s.mutex.data.get() }); 517 mem::forget(s); 518 MappedMutexGuard { 519 raw, 520 data, 521 marker: PhantomData, 522 } 523 } 524 525 /// Attempts to make a new `MappedMutexGuard` for a component of the 526 /// locked data. The original guard is returned if the closure returns `None`. 527 /// 528 /// This operation cannot fail as the `MutexGuard` passed 529 /// in already locked the mutex. 530 /// 531 /// This is an associated function that needs to be 532 /// used as `MutexGuard::try_map(...)`. A method would interfere with methods of 533 /// the same name on the contents of the locked data. 534 #[inline] try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> where F: FnOnce(&mut T) -> Option<&mut U>,535 pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> 536 where 537 F: FnOnce(&mut T) -> Option<&mut U>, 538 { 539 let raw = &s.mutex.raw; 540 let data = match f(unsafe { &mut *s.mutex.data.get() }) { 541 Some(data) => data, 542 None => return Err(s), 543 }; 544 mem::forget(s); 545 Ok(MappedMutexGuard { 546 raw, 547 data, 548 marker: PhantomData, 549 }) 550 } 551 552 /// Temporarily unlocks the mutex to execute the given function. 553 /// 554 /// This is safe because `&mut` guarantees that there exist no other 555 /// references to the data protected by the mutex. 556 #[inline] unlocked<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,557 pub fn unlocked<F, U>(s: &mut Self, f: F) -> U 558 where 559 F: FnOnce() -> U, 560 { 561 // Safety: A MutexGuard always holds the lock. 562 unsafe { 563 s.mutex.raw.unlock(); 564 } 565 defer!(s.mutex.raw.lock()); 566 f() 567 } 568 } 569 570 impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> { 571 /// Unlocks the mutex using a fair unlock protocol. 572 /// 573 /// By default, mutexes are unfair and allow the current thread to re-lock 574 /// the mutex before another has the chance to acquire the lock, even if 575 /// that thread has been blocked on the mutex for a long time. This is the 576 /// default because it allows much higher throughput as it avoids forcing a 577 /// context switch on every mutex unlock. This can result in one thread 578 /// acquiring a mutex many more times than other threads. 579 /// 580 /// However in some cases it can be beneficial to ensure fairness by forcing 581 /// the lock to pass on to a waiting thread if there is one. This is done by 582 /// using this method instead of dropping the `MutexGuard` normally. 583 #[inline] unlock_fair(s: Self)584 pub fn unlock_fair(s: Self) { 585 // Safety: A MutexGuard always holds the lock. 586 unsafe { 587 s.mutex.raw.unlock_fair(); 588 } 589 mem::forget(s); 590 } 591 592 /// Temporarily unlocks the mutex to execute the given function. 593 /// 594 /// The mutex is unlocked using a fair unlock protocol. 595 /// 596 /// This is safe because `&mut` guarantees that there exist no other 597 /// references to the data protected by the mutex. 598 #[inline] unlocked_fair<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,599 pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U 600 where 601 F: FnOnce() -> U, 602 { 603 // Safety: A MutexGuard always holds the lock. 604 unsafe { 605 s.mutex.raw.unlock_fair(); 606 } 607 defer!(s.mutex.raw.lock()); 608 f() 609 } 610 611 /// Temporarily yields the mutex to a waiting thread if there is one. 612 /// 613 /// This method is functionally equivalent to calling `unlock_fair` followed 614 /// by `lock`, however it can be much more efficient in the case where there 615 /// are no waiting threads. 616 #[inline] bump(s: &mut Self)617 pub fn bump(s: &mut Self) { 618 // Safety: A MutexGuard always holds the lock. 619 unsafe { 620 s.mutex.raw.bump(); 621 } 622 } 623 } 624 625 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MutexGuard<'a, R, T> { 626 type Target = T; 627 #[inline] deref(&self) -> &T628 fn deref(&self) -> &T { 629 unsafe { &*self.mutex.data.get() } 630 } 631 } 632 633 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MutexGuard<'a, R, T> { 634 #[inline] deref_mut(&mut self) -> &mut T635 fn deref_mut(&mut self) -> &mut T { 636 unsafe { &mut *self.mutex.data.get() } 637 } 638 } 639 640 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MutexGuard<'a, R, T> { 641 #[inline] drop(&mut self)642 fn drop(&mut self) { 643 // Safety: A MutexGuard always holds the lock. 644 unsafe { 645 self.mutex.raw.unlock(); 646 } 647 } 648 } 649 650 impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MutexGuard<'a, R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result651 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 652 fmt::Debug::fmt(&**self, f) 653 } 654 } 655 656 impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display for MutexGuard<'a, R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result657 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 658 (**self).fmt(f) 659 } 660 } 661 662 #[cfg(feature = "owning_ref")] 663 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MutexGuard<'a, R, T> {} 664 665 /// An RAII mutex guard returned by the `Arc` locking operations on `Mutex`. 666 /// 667 /// This is similar to the `MutexGuard` struct, except instead of using a reference to unlock the `Mutex` it 668 /// uses an `Arc<Mutex>`. This has several advantages, most notably that it has an `'static` lifetime. 669 #[cfg(feature = "arc_lock")] 670 #[must_use = "if unused the Mutex will immediately unlock"] 671 pub struct ArcMutexGuard<R: RawMutex, T: ?Sized> { 672 mutex: Arc<Mutex<R, T>>, 673 marker: PhantomData<R::GuardMarker>, 674 } 675 676 #[cfg(feature = "arc_lock")] 677 impl<R: RawMutex, T: ?Sized> ArcMutexGuard<R, T> { 678 /// Returns a reference to the `Mutex` this is guarding, contained in its `Arc`. 679 #[inline] mutex(&self) -> &Arc<Mutex<R, T>>680 pub fn mutex(&self) -> &Arc<Mutex<R, T>> { 681 &self.mutex 682 } 683 684 /// Temporarily unlocks the mutex to execute the given function. 685 /// 686 /// This is safe because `&mut` guarantees that there exist no other 687 /// references to the data protected by the mutex. 688 #[inline] unlocked<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,689 pub fn unlocked<F, U>(s: &mut Self, f: F) -> U 690 where 691 F: FnOnce() -> U, 692 { 693 // Safety: A MutexGuard always holds the lock. 694 unsafe { 695 s.mutex.raw.unlock(); 696 } 697 defer!(s.mutex.raw.lock()); 698 f() 699 } 700 } 701 702 #[cfg(feature = "arc_lock")] 703 impl<R: RawMutexFair, T: ?Sized> ArcMutexGuard<R, T> { 704 /// Unlocks the mutex using a fair unlock protocol. 705 /// 706 /// This is functionally identical to the `unlock_fair` method on [`MutexGuard`]. 707 #[inline] unlock_fair(s: Self)708 pub fn unlock_fair(s: Self) { 709 // Safety: A MutexGuard always holds the lock. 710 unsafe { 711 s.mutex.raw.unlock_fair(); 712 } 713 714 // SAFETY: make sure the Arc gets it reference decremented 715 let mut s = ManuallyDrop::new(s); 716 unsafe { ptr::drop_in_place(&mut s.mutex) }; 717 } 718 719 /// Temporarily unlocks the mutex to execute the given function. 720 /// 721 /// This is functionally identical to the `unlocked_fair` method on [`MutexGuard`]. 722 #[inline] unlocked_fair<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,723 pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U 724 where 725 F: FnOnce() -> U, 726 { 727 // Safety: A MutexGuard always holds the lock. 728 unsafe { 729 s.mutex.raw.unlock_fair(); 730 } 731 defer!(s.mutex.raw.lock()); 732 f() 733 } 734 735 /// Temporarily yields the mutex to a waiting thread if there is one. 736 /// 737 /// This is functionally identical to the `bump` method on [`MutexGuard`]. 738 #[inline] bump(s: &mut Self)739 pub fn bump(s: &mut Self) { 740 // Safety: A MutexGuard always holds the lock. 741 unsafe { 742 s.mutex.raw.bump(); 743 } 744 } 745 } 746 747 #[cfg(feature = "arc_lock")] 748 impl<R: RawMutex, T: ?Sized> Deref for ArcMutexGuard<R, T> { 749 type Target = T; 750 #[inline] deref(&self) -> &T751 fn deref(&self) -> &T { 752 unsafe { &*self.mutex.data.get() } 753 } 754 } 755 756 #[cfg(feature = "arc_lock")] 757 impl<R: RawMutex, T: ?Sized> DerefMut for ArcMutexGuard<R, T> { 758 #[inline] deref_mut(&mut self) -> &mut T759 fn deref_mut(&mut self) -> &mut T { 760 unsafe { &mut *self.mutex.data.get() } 761 } 762 } 763 764 #[cfg(feature = "arc_lock")] 765 impl<R: RawMutex, T: ?Sized> Drop for ArcMutexGuard<R, T> { 766 #[inline] drop(&mut self)767 fn drop(&mut self) { 768 // Safety: A MutexGuard always holds the lock. 769 unsafe { 770 self.mutex.raw.unlock(); 771 } 772 } 773 } 774 775 /// An RAII mutex guard returned by `MutexGuard::map`, which can point to a 776 /// subfield of the protected data. 777 /// 778 /// The main difference between `MappedMutexGuard` and `MutexGuard` is that the 779 /// former doesn't support temporarily unlocking and re-locking, since that 780 /// could introduce soundness issues if the locked object is modified by another 781 /// thread. 782 #[must_use = "if unused the Mutex will immediately unlock"] 783 pub struct MappedMutexGuard<'a, R: RawMutex, T: ?Sized> { 784 raw: &'a R, 785 data: *mut T, 786 marker: PhantomData<&'a mut T>, 787 } 788 789 unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync 790 for MappedMutexGuard<'a, R, T> 791 { 792 } 793 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + Send + 'a> Send for MappedMutexGuard<'a, R, T> where 794 R::GuardMarker: Send 795 { 796 } 797 798 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> { 799 /// Makes a new `MappedMutexGuard` for a component of the locked data. 800 /// 801 /// This operation cannot fail as the `MappedMutexGuard` passed 802 /// in already locked the mutex. 803 /// 804 /// This is an associated function that needs to be 805 /// used as `MappedMutexGuard::map(...)`. A method would interfere with methods of 806 /// the same name on the contents of the locked data. 807 #[inline] map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> where F: FnOnce(&mut T) -> &mut U,808 pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> 809 where 810 F: FnOnce(&mut T) -> &mut U, 811 { 812 let raw = s.raw; 813 let data = f(unsafe { &mut *s.data }); 814 mem::forget(s); 815 MappedMutexGuard { 816 raw, 817 data, 818 marker: PhantomData, 819 } 820 } 821 822 /// Attempts to make a new `MappedMutexGuard` for a component of the 823 /// locked data. The original guard is returned if the closure returns `None`. 824 /// 825 /// This operation cannot fail as the `MappedMutexGuard` passed 826 /// in already locked the mutex. 827 /// 828 /// This is an associated function that needs to be 829 /// used as `MappedMutexGuard::try_map(...)`. A method would interfere with methods of 830 /// the same name on the contents of the locked data. 831 #[inline] try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> where F: FnOnce(&mut T) -> Option<&mut U>,832 pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> 833 where 834 F: FnOnce(&mut T) -> Option<&mut U>, 835 { 836 let raw = s.raw; 837 let data = match f(unsafe { &mut *s.data }) { 838 Some(data) => data, 839 None => return Err(s), 840 }; 841 mem::forget(s); 842 Ok(MappedMutexGuard { 843 raw, 844 data, 845 marker: PhantomData, 846 }) 847 } 848 } 849 850 impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> { 851 /// Unlocks the mutex using a fair unlock protocol. 852 /// 853 /// By default, mutexes are unfair and allow the current thread to re-lock 854 /// the mutex before another has the chance to acquire the lock, even if 855 /// that thread has been blocked on the mutex for a long time. This is the 856 /// default because it allows much higher throughput as it avoids forcing a 857 /// context switch on every mutex unlock. This can result in one thread 858 /// acquiring a mutex many more times than other threads. 859 /// 860 /// However in some cases it can be beneficial to ensure fairness by forcing 861 /// the lock to pass on to a waiting thread if there is one. This is done by 862 /// using this method instead of dropping the `MutexGuard` normally. 863 #[inline] unlock_fair(s: Self)864 pub fn unlock_fair(s: Self) { 865 // Safety: A MutexGuard always holds the lock. 866 unsafe { 867 s.raw.unlock_fair(); 868 } 869 mem::forget(s); 870 } 871 } 872 873 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MappedMutexGuard<'a, R, T> { 874 type Target = T; 875 #[inline] deref(&self) -> &T876 fn deref(&self) -> &T { 877 unsafe { &*self.data } 878 } 879 } 880 881 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MappedMutexGuard<'a, R, T> { 882 #[inline] deref_mut(&mut self) -> &mut T883 fn deref_mut(&mut self) -> &mut T { 884 unsafe { &mut *self.data } 885 } 886 } 887 888 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MappedMutexGuard<'a, R, T> { 889 #[inline] drop(&mut self)890 fn drop(&mut self) { 891 // Safety: A MappedMutexGuard always holds the lock. 892 unsafe { 893 self.raw.unlock(); 894 } 895 } 896 } 897 898 impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MappedMutexGuard<'a, R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result899 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 900 fmt::Debug::fmt(&**self, f) 901 } 902 } 903 904 impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display 905 for MappedMutexGuard<'a, R, T> 906 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result907 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 908 (**self).fmt(f) 909 } 910 } 911 912 #[cfg(feature = "owning_ref")] 913 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MappedMutexGuard<'a, R, T> {} 914