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 = "owning_ref")] 15 use owning_ref::StableAddress; 16 17 #[cfg(feature = "serde")] 18 use serde::{Deserialize, Deserializer, Serialize, Serializer}; 19 20 /// Basic operations for a mutex. 21 /// 22 /// Types implementing this trait can be used by `Mutex` to form a safe and 23 /// fully-functioning mutex type. 24 /// 25 /// # Safety 26 /// 27 /// Implementations of this trait must ensure that the mutex is actually 28 /// exclusive: a lock can't be acquired while the mutex is already locked. 29 pub unsafe trait RawMutex { 30 /// Initial value for an unlocked mutex. 31 // A “non-constant” const item is a legacy way to supply an initialized value to downstream 32 // static items. Can hopefully be replaced with `const fn new() -> Self` at some point. 33 #[allow(clippy::declare_interior_mutable_const)] 34 const INIT: Self; 35 36 /// Marker type which determines whether a lock guard should be `Send`. Use 37 /// one of the `GuardSend` or `GuardNoSend` helper types here. 38 type GuardMarker; 39 40 /// Acquires this mutex, blocking the current thread until it is able to do so. lock(&self)41 fn lock(&self); 42 43 /// Attempts to acquire this mutex without blocking. Returns `true` 44 /// if the lock was successfully acquired and `false` otherwise. try_lock(&self) -> bool45 fn try_lock(&self) -> bool; 46 47 /// Unlocks this mutex. 48 /// 49 /// # Safety 50 /// 51 /// This method may only be called if the mutex is held in the current context, i.e. it must 52 /// be paired with a successful call to [`lock`], [`try_lock`], [`try_lock_for`] or [`try_lock_until`]. 53 /// 54 /// [`lock`]: #tymethod.lock 55 /// [`try_lock`]: #tymethod.try_lock 56 /// [`try_lock_for`]: trait.RawMutexTimed.html#tymethod.try_lock_for 57 /// [`try_lock_until`]: trait.RawMutexTimed.html#tymethod.try_lock_until unlock(&self)58 unsafe fn unlock(&self); 59 60 /// Checks whether the mutex is currently locked. 61 #[inline] is_locked(&self) -> bool62 fn is_locked(&self) -> bool { 63 let acquired_lock = self.try_lock(); 64 if acquired_lock { 65 // Safety: The lock has been successfully acquired above. 66 unsafe { 67 self.unlock(); 68 } 69 } 70 !acquired_lock 71 } 72 } 73 74 /// Additional methods for mutexes which support fair unlocking. 75 /// 76 /// Fair unlocking means that a lock is handed directly over to the next waiting 77 /// thread if there is one, without giving other threads the opportunity to 78 /// "steal" the lock in the meantime. This is typically slower than unfair 79 /// unlocking, but may be necessary in certain circumstances. 80 pub unsafe trait RawMutexFair: RawMutex { 81 /// Unlocks this mutex using a fair unlock protocol. 82 /// 83 /// # Safety 84 /// 85 /// This method may only be called if the mutex is held in the current context, see 86 /// the documentation of [`unlock`]. 87 /// 88 /// [`unlock`]: trait.RawMutex.html#tymethod.unlock unlock_fair(&self)89 unsafe fn unlock_fair(&self); 90 91 /// Temporarily yields the mutex to a waiting thread if there is one. 92 /// 93 /// This method is functionally equivalent to calling `unlock_fair` followed 94 /// by `lock`, however it can be much more efficient in the case where there 95 /// are no waiting threads. 96 /// 97 /// # Safety 98 /// 99 /// This method may only be called if the mutex is held in the current context, see 100 /// the documentation of [`unlock`]. 101 /// 102 /// [`unlock`]: trait.RawMutex.html#tymethod.unlock bump(&self)103 unsafe fn bump(&self) { 104 self.unlock_fair(); 105 self.lock(); 106 } 107 } 108 109 /// Additional methods for mutexes which support locking with timeouts. 110 /// 111 /// The `Duration` and `Instant` types are specified as associated types so that 112 /// this trait is usable even in `no_std` environments. 113 pub unsafe trait RawMutexTimed: RawMutex { 114 /// Duration type used for `try_lock_for`. 115 type Duration; 116 117 /// Instant type used for `try_lock_until`. 118 type Instant; 119 120 /// Attempts to acquire this lock until a timeout is reached. try_lock_for(&self, timeout: Self::Duration) -> bool121 fn try_lock_for(&self, timeout: Self::Duration) -> bool; 122 123 /// Attempts to acquire this lock until a timeout is reached. try_lock_until(&self, timeout: Self::Instant) -> bool124 fn try_lock_until(&self, timeout: Self::Instant) -> bool; 125 } 126 127 /// A mutual exclusion primitive useful for protecting shared data 128 /// 129 /// This mutex will block threads waiting for the lock to become available. The 130 /// mutex can also be statically initialized or created via a `new` 131 /// constructor. Each mutex has a type parameter which represents the data that 132 /// it is protecting. The data can only be accessed through the RAII guards 133 /// returned from `lock` and `try_lock`, which guarantees that the data is only 134 /// ever accessed when the mutex is locked. 135 pub struct Mutex<R, T: ?Sized> { 136 raw: R, 137 data: UnsafeCell<T>, 138 } 139 140 unsafe impl<R: RawMutex + Send, T: ?Sized + Send> Send for Mutex<R, T> {} 141 unsafe impl<R: RawMutex + Sync, T: ?Sized + Send> Sync for Mutex<R, T> {} 142 143 impl<R: RawMutex, T> Mutex<R, T> { 144 /// Creates a new mutex in an unlocked state ready for use. 145 #[cfg(feature = "nightly")] 146 #[inline] new(val: T) -> Mutex<R, T>147 pub const fn new(val: T) -> Mutex<R, T> { 148 Mutex { 149 raw: R::INIT, 150 data: UnsafeCell::new(val), 151 } 152 } 153 154 /// Creates a new mutex in an unlocked state ready for use. 155 #[cfg(not(feature = "nightly"))] 156 #[inline] new(val: T) -> Mutex<R, T>157 pub fn new(val: T) -> Mutex<R, T> { 158 Mutex { 159 raw: R::INIT, 160 data: UnsafeCell::new(val), 161 } 162 } 163 164 /// Consumes this mutex, returning the underlying data. 165 #[inline] into_inner(self) -> T166 pub fn into_inner(self) -> T { 167 self.data.into_inner() 168 } 169 } 170 171 impl<R, T> Mutex<R, T> { 172 /// Creates a new mutex based on a pre-existing raw mutex. 173 /// 174 /// This allows creating a mutex in a constant context on stable Rust. 175 #[inline] const_new(raw_mutex: R, val: T) -> Mutex<R, T>176 pub const fn const_new(raw_mutex: R, val: T) -> Mutex<R, T> { 177 Mutex { 178 raw: raw_mutex, 179 data: UnsafeCell::new(val), 180 } 181 } 182 } 183 184 impl<R: RawMutex, T: ?Sized> Mutex<R, T> { 185 /// # Safety 186 /// 187 /// The lock must be held when calling this method. 188 #[inline] guard(&self) -> MutexGuard<'_, R, T>189 unsafe fn guard(&self) -> MutexGuard<'_, R, T> { 190 MutexGuard { 191 mutex: self, 192 marker: PhantomData, 193 } 194 } 195 196 /// Acquires a mutex, blocking the current thread until it is able to do so. 197 /// 198 /// This function will block the local thread until it is available to acquire 199 /// the mutex. Upon returning, the thread is the only thread with the mutex 200 /// held. An RAII guard is returned to allow scoped unlock of the lock. When 201 /// the guard goes out of scope, the mutex will be unlocked. 202 /// 203 /// Attempts to lock a mutex in the thread which already holds the lock will 204 /// result in a deadlock. 205 #[inline] lock(&self) -> MutexGuard<'_, R, T>206 pub fn lock(&self) -> MutexGuard<'_, R, T> { 207 self.raw.lock(); 208 // SAFETY: The lock is held, as required. 209 unsafe { self.guard() } 210 } 211 212 /// Attempts to acquire this lock. 213 /// 214 /// If the lock could not be acquired at this time, then `None` is returned. 215 /// Otherwise, an RAII guard is returned. The lock will be unlocked when the 216 /// guard is dropped. 217 /// 218 /// This function does not block. 219 #[inline] try_lock(&self) -> Option<MutexGuard<'_, R, T>>220 pub fn try_lock(&self) -> Option<MutexGuard<'_, R, T>> { 221 if self.raw.try_lock() { 222 // SAFETY: The lock is held, as required. 223 Some(unsafe { self.guard() }) 224 } else { 225 None 226 } 227 } 228 229 /// Returns a mutable reference to the underlying data. 230 /// 231 /// Since this call borrows the `Mutex` mutably, no actual locking needs to 232 /// take place---the mutable borrow statically guarantees no locks exist. 233 #[inline] get_mut(&mut self) -> &mut T234 pub fn get_mut(&mut self) -> &mut T { 235 unsafe { &mut *self.data.get() } 236 } 237 238 /// Checks whether the mutex is currently locked. 239 #[inline] is_locked(&self) -> bool240 pub fn is_locked(&self) -> bool { 241 self.raw.is_locked() 242 } 243 244 /// Forcibly unlocks the mutex. 245 /// 246 /// This is useful when combined with `mem::forget` to hold a lock without 247 /// the need to maintain a `MutexGuard` object alive, for example when 248 /// dealing with FFI. 249 /// 250 /// # Safety 251 /// 252 /// This method must only be called if the current thread logically owns a 253 /// `MutexGuard` but that guard has be discarded using `mem::forget`. 254 /// Behavior is undefined if a mutex is unlocked when not locked. 255 #[inline] force_unlock(&self)256 pub unsafe fn force_unlock(&self) { 257 self.raw.unlock(); 258 } 259 260 /// Returns the underlying raw mutex object. 261 /// 262 /// Note that you will most likely need to import the `RawMutex` trait from 263 /// `lock_api` to be able to call functions on the raw mutex. 264 /// 265 /// # Safety 266 /// 267 /// This method is unsafe because it allows unlocking a mutex while 268 /// still holding a reference to a `MutexGuard`. 269 #[inline] raw(&self) -> &R270 pub unsafe fn raw(&self) -> &R { 271 &self.raw 272 } 273 274 /// Returns a raw pointer to the underlying data. 275 /// 276 /// This is useful when combined with `mem::forget` to hold a lock without 277 /// the need to maintain a `MutexGuard` object alive, for example when 278 /// dealing with FFI. 279 /// 280 /// # Safety 281 /// 282 /// You must ensure that there are no data races when dereferencing the 283 /// returned pointer, for example if the current thread logically owns 284 /// a `MutexGuard` but that guard has been discarded using `mem::forget`. 285 #[inline] data_ptr(&self) -> *mut T286 pub fn data_ptr(&self) -> *mut T { 287 self.data.get() 288 } 289 } 290 291 impl<R: RawMutexFair, T: ?Sized> Mutex<R, T> { 292 /// Forcibly unlocks the mutex using a fair unlock procotol. 293 /// 294 /// This is useful when combined with `mem::forget` to hold a lock without 295 /// the need to maintain a `MutexGuard` object alive, for example when 296 /// dealing with FFI. 297 /// 298 /// # Safety 299 /// 300 /// This method must only be called if the current thread logically owns a 301 /// `MutexGuard` but that guard has be discarded using `mem::forget`. 302 /// Behavior is undefined if a mutex is unlocked when not locked. 303 #[inline] force_unlock_fair(&self)304 pub unsafe fn force_unlock_fair(&self) { 305 self.raw.unlock_fair(); 306 } 307 } 308 309 impl<R: RawMutexTimed, T: ?Sized> Mutex<R, T> { 310 /// Attempts to acquire this lock until a timeout is reached. 311 /// 312 /// If the lock could not be acquired before the timeout expired, then 313 /// `None` is returned. Otherwise, an RAII guard is returned. The lock will 314 /// be unlocked when the guard is dropped. 315 #[inline] try_lock_for(&self, timeout: R::Duration) -> Option<MutexGuard<'_, R, T>>316 pub fn try_lock_for(&self, timeout: R::Duration) -> Option<MutexGuard<'_, R, T>> { 317 if self.raw.try_lock_for(timeout) { 318 // SAFETY: The lock is held, as required. 319 Some(unsafe { self.guard() }) 320 } else { 321 None 322 } 323 } 324 325 /// Attempts to acquire this lock until a timeout is reached. 326 /// 327 /// If the lock could not be acquired before the timeout expired, then 328 /// `None` is returned. Otherwise, an RAII guard is returned. The lock will 329 /// be unlocked when the guard is dropped. 330 #[inline] try_lock_until(&self, timeout: R::Instant) -> Option<MutexGuard<'_, R, T>>331 pub fn try_lock_until(&self, timeout: R::Instant) -> Option<MutexGuard<'_, R, T>> { 332 if self.raw.try_lock_until(timeout) { 333 // SAFETY: The lock is held, as required. 334 Some(unsafe { self.guard() }) 335 } else { 336 None 337 } 338 } 339 } 340 341 impl<R: RawMutex, T: ?Sized + Default> Default for Mutex<R, T> { 342 #[inline] default() -> Mutex<R, T>343 fn default() -> Mutex<R, T> { 344 Mutex::new(Default::default()) 345 } 346 } 347 348 impl<R: RawMutex, T> From<T> for Mutex<R, T> { 349 #[inline] from(t: T) -> Mutex<R, T>350 fn from(t: T) -> Mutex<R, T> { 351 Mutex::new(t) 352 } 353 } 354 355 impl<R: RawMutex, T: ?Sized + fmt::Debug> fmt::Debug for Mutex<R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result356 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 357 match self.try_lock() { 358 Some(guard) => f.debug_struct("Mutex").field("data", &&*guard).finish(), 359 None => { 360 struct LockedPlaceholder; 361 impl fmt::Debug for LockedPlaceholder { 362 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 363 f.write_str("<locked>") 364 } 365 } 366 367 f.debug_struct("Mutex") 368 .field("data", &LockedPlaceholder) 369 .finish() 370 } 371 } 372 } 373 } 374 375 // Copied and modified from serde 376 #[cfg(feature = "serde")] 377 impl<R, T> Serialize for Mutex<R, T> 378 where 379 R: RawMutex, 380 T: Serialize + ?Sized, 381 { serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,382 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 383 where 384 S: Serializer, 385 { 386 self.lock().serialize(serializer) 387 } 388 } 389 390 #[cfg(feature = "serde")] 391 impl<'de, R, T> Deserialize<'de> for Mutex<R, T> 392 where 393 R: RawMutex, 394 T: Deserialize<'de> + ?Sized, 395 { deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,396 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 397 where 398 D: Deserializer<'de>, 399 { 400 Deserialize::deserialize(deserializer).map(Mutex::new) 401 } 402 } 403 404 /// An RAII implementation of a "scoped lock" of a mutex. When this structure is 405 /// dropped (falls out of scope), the lock will be unlocked. 406 /// 407 /// The data protected by the mutex can be accessed through this guard via its 408 /// `Deref` and `DerefMut` implementations. 409 #[must_use = "if unused the Mutex will immediately unlock"] 410 pub struct MutexGuard<'a, R: RawMutex, T: ?Sized> { 411 mutex: &'a Mutex<R, T>, 412 marker: PhantomData<(&'a mut T, R::GuardMarker)>, 413 } 414 415 unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync for MutexGuard<'a, R, T> {} 416 417 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> { 418 /// Returns a reference to the original `Mutex` object. mutex(s: &Self) -> &'a Mutex<R, T>419 pub fn mutex(s: &Self) -> &'a Mutex<R, T> { 420 s.mutex 421 } 422 423 /// Makes a new `MappedMutexGuard` for a component of the locked data. 424 /// 425 /// This operation cannot fail as the `MutexGuard` passed 426 /// in already locked the mutex. 427 /// 428 /// This is an associated function that needs to be 429 /// used as `MutexGuard::map(...)`. A method would interfere with methods of 430 /// the same name on the contents of the locked data. 431 #[inline] map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> where F: FnOnce(&mut T) -> &mut U,432 pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> 433 where 434 F: FnOnce(&mut T) -> &mut U, 435 { 436 let raw = &s.mutex.raw; 437 let data = f(unsafe { &mut *s.mutex.data.get() }); 438 mem::forget(s); 439 MappedMutexGuard { 440 raw, 441 data, 442 marker: PhantomData, 443 } 444 } 445 446 /// Attempts to make a new `MappedMutexGuard` for a component of the 447 /// locked data. The original guard is returned if the closure returns `None`. 448 /// 449 /// This operation cannot fail as the `MutexGuard` passed 450 /// in already locked the mutex. 451 /// 452 /// This is an associated function that needs to be 453 /// used as `MutexGuard::try_map(...)`. A method would interfere with methods of 454 /// the same name on the contents of the locked data. 455 #[inline] try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> where F: FnOnce(&mut T) -> Option<&mut U>,456 pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> 457 where 458 F: FnOnce(&mut T) -> Option<&mut U>, 459 { 460 let raw = &s.mutex.raw; 461 let data = match f(unsafe { &mut *s.mutex.data.get() }) { 462 Some(data) => data, 463 None => return Err(s), 464 }; 465 mem::forget(s); 466 Ok(MappedMutexGuard { 467 raw, 468 data, 469 marker: PhantomData, 470 }) 471 } 472 473 /// Temporarily unlocks the mutex to execute the given function. 474 /// 475 /// This is safe because `&mut` guarantees that there exist no other 476 /// references to the data protected by the mutex. 477 #[inline] unlocked<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,478 pub fn unlocked<F, U>(s: &mut Self, f: F) -> U 479 where 480 F: FnOnce() -> U, 481 { 482 // Safety: A MutexGuard always holds the lock. 483 unsafe { 484 s.mutex.raw.unlock(); 485 } 486 defer!(s.mutex.raw.lock()); 487 f() 488 } 489 } 490 491 impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> { 492 /// Unlocks the mutex using a fair unlock protocol. 493 /// 494 /// By default, mutexes are unfair and allow the current thread to re-lock 495 /// the mutex before another has the chance to acquire the lock, even if 496 /// that thread has been blocked on the mutex for a long time. This is the 497 /// default because it allows much higher throughput as it avoids forcing a 498 /// context switch on every mutex unlock. This can result in one thread 499 /// acquiring a mutex many more times than other threads. 500 /// 501 /// However in some cases it can be beneficial to ensure fairness by forcing 502 /// the lock to pass on to a waiting thread if there is one. This is done by 503 /// using this method instead of dropping the `MutexGuard` normally. 504 #[inline] unlock_fair(s: Self)505 pub fn unlock_fair(s: Self) { 506 // Safety: A MutexGuard always holds the lock. 507 unsafe { 508 s.mutex.raw.unlock_fair(); 509 } 510 mem::forget(s); 511 } 512 513 /// Temporarily unlocks the mutex to execute the given function. 514 /// 515 /// The mutex is unlocked using a fair unlock protocol. 516 /// 517 /// This is safe because `&mut` guarantees that there exist no other 518 /// references to the data protected by the mutex. 519 #[inline] unlocked_fair<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,520 pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U 521 where 522 F: FnOnce() -> U, 523 { 524 // Safety: A MutexGuard always holds the lock. 525 unsafe { 526 s.mutex.raw.unlock_fair(); 527 } 528 defer!(s.mutex.raw.lock()); 529 f() 530 } 531 532 /// Temporarily yields the mutex to a waiting thread if there is one. 533 /// 534 /// This method is functionally equivalent to calling `unlock_fair` followed 535 /// by `lock`, however it can be much more efficient in the case where there 536 /// are no waiting threads. 537 #[inline] bump(s: &mut Self)538 pub fn bump(s: &mut Self) { 539 // Safety: A MutexGuard always holds the lock. 540 unsafe { 541 s.mutex.raw.bump(); 542 } 543 } 544 } 545 546 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MutexGuard<'a, R, T> { 547 type Target = T; 548 #[inline] deref(&self) -> &T549 fn deref(&self) -> &T { 550 unsafe { &*self.mutex.data.get() } 551 } 552 } 553 554 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MutexGuard<'a, R, T> { 555 #[inline] deref_mut(&mut self) -> &mut T556 fn deref_mut(&mut self) -> &mut T { 557 unsafe { &mut *self.mutex.data.get() } 558 } 559 } 560 561 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MutexGuard<'a, R, T> { 562 #[inline] drop(&mut self)563 fn drop(&mut self) { 564 // Safety: A MutexGuard always holds the lock. 565 unsafe { 566 self.mutex.raw.unlock(); 567 } 568 } 569 } 570 571 impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MutexGuard<'a, R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result572 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 573 fmt::Debug::fmt(&**self, f) 574 } 575 } 576 577 impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display for MutexGuard<'a, R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result578 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 579 (**self).fmt(f) 580 } 581 } 582 583 #[cfg(feature = "owning_ref")] 584 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MutexGuard<'a, R, T> {} 585 586 /// An RAII mutex guard returned by `MutexGuard::map`, which can point to a 587 /// subfield of the protected data. 588 /// 589 /// The main difference between `MappedMutexGuard` and `MutexGuard` is that the 590 /// former doesn't support temporarily unlocking and re-locking, since that 591 /// could introduce soundness issues if the locked object is modified by another 592 /// thread. 593 #[must_use = "if unused the Mutex will immediately unlock"] 594 pub struct MappedMutexGuard<'a, R: RawMutex, T: ?Sized> { 595 raw: &'a R, 596 data: *mut T, 597 marker: PhantomData<&'a mut T>, 598 } 599 600 unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync 601 for MappedMutexGuard<'a, R, T> 602 { 603 } 604 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + Send + 'a> Send for MappedMutexGuard<'a, R, T> where 605 R::GuardMarker: Send 606 { 607 } 608 609 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> { 610 /// Makes a new `MappedMutexGuard` for a component of the locked data. 611 /// 612 /// This operation cannot fail as the `MappedMutexGuard` passed 613 /// in already locked the mutex. 614 /// 615 /// This is an associated function that needs to be 616 /// used as `MappedMutexGuard::map(...)`. A method would interfere with methods of 617 /// the same name on the contents of the locked data. 618 #[inline] map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> where F: FnOnce(&mut T) -> &mut U,619 pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> 620 where 621 F: FnOnce(&mut T) -> &mut U, 622 { 623 let raw = s.raw; 624 let data = f(unsafe { &mut *s.data }); 625 mem::forget(s); 626 MappedMutexGuard { 627 raw, 628 data, 629 marker: PhantomData, 630 } 631 } 632 633 /// Attempts to make a new `MappedMutexGuard` for a component of the 634 /// locked data. The original guard is returned if the closure returns `None`. 635 /// 636 /// This operation cannot fail as the `MappedMutexGuard` passed 637 /// in already locked the mutex. 638 /// 639 /// This is an associated function that needs to be 640 /// used as `MappedMutexGuard::try_map(...)`. A method would interfere with methods of 641 /// the same name on the contents of the locked data. 642 #[inline] try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> where F: FnOnce(&mut T) -> Option<&mut U>,643 pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> 644 where 645 F: FnOnce(&mut T) -> Option<&mut U>, 646 { 647 let raw = s.raw; 648 let data = match f(unsafe { &mut *s.data }) { 649 Some(data) => data, 650 None => return Err(s), 651 }; 652 mem::forget(s); 653 Ok(MappedMutexGuard { 654 raw, 655 data, 656 marker: PhantomData, 657 }) 658 } 659 } 660 661 impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> { 662 /// Unlocks the mutex using a fair unlock protocol. 663 /// 664 /// By default, mutexes are unfair and allow the current thread to re-lock 665 /// the mutex before another has the chance to acquire the lock, even if 666 /// that thread has been blocked on the mutex for a long time. This is the 667 /// default because it allows much higher throughput as it avoids forcing a 668 /// context switch on every mutex unlock. This can result in one thread 669 /// acquiring a mutex many more times than other threads. 670 /// 671 /// However in some cases it can be beneficial to ensure fairness by forcing 672 /// the lock to pass on to a waiting thread if there is one. This is done by 673 /// using this method instead of dropping the `MutexGuard` normally. 674 #[inline] unlock_fair(s: Self)675 pub fn unlock_fair(s: Self) { 676 // Safety: A MutexGuard always holds the lock. 677 unsafe { 678 s.raw.unlock_fair(); 679 } 680 mem::forget(s); 681 } 682 } 683 684 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MappedMutexGuard<'a, R, T> { 685 type Target = T; 686 #[inline] deref(&self) -> &T687 fn deref(&self) -> &T { 688 unsafe { &*self.data } 689 } 690 } 691 692 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MappedMutexGuard<'a, R, T> { 693 #[inline] deref_mut(&mut self) -> &mut T694 fn deref_mut(&mut self) -> &mut T { 695 unsafe { &mut *self.data } 696 } 697 } 698 699 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MappedMutexGuard<'a, R, T> { 700 #[inline] drop(&mut self)701 fn drop(&mut self) { 702 // Safety: A MappedMutexGuard always holds the lock. 703 unsafe { 704 self.raw.unlock(); 705 } 706 } 707 } 708 709 impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MappedMutexGuard<'a, R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result710 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 711 fmt::Debug::fmt(&**self, f) 712 } 713 } 714 715 impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display 716 for MappedMutexGuard<'a, R, T> 717 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result718 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 719 (**self).fmt(f) 720 } 721 } 722 723 #[cfg(feature = "owning_ref")] 724 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MappedMutexGuard<'a, R, T> {} 725