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 const INIT: Self; 32 33 /// Marker type which determines whether a lock guard should be `Send`. Use 34 /// one of the `GuardSend` or `GuardNoSend` helper types here. 35 type GuardMarker; 36 37 /// Acquires this mutex, blocking the current thread until it is able to do so. lock(&self)38 fn lock(&self); 39 40 /// Attempts to acquire this mutex without blocking. try_lock(&self) -> bool41 fn try_lock(&self) -> bool; 42 43 /// Unlocks this mutex. unlock(&self)44 fn unlock(&self); 45 } 46 47 /// Additional methods for mutexes which support fair unlocking. 48 /// 49 /// Fair unlocking means that a lock is handed directly over to the next waiting 50 /// thread if there is one, without giving other threads the opportunity to 51 /// "steal" the lock in the meantime. This is typically slower than unfair 52 /// unlocking, but may be necessary in certain circumstances. 53 pub unsafe trait RawMutexFair: RawMutex { 54 /// Unlocks this mutex using a fair unlock protocol. unlock_fair(&self)55 fn unlock_fair(&self); 56 57 /// Temporarily yields the mutex to a waiting thread if there is one. 58 /// 59 /// This method is functionally equivalent to calling `unlock_fair` followed 60 /// by `lock`, however it can be much more efficient in the case where there 61 /// are no waiting threads. bump(&self)62 fn bump(&self) { 63 self.unlock_fair(); 64 self.lock(); 65 } 66 } 67 68 /// Additional methods for mutexes which support locking with timeouts. 69 /// 70 /// The `Duration` and `Instant` types are specified as associated types so that 71 /// this trait is usable even in `no_std` environments. 72 pub unsafe trait RawMutexTimed: RawMutex { 73 /// Duration type used for `try_lock_for`. 74 type Duration; 75 76 /// Instant type used for `try_lock_until`. 77 type Instant; 78 79 /// Attempts to acquire this lock until a timeout is reached. try_lock_for(&self, timeout: Self::Duration) -> bool80 fn try_lock_for(&self, timeout: Self::Duration) -> bool; 81 82 /// Attempts to acquire this lock until a timeout is reached. try_lock_until(&self, timeout: Self::Instant) -> bool83 fn try_lock_until(&self, timeout: Self::Instant) -> bool; 84 } 85 86 /// A mutual exclusion primitive useful for protecting shared data 87 /// 88 /// This mutex will block threads waiting for the lock to become available. The 89 /// mutex can also be statically initialized or created via a `new` 90 /// constructor. Each mutex has a type parameter which represents the data that 91 /// it is protecting. The data can only be accessed through the RAII guards 92 /// returned from `lock` and `try_lock`, which guarantees that the data is only 93 /// ever accessed when the mutex is locked. 94 pub struct Mutex<R: RawMutex, T: ?Sized> { 95 raw: R, 96 data: UnsafeCell<T>, 97 } 98 99 // Copied and modified from serde 100 #[cfg(feature = "serde")] 101 impl<R, T> Serialize for Mutex<R, T> 102 where 103 R: RawMutex, 104 T: Serialize + ?Sized, 105 { serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,106 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 107 where 108 S: Serializer, 109 { 110 self.lock().serialize(serializer) 111 } 112 } 113 114 #[cfg(feature = "serde")] 115 impl<'de, R, T> Deserialize<'de> for Mutex<R, T> 116 where 117 R: RawMutex, 118 T: Deserialize<'de> + ?Sized, 119 { deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,120 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 121 where 122 D: Deserializer<'de>, 123 { 124 Deserialize::deserialize(deserializer).map(Mutex::new) 125 } 126 } 127 128 unsafe impl<R: RawMutex + Send, T: ?Sized + Send> Send for Mutex<R, T> {} 129 unsafe impl<R: RawMutex + Sync, T: ?Sized + Send> Sync for Mutex<R, T> {} 130 131 impl<R: RawMutex, T> Mutex<R, T> { 132 /// Creates a new mutex in an unlocked state ready for use. 133 #[cfg(feature = "nightly")] 134 #[inline] new(val: T) -> Mutex<R, T>135 pub const fn new(val: T) -> Mutex<R, T> { 136 Mutex { data: UnsafeCell::new(val), raw: R::INIT } 137 } 138 139 /// Creates a new mutex in an unlocked state ready for use. 140 #[cfg(not(feature = "nightly"))] 141 #[inline] new(val: T) -> Mutex<R, T>142 pub fn new(val: T) -> Mutex<R, T> { 143 Mutex { data: UnsafeCell::new(val), raw: R::INIT } 144 } 145 146 /// Consumes this mutex, returning the underlying data. 147 #[inline] 148 #[allow(unused_unsafe)] into_inner(self) -> T149 pub fn into_inner(self) -> T { 150 unsafe { self.data.into_inner() } 151 } 152 } 153 154 impl<R: RawMutex, T: ?Sized> Mutex<R, T> { 155 /// # Safety 156 /// 157 /// The lock must be held when calling this method. 158 #[inline] guard(&self) -> MutexGuard<'_, R, T>159 unsafe fn guard(&self) -> MutexGuard<'_, R, T> { 160 MutexGuard { mutex: self, marker: PhantomData } 161 } 162 163 /// Acquires a mutex, blocking the current thread until it is able to do so. 164 /// 165 /// This function will block the local thread until it is available to acquire 166 /// the mutex. Upon returning, the thread is the only thread with the mutex 167 /// held. An RAII guard is returned to allow scoped unlock of the lock. When 168 /// the guard goes out of scope, the mutex will be unlocked. 169 /// 170 /// Attempts to lock a mutex in the thread which already holds the lock will 171 /// result in a deadlock. 172 #[inline] lock(&self) -> MutexGuard<'_, R, T>173 pub fn lock(&self) -> MutexGuard<'_, R, T> { 174 self.raw.lock(); 175 // SAFETY: The lock is held, as required. 176 unsafe { self.guard() } 177 } 178 179 /// Attempts to acquire this lock. 180 /// 181 /// If the lock could not be acquired at this time, then `None` is returned. 182 /// Otherwise, an RAII guard is returned. The lock will be unlocked when the 183 /// guard is dropped. 184 /// 185 /// This function does not block. 186 #[inline] try_lock(&self) -> Option<MutexGuard<'_, R, T>>187 pub fn try_lock(&self) -> Option<MutexGuard<'_, R, T>> { 188 if self.raw.try_lock() { 189 // SAFETY: The lock is held, as required. 190 Some(unsafe { self.guard() }) 191 } else { 192 None 193 } 194 } 195 196 /// Returns a mutable reference to the underlying data. 197 /// 198 /// Since this call borrows the `Mutex` mutably, no actual locking needs to 199 /// take place---the mutable borrow statically guarantees no locks exist. 200 #[inline] get_mut(&mut self) -> &mut T201 pub fn get_mut(&mut self) -> &mut T { 202 unsafe { &mut *self.data.get() } 203 } 204 205 /// Forcibly unlocks the mutex. 206 /// 207 /// This is useful when combined with `mem::forget` to hold a lock without 208 /// the need to maintain a `MutexGuard` object alive, for example when 209 /// dealing with FFI. 210 /// 211 /// # Safety 212 /// 213 /// This method must only be called if the current thread logically owns a 214 /// `MutexGuard` but that guard has be discarded using `mem::forget`. 215 /// Behavior is undefined if a mutex is unlocked when not locked. 216 #[inline] force_unlock(&self)217 pub unsafe fn force_unlock(&self) { 218 self.raw.unlock(); 219 } 220 221 /// Returns the underlying raw mutex object. 222 /// 223 /// Note that you will most likely need to import the `RawMutex` trait from 224 /// `lock_api` to be able to call functions on the raw mutex. 225 /// 226 /// # Safety 227 /// 228 /// This method is unsafe because it allows unlocking a mutex while 229 /// still holding a reference to a `MutexGuard`. 230 #[inline] raw(&self) -> &R231 pub unsafe fn raw(&self) -> &R { 232 &self.raw 233 } 234 } 235 236 impl<R: RawMutexFair, T: ?Sized> Mutex<R, T> { 237 /// Forcibly unlocks the mutex using a fair unlock procotol. 238 /// 239 /// This is useful when combined with `mem::forget` to hold a lock without 240 /// the need to maintain a `MutexGuard` object alive, for example when 241 /// dealing with FFI. 242 /// 243 /// # Safety 244 /// 245 /// This method must only be called if the current thread logically owns a 246 /// `MutexGuard` but that guard has be discarded using `mem::forget`. 247 /// Behavior is undefined if a mutex is unlocked when not locked. 248 #[inline] force_unlock_fair(&self)249 pub unsafe fn force_unlock_fair(&self) { 250 self.raw.unlock_fair(); 251 } 252 } 253 254 impl<R: RawMutexTimed, T: ?Sized> Mutex<R, T> { 255 /// Attempts to acquire this lock until a timeout is reached. 256 /// 257 /// If the lock could not be acquired before the timeout expired, then 258 /// `None` is returned. Otherwise, an RAII guard is returned. The lock will 259 /// be unlocked when the guard is dropped. 260 #[inline] try_lock_for(&self, timeout: R::Duration) -> Option<MutexGuard<'_, R, T>>261 pub fn try_lock_for(&self, timeout: R::Duration) -> Option<MutexGuard<'_, R, T>> { 262 if self.raw.try_lock_for(timeout) { 263 // SAFETY: The lock is held, as required. 264 Some(unsafe { self.guard() }) 265 } else { 266 None 267 } 268 } 269 270 /// Attempts to acquire this lock until a timeout is reached. 271 /// 272 /// If the lock could not be acquired before the timeout expired, then 273 /// `None` is returned. Otherwise, an RAII guard is returned. The lock will 274 /// be unlocked when the guard is dropped. 275 #[inline] try_lock_until(&self, timeout: R::Instant) -> Option<MutexGuard<'_, R, T>>276 pub fn try_lock_until(&self, timeout: R::Instant) -> Option<MutexGuard<'_, R, T>> { 277 if self.raw.try_lock_until(timeout) { 278 // SAFETY: The lock is held, as required. 279 Some(unsafe { self.guard() }) 280 } else { 281 None 282 } 283 } 284 } 285 286 impl<R: RawMutex, T: ?Sized + Default> Default for Mutex<R, T> { 287 #[inline] default() -> Mutex<R, T>288 fn default() -> Mutex<R, T> { 289 Mutex::new(Default::default()) 290 } 291 } 292 293 impl<R: RawMutex, T> From<T> for Mutex<R, T> { 294 #[inline] from(t: T) -> Mutex<R, T>295 fn from(t: T) -> Mutex<R, T> { 296 Mutex::new(t) 297 } 298 } 299 300 impl<R: RawMutex, T: ?Sized + fmt::Debug> fmt::Debug for Mutex<R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result301 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 302 match self.try_lock() { 303 Some(guard) => f.debug_struct("Mutex").field("data", &&*guard).finish(), 304 None => { 305 struct LockedPlaceholder; 306 impl fmt::Debug for LockedPlaceholder { 307 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 308 f.write_str("<locked>") 309 } 310 } 311 312 f.debug_struct("Mutex").field("data", &LockedPlaceholder).finish() 313 } 314 } 315 } 316 } 317 318 /// An RAII implementation of a "scoped lock" of a mutex. When this structure is 319 /// dropped (falls out of scope), the lock will be unlocked. 320 /// 321 /// The data protected by the mutex can be accessed through this guard via its 322 /// `Deref` and `DerefMut` implementations. 323 #[must_use = "if unused the Mutex will immediately unlock"] 324 pub struct MutexGuard<'a, R: RawMutex, T: ?Sized> { 325 mutex: &'a Mutex<R, T>, 326 marker: PhantomData<(&'a mut T, R::GuardMarker)>, 327 } 328 329 unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync for MutexGuard<'a, R, T> {} 330 331 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> { 332 /// Returns a reference to the original `Mutex` object. mutex(s: &Self) -> &'a Mutex<R, T>333 pub fn mutex(s: &Self) -> &'a Mutex<R, T> { 334 s.mutex 335 } 336 337 /// Makes a new `MappedMutexGuard` for a component of the locked data. 338 /// 339 /// This operation cannot fail as the `MutexGuard` passed 340 /// in already locked the mutex. 341 /// 342 /// This is an associated function that needs to be 343 /// used as `MutexGuard::map(...)`. A method would interfere with methods of 344 /// the same name on the contents of the locked data. 345 #[inline] map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> where F: FnOnce(&mut T) -> &mut U,346 pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> 347 where 348 F: FnOnce(&mut T) -> &mut U, 349 { 350 let raw = &s.mutex.raw; 351 let data = f(unsafe { &mut *s.mutex.data.get() }); 352 mem::forget(s); 353 MappedMutexGuard { raw, data, marker: PhantomData } 354 } 355 356 /// Attempts to make a new `MappedMutexGuard` for a component of the 357 /// locked data. The original guard is return if the closure returns `None`. 358 /// 359 /// This operation cannot fail as the `MutexGuard` passed 360 /// in already locked the mutex. 361 /// 362 /// This is an associated function that needs to be 363 /// used as `MutexGuard::map(...)`. A method would interfere with methods of 364 /// the same name on the contents of the locked data. 365 #[inline] try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> where F: FnOnce(&mut T) -> Option<&mut U>,366 pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> 367 where 368 F: FnOnce(&mut T) -> Option<&mut U>, 369 { 370 let raw = &s.mutex.raw; 371 let data = match f(unsafe { &mut *s.mutex.data.get() }) { 372 Some(data) => data, 373 None => return Err(s), 374 }; 375 mem::forget(s); 376 Ok(MappedMutexGuard { raw, data, marker: PhantomData }) 377 } 378 379 /// Temporarily unlocks the mutex to execute the given function. 380 /// 381 /// This is safe because `&mut` guarantees that there exist no other 382 /// references to the data protected by the mutex. 383 #[inline] unlocked<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,384 pub fn unlocked<F, U>(s: &mut Self, f: F) -> U 385 where 386 F: FnOnce() -> U, 387 { 388 s.mutex.raw.unlock(); 389 defer!(s.mutex.raw.lock()); 390 f() 391 } 392 } 393 394 impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> { 395 /// Unlocks the mutex using a fair unlock protocol. 396 /// 397 /// By default, mutexes are unfair and allow the current thread to re-lock 398 /// the mutex before another has the chance to acquire the lock, even if 399 /// that thread has been blocked on the mutex for a long time. This is the 400 /// default because it allows much higher throughput as it avoids forcing a 401 /// context switch on every mutex unlock. This can result in one thread 402 /// acquiring a mutex many more times than other threads. 403 /// 404 /// However in some cases it can be beneficial to ensure fairness by forcing 405 /// the lock to pass on to a waiting thread if there is one. This is done by 406 /// using this method instead of dropping the `MutexGuard` normally. 407 #[inline] unlock_fair(s: Self)408 pub fn unlock_fair(s: Self) { 409 s.mutex.raw.unlock_fair(); 410 mem::forget(s); 411 } 412 413 /// Temporarily unlocks the mutex to execute the given function. 414 /// 415 /// The mutex is unlocked a fair unlock protocol. 416 /// 417 /// This is safe because `&mut` guarantees that there exist no other 418 /// references to the data protected by the mutex. 419 #[inline] unlocked_fair<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,420 pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U 421 where 422 F: FnOnce() -> U, 423 { 424 s.mutex.raw.unlock_fair(); 425 defer!(s.mutex.raw.lock()); 426 f() 427 } 428 429 /// Temporarily yields the mutex to a waiting thread if there is one. 430 /// 431 /// This method is functionally equivalent to calling `unlock_fair` followed 432 /// by `lock`, however it can be much more efficient in the case where there 433 /// are no waiting threads. 434 #[inline] bump(s: &mut Self)435 pub fn bump(s: &mut Self) { 436 s.mutex.raw.bump(); 437 } 438 } 439 440 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MutexGuard<'a, R, T> { 441 type Target = T; 442 #[inline] deref(&self) -> &T443 fn deref(&self) -> &T { 444 unsafe { &*self.mutex.data.get() } 445 } 446 } 447 448 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MutexGuard<'a, R, T> { 449 #[inline] deref_mut(&mut self) -> &mut T450 fn deref_mut(&mut self) -> &mut T { 451 unsafe { &mut *self.mutex.data.get() } 452 } 453 } 454 455 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MutexGuard<'a, R, T> { 456 #[inline] drop(&mut self)457 fn drop(&mut self) { 458 self.mutex.raw.unlock(); 459 } 460 } 461 462 impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MutexGuard<'a, R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result463 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 464 fmt::Debug::fmt(&**self, f) 465 } 466 } 467 468 impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display for MutexGuard<'a, R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result469 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 470 (**self).fmt(f) 471 } 472 } 473 474 #[cfg(feature = "owning_ref")] 475 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MutexGuard<'a, R, T> {} 476 477 /// An RAII mutex guard returned by `MutexGuard::map`, which can point to a 478 /// subfield of the protected data. 479 /// 480 /// The main difference between `MappedMutexGuard` and `MutexGuard` is that the 481 /// former doesn't support temporarily unlocking and re-locking, since that 482 /// could introduce soundness issues if the locked object is modified by another 483 /// thread. 484 #[must_use = "if unused the Mutex will immediately unlock"] 485 pub struct MappedMutexGuard<'a, R: RawMutex, T: ?Sized> { 486 raw: &'a R, 487 data: *mut T, 488 marker: PhantomData<&'a mut T>, 489 } 490 491 unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync 492 for MappedMutexGuard<'a, R, T> 493 { 494 } 495 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Send for MappedMutexGuard<'a, R, T> where 496 R::GuardMarker: Send 497 { 498 } 499 500 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> { 501 /// Makes a new `MappedMutexGuard` for a component of the locked data. 502 /// 503 /// This operation cannot fail as the `MappedMutexGuard` passed 504 /// in already locked the mutex. 505 /// 506 /// This is an associated function that needs to be 507 /// used as `MappedMutexGuard::map(...)`. A method would interfere with methods of 508 /// the same name on the contents of the locked data. 509 #[inline] map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> where F: FnOnce(&mut T) -> &mut U,510 pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> 511 where 512 F: FnOnce(&mut T) -> &mut U, 513 { 514 let raw = s.raw; 515 let data = f(unsafe { &mut *s.data }); 516 mem::forget(s); 517 MappedMutexGuard { raw, data, marker: PhantomData } 518 } 519 520 /// Attempts to make a new `MappedMutexGuard` for a component of the 521 /// locked data. The original guard is return if the closure returns `None`. 522 /// 523 /// This operation cannot fail as the `MappedMutexGuard` passed 524 /// in already locked the mutex. 525 /// 526 /// This is an associated function that needs to be 527 /// used as `MappedMutexGuard::map(...)`. A method would interfere with methods of 528 /// the same name on the contents of the locked data. 529 #[inline] try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> where F: FnOnce(&mut T) -> Option<&mut U>,530 pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> 531 where 532 F: FnOnce(&mut T) -> Option<&mut U>, 533 { 534 let raw = s.raw; 535 let data = match f(unsafe { &mut *s.data }) { 536 Some(data) => data, 537 None => return Err(s), 538 }; 539 mem::forget(s); 540 Ok(MappedMutexGuard { raw, data, marker: PhantomData }) 541 } 542 } 543 544 impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> { 545 /// Unlocks the mutex using a fair unlock protocol. 546 /// 547 /// By default, mutexes are unfair and allow the current thread to re-lock 548 /// the mutex before another has the chance to acquire the lock, even if 549 /// that thread has been blocked on the mutex for a long time. This is the 550 /// default because it allows much higher throughput as it avoids forcing a 551 /// context switch on every mutex unlock. This can result in one thread 552 /// acquiring a mutex many more times than other threads. 553 /// 554 /// However in some cases it can be beneficial to ensure fairness by forcing 555 /// the lock to pass on to a waiting thread if there is one. This is done by 556 /// using this method instead of dropping the `MutexGuard` normally. 557 #[inline] unlock_fair(s: Self)558 pub fn unlock_fair(s: Self) { 559 s.raw.unlock_fair(); 560 mem::forget(s); 561 } 562 } 563 564 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MappedMutexGuard<'a, R, T> { 565 type Target = T; 566 #[inline] deref(&self) -> &T567 fn deref(&self) -> &T { 568 unsafe { &*self.data } 569 } 570 } 571 572 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MappedMutexGuard<'a, R, T> { 573 #[inline] deref_mut(&mut self) -> &mut T574 fn deref_mut(&mut self) -> &mut T { 575 unsafe { &mut *self.data } 576 } 577 } 578 579 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MappedMutexGuard<'a, R, T> { 580 #[inline] drop(&mut self)581 fn drop(&mut self) { 582 self.raw.unlock(); 583 } 584 } 585 586 impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MappedMutexGuard<'a, R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result587 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 588 fmt::Debug::fmt(&**self, f) 589 } 590 } 591 592 impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display 593 for MappedMutexGuard<'a, R, T> 594 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result595 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 596 (**self).fmt(f) 597 } 598 } 599 600 #[cfg(feature = "owning_ref")] 601 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MappedMutexGuard<'a, R, T> {} 602