1 // Copyright 2016 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 reader-writer lock. 28 /// 29 /// Types implementing this trait can be used by `RwLock` to form a safe and 30 /// fully-functioning `RwLock` type. 31 /// 32 /// # Safety 33 /// 34 /// Implementations of this trait must ensure that the `RwLock` is actually 35 /// exclusive: an exclusive lock can't be acquired while an exclusive or shared 36 /// lock exists, and a shared lock can't be acquire while an exclusive lock 37 /// exists. 38 pub unsafe trait RawRwLock { 39 /// Initial value for an unlocked `RwLock`. 40 // A “non-constant” const item is a legacy way to supply an initialized value to downstream 41 // static items. Can hopefully be replaced with `const fn new() -> Self` at some point. 42 #[allow(clippy::declare_interior_mutable_const)] 43 const INIT: Self; 44 45 /// Marker type which determines whether a lock guard should be `Send`. Use 46 /// one of the `GuardSend` or `GuardNoSend` helper types here. 47 type GuardMarker; 48 49 /// Acquires a shared lock, blocking the current thread until it is able to do so. lock_shared(&self)50 fn lock_shared(&self); 51 52 /// Attempts to acquire a shared lock without blocking. try_lock_shared(&self) -> bool53 fn try_lock_shared(&self) -> bool; 54 55 /// Releases a shared lock. 56 /// 57 /// # Safety 58 /// 59 /// This method may only be called if a shared lock is held in the current context. unlock_shared(&self)60 unsafe fn unlock_shared(&self); 61 62 /// Acquires an exclusive lock, blocking the current thread until it is able to do so. lock_exclusive(&self)63 fn lock_exclusive(&self); 64 65 /// Attempts to acquire an exclusive lock without blocking. try_lock_exclusive(&self) -> bool66 fn try_lock_exclusive(&self) -> bool; 67 68 /// Releases an exclusive lock. 69 /// 70 /// # Safety 71 /// 72 /// This method may only be called if an exclusive lock is held in the current context. unlock_exclusive(&self)73 unsafe fn unlock_exclusive(&self); 74 75 /// Checks if this `RwLock` is currently locked in any way. 76 #[inline] is_locked(&self) -> bool77 fn is_locked(&self) -> bool { 78 let acquired_lock = self.try_lock_exclusive(); 79 if acquired_lock { 80 // Safety: A lock was successfully acquired above. 81 unsafe { 82 self.unlock_exclusive(); 83 } 84 } 85 !acquired_lock 86 } 87 88 /// Check if this `RwLock` is currently exclusively locked. is_locked_exclusive(&self) -> bool89 fn is_locked_exclusive(&self) -> bool { 90 let acquired_lock = self.try_lock_shared(); 91 if acquired_lock { 92 // Safety: A shared lock was successfully acquired above. 93 unsafe { 94 self.unlock_shared(); 95 } 96 } 97 !acquired_lock 98 } 99 } 100 101 /// Additional methods for RwLocks which support fair unlocking. 102 /// 103 /// Fair unlocking means that a lock is handed directly over to the next waiting 104 /// thread if there is one, without giving other threads the opportunity to 105 /// "steal" the lock in the meantime. This is typically slower than unfair 106 /// unlocking, but may be necessary in certain circumstances. 107 pub unsafe trait RawRwLockFair: RawRwLock { 108 /// Releases a shared lock using a fair unlock protocol. 109 /// 110 /// # Safety 111 /// 112 /// This method may only be called if a shared lock is held in the current context. unlock_shared_fair(&self)113 unsafe fn unlock_shared_fair(&self); 114 115 /// Releases an exclusive lock using a fair unlock protocol. 116 /// 117 /// # Safety 118 /// 119 /// This method may only be called if an exclusive lock is held in the current context. unlock_exclusive_fair(&self)120 unsafe fn unlock_exclusive_fair(&self); 121 122 /// Temporarily yields a shared lock to a waiting thread if there is one. 123 /// 124 /// This method is functionally equivalent to calling `unlock_shared_fair` followed 125 /// by `lock_shared`, however it can be much more efficient in the case where there 126 /// are no waiting threads. 127 /// 128 /// # Safety 129 /// 130 /// This method may only be called if a shared lock is held in the current context. bump_shared(&self)131 unsafe fn bump_shared(&self) { 132 self.unlock_shared_fair(); 133 self.lock_shared(); 134 } 135 136 /// Temporarily yields an exclusive lock to a waiting thread if there is one. 137 /// 138 /// This method is functionally equivalent to calling `unlock_exclusive_fair` followed 139 /// by `lock_exclusive`, however it can be much more efficient in the case where there 140 /// are no waiting threads. 141 /// 142 /// # Safety 143 /// 144 /// This method may only be called if an exclusive lock is held in the current context. bump_exclusive(&self)145 unsafe fn bump_exclusive(&self) { 146 self.unlock_exclusive_fair(); 147 self.lock_exclusive(); 148 } 149 } 150 151 /// Additional methods for RwLocks which support atomically downgrading an 152 /// exclusive lock to a shared lock. 153 pub unsafe trait RawRwLockDowngrade: RawRwLock { 154 /// Atomically downgrades an exclusive lock into a shared lock without 155 /// allowing any thread to take an exclusive lock in the meantime. 156 /// 157 /// # Safety 158 /// 159 /// This method may only be called if an exclusive lock is held in the current context. downgrade(&self)160 unsafe fn downgrade(&self); 161 } 162 163 /// Additional methods for RwLocks which support locking with timeouts. 164 /// 165 /// The `Duration` and `Instant` types are specified as associated types so that 166 /// this trait is usable even in `no_std` environments. 167 pub unsafe trait RawRwLockTimed: RawRwLock { 168 /// Duration type used for `try_lock_for`. 169 type Duration; 170 171 /// Instant type used for `try_lock_until`. 172 type Instant; 173 174 /// Attempts to acquire a shared lock until a timeout is reached. try_lock_shared_for(&self, timeout: Self::Duration) -> bool175 fn try_lock_shared_for(&self, timeout: Self::Duration) -> bool; 176 177 /// Attempts to acquire a shared lock until a timeout is reached. try_lock_shared_until(&self, timeout: Self::Instant) -> bool178 fn try_lock_shared_until(&self, timeout: Self::Instant) -> bool; 179 180 /// Attempts to acquire an exclusive lock until a timeout is reached. try_lock_exclusive_for(&self, timeout: Self::Duration) -> bool181 fn try_lock_exclusive_for(&self, timeout: Self::Duration) -> bool; 182 183 /// Attempts to acquire an exclusive lock until a timeout is reached. try_lock_exclusive_until(&self, timeout: Self::Instant) -> bool184 fn try_lock_exclusive_until(&self, timeout: Self::Instant) -> bool; 185 } 186 187 /// Additional methods for RwLocks which support recursive read locks. 188 /// 189 /// These are guaranteed to succeed without blocking if 190 /// another read lock is held at the time of the call. This allows a thread 191 /// to recursively lock a `RwLock`. However using this method can cause 192 /// writers to starve since readers no longer block if a writer is waiting 193 /// for the lock. 194 pub unsafe trait RawRwLockRecursive: RawRwLock { 195 /// Acquires a shared lock without deadlocking in case of a recursive lock. lock_shared_recursive(&self)196 fn lock_shared_recursive(&self); 197 198 /// Attempts to acquire a shared lock without deadlocking in case of a recursive lock. try_lock_shared_recursive(&self) -> bool199 fn try_lock_shared_recursive(&self) -> bool; 200 } 201 202 /// Additional methods for RwLocks which support recursive read locks and timeouts. 203 pub unsafe trait RawRwLockRecursiveTimed: RawRwLockRecursive + RawRwLockTimed { 204 /// Attempts to acquire a shared lock until a timeout is reached, without 205 /// deadlocking in case of a recursive lock. try_lock_shared_recursive_for(&self, timeout: Self::Duration) -> bool206 fn try_lock_shared_recursive_for(&self, timeout: Self::Duration) -> bool; 207 208 /// Attempts to acquire a shared lock until a timeout is reached, without 209 /// deadlocking in case of a recursive lock. try_lock_shared_recursive_until(&self, timeout: Self::Instant) -> bool210 fn try_lock_shared_recursive_until(&self, timeout: Self::Instant) -> bool; 211 } 212 213 /// Additional methods for RwLocks which support atomically upgrading a shared 214 /// lock to an exclusive lock. 215 /// 216 /// This requires acquiring a special "upgradable read lock" instead of a 217 /// normal shared lock. There may only be one upgradable lock at any time, 218 /// otherwise deadlocks could occur when upgrading. 219 pub unsafe trait RawRwLockUpgrade: RawRwLock { 220 /// Acquires an upgradable lock, blocking the current thread until it is able to do so. lock_upgradable(&self)221 fn lock_upgradable(&self); 222 223 /// Attempts to acquire an upgradable lock without blocking. try_lock_upgradable(&self) -> bool224 fn try_lock_upgradable(&self) -> bool; 225 226 /// Releases an upgradable lock. 227 /// 228 /// # Safety 229 /// 230 /// This method may only be called if an upgradable lock is held in the current context. unlock_upgradable(&self)231 unsafe fn unlock_upgradable(&self); 232 233 /// Upgrades an upgradable lock to an exclusive lock. 234 /// 235 /// # Safety 236 /// 237 /// This method may only be called if an upgradable lock is held in the current context. upgrade(&self)238 unsafe fn upgrade(&self); 239 240 /// Attempts to upgrade an upgradable lock to an exclusive lock without 241 /// blocking. 242 /// 243 /// # Safety 244 /// 245 /// This method may only be called if an upgradable lock is held in the current context. try_upgrade(&self) -> bool246 unsafe fn try_upgrade(&self) -> bool; 247 } 248 249 /// Additional methods for RwLocks which support upgradable locks and fair 250 /// unlocking. 251 pub unsafe trait RawRwLockUpgradeFair: RawRwLockUpgrade + RawRwLockFair { 252 /// Releases an upgradable lock using a fair unlock protocol. 253 /// 254 /// # Safety 255 /// 256 /// This method may only be called if an upgradable lock is held in the current context. unlock_upgradable_fair(&self)257 unsafe fn unlock_upgradable_fair(&self); 258 259 /// Temporarily yields an upgradable lock to a waiting thread if there is one. 260 /// 261 /// This method is functionally equivalent to calling `unlock_upgradable_fair` followed 262 /// by `lock_upgradable`, however it can be much more efficient in the case where there 263 /// are no waiting threads. 264 /// 265 /// # Safety 266 /// 267 /// This method may only be called if an upgradable lock is held in the current context. bump_upgradable(&self)268 unsafe fn bump_upgradable(&self) { 269 self.unlock_upgradable_fair(); 270 self.lock_upgradable(); 271 } 272 } 273 274 /// Additional methods for RwLocks which support upgradable locks and lock 275 /// downgrading. 276 pub unsafe trait RawRwLockUpgradeDowngrade: RawRwLockUpgrade + RawRwLockDowngrade { 277 /// Downgrades an upgradable lock to a shared lock. 278 /// 279 /// # Safety 280 /// 281 /// This method may only be called if an upgradable lock is held in the current context. downgrade_upgradable(&self)282 unsafe fn downgrade_upgradable(&self); 283 284 /// Downgrades an exclusive lock to an upgradable lock. 285 /// 286 /// # Safety 287 /// 288 /// This method may only be called if an exclusive lock is held in the current context. downgrade_to_upgradable(&self)289 unsafe fn downgrade_to_upgradable(&self); 290 } 291 292 /// Additional methods for RwLocks which support upgradable locks and locking 293 /// with timeouts. 294 pub unsafe trait RawRwLockUpgradeTimed: RawRwLockUpgrade + RawRwLockTimed { 295 /// Attempts to acquire an upgradable lock until a timeout is reached. try_lock_upgradable_for(&self, timeout: Self::Duration) -> bool296 fn try_lock_upgradable_for(&self, timeout: Self::Duration) -> bool; 297 298 /// Attempts to acquire an upgradable lock until a timeout is reached. try_lock_upgradable_until(&self, timeout: Self::Instant) -> bool299 fn try_lock_upgradable_until(&self, timeout: Self::Instant) -> bool; 300 301 /// Attempts to upgrade an upgradable lock to an exclusive lock until a 302 /// timeout is reached. 303 /// 304 /// # Safety 305 /// 306 /// This method may only be called if an upgradable lock is held in the current context. try_upgrade_for(&self, timeout: Self::Duration) -> bool307 unsafe fn try_upgrade_for(&self, timeout: Self::Duration) -> bool; 308 309 /// Attempts to upgrade an upgradable lock to an exclusive lock until a 310 /// timeout is reached. 311 /// 312 /// # Safety 313 /// 314 /// This method may only be called if an upgradable lock is held in the current context. try_upgrade_until(&self, timeout: Self::Instant) -> bool315 unsafe fn try_upgrade_until(&self, timeout: Self::Instant) -> bool; 316 } 317 318 /// A reader-writer lock 319 /// 320 /// This type of lock allows a number of readers or at most one writer at any 321 /// point in time. The write portion of this lock typically allows modification 322 /// of the underlying data (exclusive access) and the read portion of this lock 323 /// typically allows for read-only access (shared access). 324 /// 325 /// The type parameter `T` represents the data that this lock protects. It is 326 /// required that `T` satisfies `Send` to be shared across threads and `Sync` to 327 /// allow concurrent access through readers. The RAII guards returned from the 328 /// locking methods implement `Deref` (and `DerefMut` for the `write` methods) 329 /// to allow access to the contained of the lock. 330 pub struct RwLock<R, T: ?Sized> { 331 raw: R, 332 data: UnsafeCell<T>, 333 } 334 335 // Copied and modified from serde 336 #[cfg(feature = "serde")] 337 impl<R, T> Serialize for RwLock<R, T> 338 where 339 R: RawRwLock, 340 T: Serialize + ?Sized, 341 { serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,342 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 343 where 344 S: Serializer, 345 { 346 self.read().serialize(serializer) 347 } 348 } 349 350 #[cfg(feature = "serde")] 351 impl<'de, R, T> Deserialize<'de> for RwLock<R, T> 352 where 353 R: RawRwLock, 354 T: Deserialize<'de> + ?Sized, 355 { deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,356 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 357 where 358 D: Deserializer<'de>, 359 { 360 Deserialize::deserialize(deserializer).map(RwLock::new) 361 } 362 } 363 364 unsafe impl<R: RawRwLock + Send, T: ?Sized + Send> Send for RwLock<R, T> {} 365 unsafe impl<R: RawRwLock + Sync, T: ?Sized + Send + Sync> Sync for RwLock<R, T> {} 366 367 impl<R: RawRwLock, T> RwLock<R, T> { 368 /// Creates a new instance of an `RwLock<T>` which is unlocked. 369 #[cfg(has_const_fn_trait_bound)] 370 #[inline] new(val: T) -> RwLock<R, T>371 pub const fn new(val: T) -> RwLock<R, T> { 372 RwLock { 373 data: UnsafeCell::new(val), 374 raw: R::INIT, 375 } 376 } 377 378 /// Creates a new instance of an `RwLock<T>` which is unlocked. 379 #[cfg(not(has_const_fn_trait_bound))] 380 #[inline] new(val: T) -> RwLock<R, T>381 pub fn new(val: T) -> RwLock<R, T> { 382 RwLock { 383 data: UnsafeCell::new(val), 384 raw: R::INIT, 385 } 386 } 387 388 /// Consumes this `RwLock`, returning the underlying data. 389 #[inline] 390 #[allow(unused_unsafe)] into_inner(self) -> T391 pub fn into_inner(self) -> T { 392 unsafe { self.data.into_inner() } 393 } 394 } 395 396 impl<R, T> RwLock<R, T> { 397 /// Creates a new new instance of an `RwLock<T>` based on a pre-existing 398 /// `RawRwLock<T>`. 399 /// 400 /// This allows creating a `RwLock<T>` in a constant context on stable 401 /// Rust. 402 #[inline] const_new(raw_rwlock: R, val: T) -> RwLock<R, T>403 pub const fn const_new(raw_rwlock: R, val: T) -> RwLock<R, T> { 404 RwLock { 405 data: UnsafeCell::new(val), 406 raw: raw_rwlock, 407 } 408 } 409 } 410 411 impl<R: RawRwLock, T: ?Sized> RwLock<R, T> { 412 /// Creates a new `RwLockReadGuard` without checking if the lock is held. 413 /// 414 /// # Safety 415 /// 416 /// This method must only be called if the thread logically holds a read lock. 417 /// 418 /// This function does not increment the read count of the lock. Calling this function when a 419 /// guard has already been produced is undefined behaviour unless the guard was forgotten 420 /// with `mem::forget`.` 421 #[inline] make_read_guard_unchecked(&self) -> RwLockReadGuard<'_, R, T>422 pub unsafe fn make_read_guard_unchecked(&self) -> RwLockReadGuard<'_, R, T> { 423 RwLockReadGuard { 424 rwlock: self, 425 marker: PhantomData, 426 } 427 } 428 429 /// Creates a new `RwLockReadGuard` without checking if the lock is held. 430 /// 431 /// # Safety 432 /// 433 /// This method must only be called if the thread logically holds a write lock. 434 /// 435 /// Calling this function when a guard has already been produced is undefined behaviour unless 436 /// the guard was forgotten with `mem::forget`. 437 #[inline] make_write_guard_unchecked(&self) -> RwLockWriteGuard<'_, R, T>438 pub unsafe fn make_write_guard_unchecked(&self) -> RwLockWriteGuard<'_, R, T> { 439 RwLockWriteGuard { 440 rwlock: self, 441 marker: PhantomData, 442 } 443 } 444 445 /// Locks this `RwLock` with shared read access, blocking the current thread 446 /// until it can be acquired. 447 /// 448 /// The calling thread will be blocked until there are no more writers which 449 /// hold the lock. There may be other readers currently inside the lock when 450 /// this method returns. 451 /// 452 /// Note that attempts to recursively acquire a read lock on a `RwLock` when 453 /// the current thread already holds one may result in a deadlock. 454 /// 455 /// Returns an RAII guard which will release this thread's shared access 456 /// once it is dropped. 457 #[inline] read(&self) -> RwLockReadGuard<'_, R, T>458 pub fn read(&self) -> RwLockReadGuard<'_, R, T> { 459 self.raw.lock_shared(); 460 // SAFETY: The lock is held, as required. 461 unsafe { self.make_read_guard_unchecked() } 462 } 463 464 /// Attempts to acquire this `RwLock` with shared read access. 465 /// 466 /// If the access could not be granted at this time, then `None` is returned. 467 /// Otherwise, an RAII guard is returned which will release the shared access 468 /// when it is dropped. 469 /// 470 /// This function does not block. 471 #[inline] try_read(&self) -> Option<RwLockReadGuard<'_, R, T>>472 pub fn try_read(&self) -> Option<RwLockReadGuard<'_, R, T>> { 473 if self.raw.try_lock_shared() { 474 // SAFETY: The lock is held, as required. 475 Some(unsafe { self.make_read_guard_unchecked() }) 476 } else { 477 None 478 } 479 } 480 481 /// Locks this `RwLock` with exclusive write access, blocking the current 482 /// thread until it can be acquired. 483 /// 484 /// This function will not return while other writers or other readers 485 /// currently have access to the lock. 486 /// 487 /// Returns an RAII guard which will drop the write access of this `RwLock` 488 /// when dropped. 489 #[inline] write(&self) -> RwLockWriteGuard<'_, R, T>490 pub fn write(&self) -> RwLockWriteGuard<'_, R, T> { 491 self.raw.lock_exclusive(); 492 // SAFETY: The lock is held, as required. 493 unsafe { self.make_write_guard_unchecked() } 494 } 495 496 /// Attempts to lock this `RwLock` with exclusive write access. 497 /// 498 /// If the lock could not be acquired at this time, then `None` is returned. 499 /// Otherwise, an RAII guard is returned which will release the lock when 500 /// it is dropped. 501 /// 502 /// This function does not block. 503 #[inline] try_write(&self) -> Option<RwLockWriteGuard<'_, R, T>>504 pub fn try_write(&self) -> Option<RwLockWriteGuard<'_, R, T>> { 505 if self.raw.try_lock_exclusive() { 506 // SAFETY: The lock is held, as required. 507 Some(unsafe { self.make_write_guard_unchecked() }) 508 } else { 509 None 510 } 511 } 512 513 /// Returns a mutable reference to the underlying data. 514 /// 515 /// Since this call borrows the `RwLock` mutably, no actual locking needs to 516 /// take place---the mutable borrow statically guarantees no locks exist. 517 #[inline] get_mut(&mut self) -> &mut T518 pub fn get_mut(&mut self) -> &mut T { 519 unsafe { &mut *self.data.get() } 520 } 521 522 /// Checks whether this `RwLock` is currently locked in any way. 523 #[inline] is_locked(&self) -> bool524 pub fn is_locked(&self) -> bool { 525 self.raw.is_locked() 526 } 527 528 /// Check if this `RwLock` is currently exclusively locked. 529 #[inline] is_locked_exclusive(&self) -> bool530 pub fn is_locked_exclusive(&self) -> bool { 531 self.raw.is_locked_exclusive() 532 } 533 534 /// Forcibly unlocks a read lock. 535 /// 536 /// This is useful when combined with `mem::forget` to hold a lock without 537 /// the need to maintain a `RwLockReadGuard` object alive, for example when 538 /// dealing with FFI. 539 /// 540 /// # Safety 541 /// 542 /// This method must only be called if the current thread logically owns a 543 /// `RwLockReadGuard` but that guard has be discarded using `mem::forget`. 544 /// Behavior is undefined if a rwlock is read-unlocked when not read-locked. 545 #[inline] force_unlock_read(&self)546 pub unsafe fn force_unlock_read(&self) { 547 self.raw.unlock_shared(); 548 } 549 550 /// Forcibly unlocks a write lock. 551 /// 552 /// This is useful when combined with `mem::forget` to hold a lock without 553 /// the need to maintain a `RwLockWriteGuard` object alive, for example when 554 /// dealing with FFI. 555 /// 556 /// # Safety 557 /// 558 /// This method must only be called if the current thread logically owns a 559 /// `RwLockWriteGuard` but that guard has be discarded using `mem::forget`. 560 /// Behavior is undefined if a rwlock is write-unlocked when not write-locked. 561 #[inline] force_unlock_write(&self)562 pub unsafe fn force_unlock_write(&self) { 563 self.raw.unlock_exclusive(); 564 } 565 566 /// Returns the underlying raw reader-writer lock object. 567 /// 568 /// Note that you will most likely need to import the `RawRwLock` trait from 569 /// `lock_api` to be able to call functions on the raw 570 /// reader-writer lock. 571 /// 572 /// # Safety 573 /// 574 /// This method is unsafe because it allows unlocking a mutex while 575 /// still holding a reference to a lock guard. raw(&self) -> &R576 pub unsafe fn raw(&self) -> &R { 577 &self.raw 578 } 579 580 /// Returns a raw pointer to the underlying data. 581 /// 582 /// This is useful when combined with `mem::forget` to hold a lock without 583 /// the need to maintain a `RwLockReadGuard` or `RwLockWriteGuard` object 584 /// alive, for example when dealing with FFI. 585 /// 586 /// # Safety 587 /// 588 /// You must ensure that there are no data races when dereferencing the 589 /// returned pointer, for example if the current thread logically owns a 590 /// `RwLockReadGuard` or `RwLockWriteGuard` but that guard has been discarded 591 /// using `mem::forget`. 592 #[inline] data_ptr(&self) -> *mut T593 pub fn data_ptr(&self) -> *mut T { 594 self.data.get() 595 } 596 597 /// Creates a new `RwLockReadGuard` without checking if the lock is held. 598 /// 599 /// # Safety 600 /// 601 /// This method must only be called if the thread logically holds a read lock. 602 /// 603 /// This function does not increment the read count of the lock. Calling this function when a 604 /// guard has already been produced is undefined behaviour unless the guard was forgotten 605 /// with `mem::forget`.` 606 #[cfg(feature = "arc_lock")] 607 #[inline] make_arc_read_guard_unchecked(self: &Arc<Self>) -> ArcRwLockReadGuard<R, T>608 pub unsafe fn make_arc_read_guard_unchecked(self: &Arc<Self>) -> ArcRwLockReadGuard<R, T> { 609 ArcRwLockReadGuard { 610 rwlock: self.clone(), 611 marker: PhantomData, 612 } 613 } 614 615 /// Creates a new `RwLockWriteGuard` without checking if the lock is held. 616 /// 617 /// # Safety 618 /// 619 /// This method must only be called if the thread logically holds a write lock. 620 /// 621 /// Calling this function when a guard has already been produced is undefined behaviour unless 622 /// the guard was forgotten with `mem::forget`. 623 #[cfg(feature = "arc_lock")] 624 #[inline] make_arc_write_guard_unchecked(self: &Arc<Self>) -> ArcRwLockWriteGuard<R, T>625 pub unsafe fn make_arc_write_guard_unchecked(self: &Arc<Self>) -> ArcRwLockWriteGuard<R, T> { 626 ArcRwLockWriteGuard { 627 rwlock: self.clone(), 628 marker: PhantomData, 629 } 630 } 631 632 /// Locks this `RwLock` with read access, through an `Arc`. 633 /// 634 /// This method is similar to the `read` method; however, it requires the `RwLock` to be inside of an `Arc` 635 /// and the resulting read guard has no lifetime requirements. 636 #[cfg(feature = "arc_lock")] 637 #[inline] read_arc(self: &Arc<Self>) -> ArcRwLockReadGuard<R, T>638 pub fn read_arc(self: &Arc<Self>) -> ArcRwLockReadGuard<R, T> { 639 self.raw.lock_shared(); 640 // SAFETY: locking guarantee is upheld 641 unsafe { self.make_arc_read_guard_unchecked() } 642 } 643 644 /// Attempts to lock this `RwLock` with read access, through an `Arc`. 645 /// 646 /// This method is similar to the `try_read` method; however, it requires the `RwLock` to be inside of an 647 /// `Arc` and the resulting read guard has no lifetime requirements. 648 #[cfg(feature = "arc_lock")] 649 #[inline] try_read_arc(self: &Arc<Self>) -> Option<ArcRwLockReadGuard<R, T>>650 pub fn try_read_arc(self: &Arc<Self>) -> Option<ArcRwLockReadGuard<R, T>> { 651 if self.raw.try_lock_shared() { 652 // SAFETY: locking guarantee is upheld 653 Some(unsafe { self.make_arc_read_guard_unchecked() }) 654 } else { 655 None 656 } 657 } 658 659 /// Locks this `RwLock` with write access, through an `Arc`. 660 /// 661 /// This method is similar to the `write` method; however, it requires the `RwLock` to be inside of an `Arc` 662 /// and the resulting write guard has no lifetime requirements. 663 #[cfg(feature = "arc_lock")] 664 #[inline] write_arc(self: &Arc<Self>) -> ArcRwLockWriteGuard<R, T>665 pub fn write_arc(self: &Arc<Self>) -> ArcRwLockWriteGuard<R, T> { 666 self.raw.lock_exclusive(); 667 // SAFETY: locking guarantee is upheld 668 unsafe { self.make_arc_write_guard_unchecked() } 669 } 670 671 /// Attempts to lock this `RwLock` with writ access, through an `Arc`. 672 /// 673 /// This method is similar to the `try_write` method; however, it requires the `RwLock` to be inside of an 674 /// `Arc` and the resulting write guard has no lifetime requirements. 675 #[cfg(feature = "arc_lock")] 676 #[inline] try_write_arc(self: &Arc<Self>) -> Option<ArcRwLockWriteGuard<R, T>>677 pub fn try_write_arc(self: &Arc<Self>) -> Option<ArcRwLockWriteGuard<R, T>> { 678 if self.raw.try_lock_exclusive() { 679 // SAFETY: locking guarantee is upheld 680 Some(unsafe { self.make_arc_write_guard_unchecked() }) 681 } else { 682 None 683 } 684 } 685 } 686 687 impl<R: RawRwLockFair, T: ?Sized> RwLock<R, T> { 688 /// Forcibly unlocks a read lock using a fair unlock procotol. 689 /// 690 /// This is useful when combined with `mem::forget` to hold a lock without 691 /// the need to maintain a `RwLockReadGuard` object alive, for example when 692 /// dealing with FFI. 693 /// 694 /// # Safety 695 /// 696 /// This method must only be called if the current thread logically owns a 697 /// `RwLockReadGuard` but that guard has be discarded using `mem::forget`. 698 /// Behavior is undefined if a rwlock is read-unlocked when not read-locked. 699 #[inline] force_unlock_read_fair(&self)700 pub unsafe fn force_unlock_read_fair(&self) { 701 self.raw.unlock_shared_fair(); 702 } 703 704 /// Forcibly unlocks a write lock using a fair unlock procotol. 705 /// 706 /// This is useful when combined with `mem::forget` to hold a lock without 707 /// the need to maintain a `RwLockWriteGuard` object alive, for example when 708 /// dealing with FFI. 709 /// 710 /// # Safety 711 /// 712 /// This method must only be called if the current thread logically owns a 713 /// `RwLockWriteGuard` but that guard has be discarded using `mem::forget`. 714 /// Behavior is undefined if a rwlock is write-unlocked when not write-locked. 715 #[inline] force_unlock_write_fair(&self)716 pub unsafe fn force_unlock_write_fair(&self) { 717 self.raw.unlock_exclusive_fair(); 718 } 719 } 720 721 impl<R: RawRwLockTimed, T: ?Sized> RwLock<R, T> { 722 /// Attempts to acquire this `RwLock` with shared read access until a timeout 723 /// is reached. 724 /// 725 /// If the access could not be granted before the timeout expires, then 726 /// `None` is returned. Otherwise, an RAII guard is returned which will 727 /// release the shared access when it is dropped. 728 #[inline] try_read_for(&self, timeout: R::Duration) -> Option<RwLockReadGuard<'_, R, T>>729 pub fn try_read_for(&self, timeout: R::Duration) -> Option<RwLockReadGuard<'_, R, T>> { 730 if self.raw.try_lock_shared_for(timeout) { 731 // SAFETY: The lock is held, as required. 732 Some(unsafe { self.make_read_guard_unchecked() }) 733 } else { 734 None 735 } 736 } 737 738 /// Attempts to acquire this `RwLock` with shared read access until a timeout 739 /// is reached. 740 /// 741 /// If the access could not be granted before the timeout expires, then 742 /// `None` is returned. Otherwise, an RAII guard is returned which will 743 /// release the shared access when it is dropped. 744 #[inline] try_read_until(&self, timeout: R::Instant) -> Option<RwLockReadGuard<'_, R, T>>745 pub fn try_read_until(&self, timeout: R::Instant) -> Option<RwLockReadGuard<'_, R, T>> { 746 if self.raw.try_lock_shared_until(timeout) { 747 // SAFETY: The lock is held, as required. 748 Some(unsafe { self.make_read_guard_unchecked() }) 749 } else { 750 None 751 } 752 } 753 754 /// Attempts to acquire this `RwLock` with exclusive write access until a 755 /// timeout is reached. 756 /// 757 /// If the access could not be granted before the timeout expires, then 758 /// `None` is returned. Otherwise, an RAII guard is returned which will 759 /// release the exclusive access when it is dropped. 760 #[inline] try_write_for(&self, timeout: R::Duration) -> Option<RwLockWriteGuard<'_, R, T>>761 pub fn try_write_for(&self, timeout: R::Duration) -> Option<RwLockWriteGuard<'_, R, T>> { 762 if self.raw.try_lock_exclusive_for(timeout) { 763 // SAFETY: The lock is held, as required. 764 Some(unsafe { self.make_write_guard_unchecked() }) 765 } else { 766 None 767 } 768 } 769 770 /// Attempts to acquire this `RwLock` with exclusive write access until a 771 /// timeout is reached. 772 /// 773 /// If the access could not be granted before the timeout expires, then 774 /// `None` is returned. Otherwise, an RAII guard is returned which will 775 /// release the exclusive access when it is dropped. 776 #[inline] try_write_until(&self, timeout: R::Instant) -> Option<RwLockWriteGuard<'_, R, T>>777 pub fn try_write_until(&self, timeout: R::Instant) -> Option<RwLockWriteGuard<'_, R, T>> { 778 if self.raw.try_lock_exclusive_until(timeout) { 779 // SAFETY: The lock is held, as required. 780 Some(unsafe { self.make_write_guard_unchecked() }) 781 } else { 782 None 783 } 784 } 785 786 /// Attempts to acquire this `RwLock` with read access until a timeout is reached, through an `Arc`. 787 /// 788 /// This method is similar to the `try_read_for` method; however, it requires the `RwLock` to be inside of an 789 /// `Arc` and the resulting read guard has no lifetime requirements. 790 #[cfg(feature = "arc_lock")] 791 #[inline] try_read_arc_for( self: &Arc<Self>, timeout: R::Duration, ) -> Option<ArcRwLockReadGuard<R, T>>792 pub fn try_read_arc_for( 793 self: &Arc<Self>, 794 timeout: R::Duration, 795 ) -> Option<ArcRwLockReadGuard<R, T>> { 796 if self.raw.try_lock_shared_for(timeout) { 797 // SAFETY: locking guarantee is upheld 798 Some(unsafe { self.make_arc_read_guard_unchecked() }) 799 } else { 800 None 801 } 802 } 803 804 /// Attempts to acquire this `RwLock` with read access until a timeout is reached, through an `Arc`. 805 /// 806 /// This method is similar to the `try_read_until` method; however, it requires the `RwLock` to be inside of 807 /// an `Arc` and the resulting read guard has no lifetime requirements. 808 #[cfg(feature = "arc_lock")] 809 #[inline] try_read_arc_until( self: &Arc<Self>, timeout: R::Instant, ) -> Option<ArcRwLockReadGuard<R, T>>810 pub fn try_read_arc_until( 811 self: &Arc<Self>, 812 timeout: R::Instant, 813 ) -> Option<ArcRwLockReadGuard<R, T>> { 814 if self.raw.try_lock_shared_until(timeout) { 815 // SAFETY: locking guarantee is upheld 816 Some(unsafe { self.make_arc_read_guard_unchecked() }) 817 } else { 818 None 819 } 820 } 821 822 /// Attempts to acquire this `RwLock` with write access until a timeout is reached, through an `Arc`. 823 /// 824 /// This method is similar to the `try_write_for` method; however, it requires the `RwLock` to be inside of 825 /// an `Arc` and the resulting write guard has no lifetime requirements. 826 #[cfg(feature = "arc_lock")] 827 #[inline] try_write_arc_for( self: &Arc<Self>, timeout: R::Duration, ) -> Option<ArcRwLockWriteGuard<R, T>>828 pub fn try_write_arc_for( 829 self: &Arc<Self>, 830 timeout: R::Duration, 831 ) -> Option<ArcRwLockWriteGuard<R, T>> { 832 if self.raw.try_lock_exclusive_for(timeout) { 833 // SAFETY: locking guarantee is upheld 834 Some(unsafe { self.make_arc_write_guard_unchecked() }) 835 } else { 836 None 837 } 838 } 839 840 /// Attempts to acquire this `RwLock` with read access until a timeout is reached, through an `Arc`. 841 /// 842 /// This method is similar to the `try_write_until` method; however, it requires the `RwLock` to be inside of 843 /// an `Arc` and the resulting read guard has no lifetime requirements. 844 #[cfg(feature = "arc_lock")] 845 #[inline] try_write_arc_until( self: &Arc<Self>, timeout: R::Instant, ) -> Option<ArcRwLockWriteGuard<R, T>>846 pub fn try_write_arc_until( 847 self: &Arc<Self>, 848 timeout: R::Instant, 849 ) -> Option<ArcRwLockWriteGuard<R, T>> { 850 if self.raw.try_lock_exclusive_until(timeout) { 851 // SAFETY: locking guarantee is upheld 852 Some(unsafe { self.make_arc_write_guard_unchecked() }) 853 } else { 854 None 855 } 856 } 857 } 858 859 impl<R: RawRwLockRecursive, T: ?Sized> RwLock<R, T> { 860 /// Locks this `RwLock` with shared read access, blocking the current thread 861 /// until it can be acquired. 862 /// 863 /// The calling thread will be blocked until there are no more writers which 864 /// hold the lock. There may be other readers currently inside the lock when 865 /// this method returns. 866 /// 867 /// Unlike `read`, this method is guaranteed to succeed without blocking if 868 /// another read lock is held at the time of the call. This allows a thread 869 /// to recursively lock a `RwLock`. However using this method can cause 870 /// writers to starve since readers no longer block if a writer is waiting 871 /// for the lock. 872 /// 873 /// Returns an RAII guard which will release this thread's shared access 874 /// once it is dropped. 875 #[inline] read_recursive(&self) -> RwLockReadGuard<'_, R, T>876 pub fn read_recursive(&self) -> RwLockReadGuard<'_, R, T> { 877 self.raw.lock_shared_recursive(); 878 // SAFETY: The lock is held, as required. 879 unsafe { self.make_read_guard_unchecked() } 880 } 881 882 /// Attempts to acquire this `RwLock` with shared read access. 883 /// 884 /// If the access could not be granted at this time, then `None` is returned. 885 /// Otherwise, an RAII guard is returned which will release the shared access 886 /// when it is dropped. 887 /// 888 /// This method is guaranteed to succeed if another read lock is held at the 889 /// time of the call. See the documentation for `read_recursive` for details. 890 /// 891 /// This function does not block. 892 #[inline] try_read_recursive(&self) -> Option<RwLockReadGuard<'_, R, T>>893 pub fn try_read_recursive(&self) -> Option<RwLockReadGuard<'_, R, T>> { 894 if self.raw.try_lock_shared_recursive() { 895 // SAFETY: The lock is held, as required. 896 Some(unsafe { self.make_read_guard_unchecked() }) 897 } else { 898 None 899 } 900 } 901 902 /// Locks this `RwLock` with shared read access, through an `Arc`. 903 /// 904 /// This method is similar to the `read_recursive` method; however, it requires the `RwLock` to be inside of 905 /// an `Arc` and the resulting read guard has no lifetime requirements. 906 #[cfg(feature = "arc_lock")] 907 #[inline] read_arc_recursive(self: &Arc<Self>) -> ArcRwLockReadGuard<R, T>908 pub fn read_arc_recursive(self: &Arc<Self>) -> ArcRwLockReadGuard<R, T> { 909 self.raw.lock_shared_recursive(); 910 // SAFETY: locking guarantee is upheld 911 unsafe { self.make_arc_read_guard_unchecked() } 912 } 913 914 /// Attempts to lock this `RwLock` with shared read access, through an `Arc`. 915 /// 916 /// This method is similar to the `try_read_recursive` method; however, it requires the `RwLock` to be inside 917 /// of an `Arc` and the resulting read guard has no lifetime requirements. 918 #[cfg(feature = "arc_lock")] 919 #[inline] try_read_recursive_arc(self: &Arc<Self>) -> Option<ArcRwLockReadGuard<R, T>>920 pub fn try_read_recursive_arc(self: &Arc<Self>) -> Option<ArcRwLockReadGuard<R, T>> { 921 if self.raw.try_lock_shared_recursive() { 922 // SAFETY: locking guarantee is upheld 923 Some(unsafe { self.make_arc_read_guard_unchecked() }) 924 } else { 925 None 926 } 927 } 928 } 929 930 impl<R: RawRwLockRecursiveTimed, T: ?Sized> RwLock<R, T> { 931 /// Attempts to acquire this `RwLock` with shared read access until a timeout 932 /// is reached. 933 /// 934 /// If the access could not be granted before the timeout expires, then 935 /// `None` is returned. Otherwise, an RAII guard is returned which will 936 /// release the shared access when it is dropped. 937 /// 938 /// This method is guaranteed to succeed without blocking if another read 939 /// lock is held at the time of the call. See the documentation for 940 /// `read_recursive` for details. 941 #[inline] try_read_recursive_for( &self, timeout: R::Duration, ) -> Option<RwLockReadGuard<'_, R, T>>942 pub fn try_read_recursive_for( 943 &self, 944 timeout: R::Duration, 945 ) -> Option<RwLockReadGuard<'_, R, T>> { 946 if self.raw.try_lock_shared_recursive_for(timeout) { 947 // SAFETY: The lock is held, as required. 948 Some(unsafe { self.make_read_guard_unchecked() }) 949 } else { 950 None 951 } 952 } 953 954 /// Attempts to acquire this `RwLock` with shared read access until a timeout 955 /// is reached. 956 /// 957 /// If the access could not be granted before the timeout expires, then 958 /// `None` is returned. Otherwise, an RAII guard is returned which will 959 /// release the shared access when it is dropped. 960 #[inline] try_read_recursive_until( &self, timeout: R::Instant, ) -> Option<RwLockReadGuard<'_, R, T>>961 pub fn try_read_recursive_until( 962 &self, 963 timeout: R::Instant, 964 ) -> Option<RwLockReadGuard<'_, R, T>> { 965 if self.raw.try_lock_shared_recursive_until(timeout) { 966 // SAFETY: The lock is held, as required. 967 Some(unsafe { self.make_read_guard_unchecked() }) 968 } else { 969 None 970 } 971 } 972 973 /// Attempts to lock this `RwLock` with read access until a timeout is reached, through an `Arc`. 974 /// 975 /// This method is similar to the `try_read_recursive_for` method; however, it requires the `RwLock` to be 976 /// inside of an `Arc` and the resulting read guard has no lifetime requirements. 977 #[cfg(feature = "arc_lock")] 978 #[inline] try_read_arc_recursive_for( self: &Arc<Self>, timeout: R::Duration, ) -> Option<ArcRwLockReadGuard<R, T>>979 pub fn try_read_arc_recursive_for( 980 self: &Arc<Self>, 981 timeout: R::Duration, 982 ) -> Option<ArcRwLockReadGuard<R, T>> { 983 if self.raw.try_lock_shared_recursive_for(timeout) { 984 // SAFETY: locking guarantee is upheld 985 Some(unsafe { self.make_arc_read_guard_unchecked() }) 986 } else { 987 None 988 } 989 } 990 991 /// Attempts to lock this `RwLock` with read access until a timeout is reached, through an `Arc`. 992 /// 993 /// This method is similar to the `try_read_recursive_until` method; however, it requires the `RwLock` to be 994 /// inside of an `Arc` and the resulting read guard has no lifetime requirements. 995 #[cfg(feature = "arc_lock")] 996 #[inline] try_read_arc_recursive_until( self: &Arc<Self>, timeout: R::Instant, ) -> Option<ArcRwLockReadGuard<R, T>>997 pub fn try_read_arc_recursive_until( 998 self: &Arc<Self>, 999 timeout: R::Instant, 1000 ) -> Option<ArcRwLockReadGuard<R, T>> { 1001 if self.raw.try_lock_shared_recursive_until(timeout) { 1002 // SAFETY: locking guarantee is upheld 1003 Some(unsafe { self.make_arc_read_guard_unchecked() }) 1004 } else { 1005 None 1006 } 1007 } 1008 } 1009 1010 impl<R: RawRwLockUpgrade, T: ?Sized> RwLock<R, T> { 1011 /// Creates a new `RwLockUpgradableReadGuard` without checking if the lock is held. 1012 /// 1013 /// # Safety 1014 /// 1015 /// This method must only be called if the thread logically holds an upgradable read lock. 1016 /// 1017 /// This function does not increment the read count of the lock. Calling this function when a 1018 /// guard has already been produced is undefined behaviour unless the guard was forgotten 1019 /// with `mem::forget`.` 1020 #[inline] make_upgradable_guard_unchecked(&self) -> RwLockUpgradableReadGuard<'_, R, T>1021 pub unsafe fn make_upgradable_guard_unchecked(&self) -> RwLockUpgradableReadGuard<'_, R, T> { 1022 RwLockUpgradableReadGuard { 1023 rwlock: self, 1024 marker: PhantomData, 1025 } 1026 } 1027 1028 /// Locks this `RwLock` with upgradable read access, blocking the current thread 1029 /// until it can be acquired. 1030 /// 1031 /// The calling thread will be blocked until there are no more writers or other 1032 /// upgradable reads which hold the lock. There may be other readers currently 1033 /// inside the lock when this method returns. 1034 /// 1035 /// Returns an RAII guard which will release this thread's shared access 1036 /// once it is dropped. 1037 #[inline] upgradable_read(&self) -> RwLockUpgradableReadGuard<'_, R, T>1038 pub fn upgradable_read(&self) -> RwLockUpgradableReadGuard<'_, R, T> { 1039 self.raw.lock_upgradable(); 1040 // SAFETY: The lock is held, as required. 1041 unsafe { self.make_upgradable_guard_unchecked() } 1042 } 1043 1044 /// Attempts to acquire this `RwLock` with upgradable read access. 1045 /// 1046 /// If the access could not be granted at this time, then `None` is returned. 1047 /// Otherwise, an RAII guard is returned which will release the shared access 1048 /// when it is dropped. 1049 /// 1050 /// This function does not block. 1051 #[inline] try_upgradable_read(&self) -> Option<RwLockUpgradableReadGuard<'_, R, T>>1052 pub fn try_upgradable_read(&self) -> Option<RwLockUpgradableReadGuard<'_, R, T>> { 1053 if self.raw.try_lock_upgradable() { 1054 // SAFETY: The lock is held, as required. 1055 Some(unsafe { self.make_upgradable_guard_unchecked() }) 1056 } else { 1057 None 1058 } 1059 } 1060 1061 /// Creates a new `ArcRwLockUpgradableReadGuard` without checking if the lock is held. 1062 /// 1063 /// # Safety 1064 /// 1065 /// This method must only be called if the thread logically holds an upgradable read lock. 1066 /// 1067 /// This function does not increment the read count of the lock. Calling this function when a 1068 /// guard has already been produced is undefined behaviour unless the guard was forgotten 1069 /// with `mem::forget`.` 1070 #[cfg(feature = "arc_lock")] 1071 #[inline] make_upgradable_arc_guard_unchecked( self: &Arc<Self>, ) -> ArcRwLockUpgradableReadGuard<R, T>1072 pub unsafe fn make_upgradable_arc_guard_unchecked( 1073 self: &Arc<Self>, 1074 ) -> ArcRwLockUpgradableReadGuard<R, T> { 1075 ArcRwLockUpgradableReadGuard { 1076 rwlock: self.clone(), 1077 marker: PhantomData, 1078 } 1079 } 1080 1081 /// Locks this `RwLock` with upgradable read access, through an `Arc`. 1082 /// 1083 /// This method is similar to the `upgradable_read` method; however, it requires the `RwLock` to be 1084 /// inside of an `Arc` and the resulting read guard has no lifetime requirements. 1085 #[cfg(feature = "arc_lock")] 1086 #[inline] upgradable_read_arc(self: &Arc<Self>) -> ArcRwLockUpgradableReadGuard<R, T>1087 pub fn upgradable_read_arc(self: &Arc<Self>) -> ArcRwLockUpgradableReadGuard<R, T> { 1088 self.raw.lock_upgradable(); 1089 // SAFETY: locking guarantee is upheld 1090 unsafe { self.make_upgradable_arc_guard_unchecked() } 1091 } 1092 1093 /// Attempts to lock this `RwLock` with upgradable read access, through an `Arc`. 1094 /// 1095 /// This method is similar to the `try_upgradable_read` method; however, it requires the `RwLock` to be 1096 /// inside of an `Arc` and the resulting read guard has no lifetime requirements. 1097 #[cfg(feature = "arc_lock")] 1098 #[inline] try_upgradable_read_arc(self: &Arc<Self>) -> Option<ArcRwLockUpgradableReadGuard<R, T>>1099 pub fn try_upgradable_read_arc(self: &Arc<Self>) -> Option<ArcRwLockUpgradableReadGuard<R, T>> { 1100 if self.raw.try_lock_upgradable() { 1101 // SAFETY: locking guarantee is upheld 1102 Some(unsafe { self.make_upgradable_arc_guard_unchecked() }) 1103 } else { 1104 None 1105 } 1106 } 1107 } 1108 1109 impl<R: RawRwLockUpgradeTimed, T: ?Sized> RwLock<R, T> { 1110 /// Attempts to acquire this `RwLock` with upgradable read access until a timeout 1111 /// is reached. 1112 /// 1113 /// If the access could not be granted before the timeout expires, then 1114 /// `None` is returned. Otherwise, an RAII guard is returned which will 1115 /// release the shared access when it is dropped. 1116 #[inline] try_upgradable_read_for( &self, timeout: R::Duration, ) -> Option<RwLockUpgradableReadGuard<'_, R, T>>1117 pub fn try_upgradable_read_for( 1118 &self, 1119 timeout: R::Duration, 1120 ) -> Option<RwLockUpgradableReadGuard<'_, R, T>> { 1121 if self.raw.try_lock_upgradable_for(timeout) { 1122 // SAFETY: The lock is held, as required. 1123 Some(unsafe { self.make_upgradable_guard_unchecked() }) 1124 } else { 1125 None 1126 } 1127 } 1128 1129 /// Attempts to acquire this `RwLock` with upgradable read access until a timeout 1130 /// is reached. 1131 /// 1132 /// If the access could not be granted before the timeout expires, then 1133 /// `None` is returned. Otherwise, an RAII guard is returned which will 1134 /// release the shared access when it is dropped. 1135 #[inline] try_upgradable_read_until( &self, timeout: R::Instant, ) -> Option<RwLockUpgradableReadGuard<'_, R, T>>1136 pub fn try_upgradable_read_until( 1137 &self, 1138 timeout: R::Instant, 1139 ) -> Option<RwLockUpgradableReadGuard<'_, R, T>> { 1140 if self.raw.try_lock_upgradable_until(timeout) { 1141 // SAFETY: The lock is held, as required. 1142 Some(unsafe { self.make_upgradable_guard_unchecked() }) 1143 } else { 1144 None 1145 } 1146 } 1147 1148 /// Attempts to lock this `RwLock` with upgradable access until a timeout is reached, through an `Arc`. 1149 /// 1150 /// This method is similar to the `try_upgradable_read_for` method; however, it requires the `RwLock` to be 1151 /// inside of an `Arc` and the resulting read guard has no lifetime requirements. 1152 #[cfg(feature = "arc_lock")] 1153 #[inline] try_upgradable_read_arc_for( self: &Arc<Self>, timeout: R::Duration, ) -> Option<ArcRwLockUpgradableReadGuard<R, T>>1154 pub fn try_upgradable_read_arc_for( 1155 self: &Arc<Self>, 1156 timeout: R::Duration, 1157 ) -> Option<ArcRwLockUpgradableReadGuard<R, T>> { 1158 if self.raw.try_lock_upgradable_for(timeout) { 1159 // SAFETY: locking guarantee is upheld 1160 Some(unsafe { self.make_upgradable_arc_guard_unchecked() }) 1161 } else { 1162 None 1163 } 1164 } 1165 1166 /// Attempts to lock this `RwLock` with upgradable access until a timeout is reached, through an `Arc`. 1167 /// 1168 /// This method is similar to the `try_upgradable_read_until` method; however, it requires the `RwLock` to be 1169 /// inside of an `Arc` and the resulting read guard has no lifetime requirements. 1170 #[cfg(feature = "arc_lock")] 1171 #[inline] try_upgradable_read_arc_until( self: &Arc<Self>, timeout: R::Instant, ) -> Option<ArcRwLockUpgradableReadGuard<R, T>>1172 pub fn try_upgradable_read_arc_until( 1173 self: &Arc<Self>, 1174 timeout: R::Instant, 1175 ) -> Option<ArcRwLockUpgradableReadGuard<R, T>> { 1176 if self.raw.try_lock_upgradable_until(timeout) { 1177 // SAFETY: locking guarantee is upheld 1178 Some(unsafe { self.make_upgradable_arc_guard_unchecked() }) 1179 } else { 1180 None 1181 } 1182 } 1183 } 1184 1185 impl<R: RawRwLock, T: ?Sized + Default> Default for RwLock<R, T> { 1186 #[inline] default() -> RwLock<R, T>1187 fn default() -> RwLock<R, T> { 1188 RwLock::new(Default::default()) 1189 } 1190 } 1191 1192 impl<R: RawRwLock, T> From<T> for RwLock<R, T> { 1193 #[inline] from(t: T) -> RwLock<R, T>1194 fn from(t: T) -> RwLock<R, T> { 1195 RwLock::new(t) 1196 } 1197 } 1198 1199 impl<R: RawRwLock, T: ?Sized + fmt::Debug> fmt::Debug for RwLock<R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1200 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1201 match self.try_read() { 1202 Some(guard) => f.debug_struct("RwLock").field("data", &&*guard).finish(), 1203 None => { 1204 struct LockedPlaceholder; 1205 impl fmt::Debug for LockedPlaceholder { 1206 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1207 f.write_str("<locked>") 1208 } 1209 } 1210 1211 f.debug_struct("RwLock") 1212 .field("data", &LockedPlaceholder) 1213 .finish() 1214 } 1215 } 1216 } 1217 } 1218 1219 /// RAII structure used to release the shared read access of a lock when 1220 /// dropped. 1221 #[clippy::has_significant_drop] 1222 #[must_use = "if unused the RwLock will immediately unlock"] 1223 pub struct RwLockReadGuard<'a, R: RawRwLock, T: ?Sized> { 1224 rwlock: &'a RwLock<R, T>, 1225 marker: PhantomData<(&'a T, R::GuardMarker)>, 1226 } 1227 1228 unsafe impl<R: RawRwLock + Sync, T: Sync + ?Sized> Sync for RwLockReadGuard<'_, R, T> {} 1229 1230 impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> RwLockReadGuard<'a, R, T> { 1231 /// Returns a reference to the original reader-writer lock object. rwlock(s: &Self) -> &'a RwLock<R, T>1232 pub fn rwlock(s: &Self) -> &'a RwLock<R, T> { 1233 s.rwlock 1234 } 1235 1236 /// Make a new `MappedRwLockReadGuard` for a component of the locked data. 1237 /// 1238 /// This operation cannot fail as the `RwLockReadGuard` passed 1239 /// in already locked the data. 1240 /// 1241 /// This is an associated function that needs to be 1242 /// used as `RwLockReadGuard::map(...)`. A method would interfere with methods of 1243 /// the same name on the contents of the locked data. 1244 #[inline] map<U: ?Sized, F>(s: Self, f: F) -> MappedRwLockReadGuard<'a, R, U> where F: FnOnce(&T) -> &U,1245 pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedRwLockReadGuard<'a, R, U> 1246 where 1247 F: FnOnce(&T) -> &U, 1248 { 1249 let raw = &s.rwlock.raw; 1250 let data = f(unsafe { &*s.rwlock.data.get() }); 1251 mem::forget(s); 1252 MappedRwLockReadGuard { 1253 raw, 1254 data, 1255 marker: PhantomData, 1256 } 1257 } 1258 1259 /// Attempts to make a new `MappedRwLockReadGuard` for a component of the 1260 /// locked data. Returns the original guard if the closure returns `None`. 1261 /// 1262 /// This operation cannot fail as the `RwLockReadGuard` passed 1263 /// in already locked the data. 1264 /// 1265 /// This is an associated function that needs to be 1266 /// used as `RwLockReadGuard::try_map(...)`. A method would interfere with methods of 1267 /// the same name on the contents of the locked data. 1268 #[inline] try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedRwLockReadGuard<'a, R, U>, Self> where F: FnOnce(&T) -> Option<&U>,1269 pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedRwLockReadGuard<'a, R, U>, Self> 1270 where 1271 F: FnOnce(&T) -> Option<&U>, 1272 { 1273 let raw = &s.rwlock.raw; 1274 let data = match f(unsafe { &*s.rwlock.data.get() }) { 1275 Some(data) => data, 1276 None => return Err(s), 1277 }; 1278 mem::forget(s); 1279 Ok(MappedRwLockReadGuard { 1280 raw, 1281 data, 1282 marker: PhantomData, 1283 }) 1284 } 1285 1286 /// Temporarily unlocks the `RwLock` to execute the given function. 1287 /// 1288 /// This is safe because `&mut` guarantees that there exist no other 1289 /// references to the data protected by the `RwLock`. 1290 #[inline] unlocked<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,1291 pub fn unlocked<F, U>(s: &mut Self, f: F) -> U 1292 where 1293 F: FnOnce() -> U, 1294 { 1295 // Safety: An RwLockReadGuard always holds a shared lock. 1296 unsafe { 1297 s.rwlock.raw.unlock_shared(); 1298 } 1299 defer!(s.rwlock.raw.lock_shared()); 1300 f() 1301 } 1302 } 1303 1304 impl<'a, R: RawRwLockFair + 'a, T: ?Sized + 'a> RwLockReadGuard<'a, R, T> { 1305 /// Unlocks the `RwLock` using a fair unlock protocol. 1306 /// 1307 /// By default, `RwLock` is unfair and allow the current thread to re-lock 1308 /// the `RwLock` before another has the chance to acquire the lock, even if 1309 /// that thread has been blocked on the `RwLock` for a long time. This is 1310 /// the default because it allows much higher throughput as it avoids 1311 /// forcing a context switch on every `RwLock` unlock. This can result in one 1312 /// thread acquiring a `RwLock` many more times than other threads. 1313 /// 1314 /// However in some cases it can be beneficial to ensure fairness by forcing 1315 /// the lock to pass on to a waiting thread if there is one. This is done by 1316 /// using this method instead of dropping the `RwLockReadGuard` normally. 1317 #[inline] unlock_fair(s: Self)1318 pub fn unlock_fair(s: Self) { 1319 // Safety: An RwLockReadGuard always holds a shared lock. 1320 unsafe { 1321 s.rwlock.raw.unlock_shared_fair(); 1322 } 1323 mem::forget(s); 1324 } 1325 1326 /// Temporarily unlocks the `RwLock` to execute the given function. 1327 /// 1328 /// The `RwLock` is unlocked a fair unlock protocol. 1329 /// 1330 /// This is safe because `&mut` guarantees that there exist no other 1331 /// references to the data protected by the `RwLock`. 1332 #[inline] unlocked_fair<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,1333 pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U 1334 where 1335 F: FnOnce() -> U, 1336 { 1337 // Safety: An RwLockReadGuard always holds a shared lock. 1338 unsafe { 1339 s.rwlock.raw.unlock_shared_fair(); 1340 } 1341 defer!(s.rwlock.raw.lock_shared()); 1342 f() 1343 } 1344 1345 /// Temporarily yields the `RwLock` to a waiting thread if there is one. 1346 /// 1347 /// This method is functionally equivalent to calling `unlock_fair` followed 1348 /// by `read`, however it can be much more efficient in the case where there 1349 /// are no waiting threads. 1350 #[inline] bump(s: &mut Self)1351 pub fn bump(s: &mut Self) { 1352 // Safety: An RwLockReadGuard always holds a shared lock. 1353 unsafe { 1354 s.rwlock.raw.bump_shared(); 1355 } 1356 } 1357 } 1358 1359 impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Deref for RwLockReadGuard<'a, R, T> { 1360 type Target = T; 1361 #[inline] deref(&self) -> &T1362 fn deref(&self) -> &T { 1363 unsafe { &*self.rwlock.data.get() } 1364 } 1365 } 1366 1367 impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Drop for RwLockReadGuard<'a, R, T> { 1368 #[inline] drop(&mut self)1369 fn drop(&mut self) { 1370 // Safety: An RwLockReadGuard always holds a shared lock. 1371 unsafe { 1372 self.rwlock.raw.unlock_shared(); 1373 } 1374 } 1375 } 1376 1377 impl<'a, R: RawRwLock + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for RwLockReadGuard<'a, R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1378 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1379 fmt::Debug::fmt(&**self, f) 1380 } 1381 } 1382 1383 impl<'a, R: RawRwLock + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display 1384 for RwLockReadGuard<'a, R, T> 1385 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1386 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1387 (**self).fmt(f) 1388 } 1389 } 1390 1391 #[cfg(feature = "owning_ref")] 1392 unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> StableAddress for RwLockReadGuard<'a, R, T> {} 1393 1394 /// An RAII rwlock guard returned by the `Arc` locking operations on `RwLock`. 1395 /// 1396 /// This is similar to the `RwLockReadGuard` struct, except instead of using a reference to unlock the `RwLock` 1397 /// it uses an `Arc<RwLock>`. This has several advantages, most notably that it has an `'static` lifetime. 1398 #[cfg(feature = "arc_lock")] 1399 #[clippy::has_significant_drop] 1400 #[must_use = "if unused the RwLock will immediately unlock"] 1401 pub struct ArcRwLockReadGuard<R: RawRwLock, T: ?Sized> { 1402 rwlock: Arc<RwLock<R, T>>, 1403 marker: PhantomData<R::GuardMarker>, 1404 } 1405 1406 #[cfg(feature = "arc_lock")] 1407 impl<R: RawRwLock, T: ?Sized> ArcRwLockReadGuard<R, T> { 1408 /// Returns a reference to the rwlock, contained in its `Arc`. rwlock(s: &Self) -> &Arc<RwLock<R, T>>1409 pub fn rwlock(s: &Self) -> &Arc<RwLock<R, T>> { 1410 &s.rwlock 1411 } 1412 1413 /// Temporarily unlocks the `RwLock` to execute the given function. 1414 /// 1415 /// This is functionally identical to the `unlocked` method on [`RwLockReadGuard`]. 1416 #[inline] unlocked<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,1417 pub fn unlocked<F, U>(s: &mut Self, f: F) -> U 1418 where 1419 F: FnOnce() -> U, 1420 { 1421 // Safety: An RwLockReadGuard always holds a shared lock. 1422 unsafe { 1423 s.rwlock.raw.unlock_shared(); 1424 } 1425 defer!(s.rwlock.raw.lock_shared()); 1426 f() 1427 } 1428 } 1429 1430 #[cfg(feature = "arc_lock")] 1431 impl<R: RawRwLockFair, T: ?Sized> ArcRwLockReadGuard<R, T> { 1432 /// Unlocks the `RwLock` using a fair unlock protocol. 1433 /// 1434 /// This is functionally identical to the `unlock_fair` method on [`RwLockReadGuard`]. 1435 #[inline] unlock_fair(s: Self)1436 pub fn unlock_fair(s: Self) { 1437 // Safety: An RwLockReadGuard always holds a shared lock. 1438 unsafe { 1439 s.rwlock.raw.unlock_shared_fair(); 1440 } 1441 1442 // SAFETY: ensure the Arc has its refcount decremented 1443 let mut s = ManuallyDrop::new(s); 1444 unsafe { ptr::drop_in_place(&mut s.rwlock) }; 1445 } 1446 1447 /// Temporarily unlocks the `RwLock` to execute the given function. 1448 /// 1449 /// This is functionally identical to the `unlocked_fair` method on [`RwLockReadGuard`]. 1450 #[inline] unlocked_fair<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,1451 pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U 1452 where 1453 F: FnOnce() -> U, 1454 { 1455 // Safety: An RwLockReadGuard always holds a shared lock. 1456 unsafe { 1457 s.rwlock.raw.unlock_shared_fair(); 1458 } 1459 defer!(s.rwlock.raw.lock_shared()); 1460 f() 1461 } 1462 1463 /// Temporarily yields the `RwLock` to a waiting thread if there is one. 1464 /// 1465 /// This is functionally identical to the `bump` method on [`RwLockReadGuard`]. 1466 #[inline] bump(s: &mut Self)1467 pub fn bump(s: &mut Self) { 1468 // Safety: An RwLockReadGuard always holds a shared lock. 1469 unsafe { 1470 s.rwlock.raw.bump_shared(); 1471 } 1472 } 1473 } 1474 1475 #[cfg(feature = "arc_lock")] 1476 impl<R: RawRwLock, T: ?Sized> Deref for ArcRwLockReadGuard<R, T> { 1477 type Target = T; 1478 #[inline] deref(&self) -> &T1479 fn deref(&self) -> &T { 1480 unsafe { &*self.rwlock.data.get() } 1481 } 1482 } 1483 1484 #[cfg(feature = "arc_lock")] 1485 impl<R: RawRwLock, T: ?Sized> Drop for ArcRwLockReadGuard<R, T> { 1486 #[inline] drop(&mut self)1487 fn drop(&mut self) { 1488 // Safety: An RwLockReadGuard always holds a shared lock. 1489 unsafe { 1490 self.rwlock.raw.unlock_shared(); 1491 } 1492 } 1493 } 1494 1495 #[cfg(feature = "arc_lock")] 1496 impl<R: RawRwLock, T: fmt::Debug + ?Sized> fmt::Debug for ArcRwLockReadGuard<R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1497 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1498 fmt::Debug::fmt(&**self, f) 1499 } 1500 } 1501 1502 #[cfg(feature = "arc_lock")] 1503 impl<R: RawRwLock, T: fmt::Display + ?Sized> fmt::Display for ArcRwLockReadGuard<R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1504 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1505 (**self).fmt(f) 1506 } 1507 } 1508 1509 /// RAII structure used to release the exclusive write access of a lock when 1510 /// dropped. 1511 #[clippy::has_significant_drop] 1512 #[must_use = "if unused the RwLock will immediately unlock"] 1513 pub struct RwLockWriteGuard<'a, R: RawRwLock, T: ?Sized> { 1514 rwlock: &'a RwLock<R, T>, 1515 marker: PhantomData<(&'a mut T, R::GuardMarker)>, 1516 } 1517 1518 unsafe impl<R: RawRwLock + Sync, T: Sync + ?Sized> Sync for RwLockWriteGuard<'_, R, T> {} 1519 1520 impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> RwLockWriteGuard<'a, R, T> { 1521 /// Returns a reference to the original reader-writer lock object. rwlock(s: &Self) -> &'a RwLock<R, T>1522 pub fn rwlock(s: &Self) -> &'a RwLock<R, T> { 1523 s.rwlock 1524 } 1525 1526 /// Make a new `MappedRwLockWriteGuard` for a component of the locked data. 1527 /// 1528 /// This operation cannot fail as the `RwLockWriteGuard` passed 1529 /// in already locked the data. 1530 /// 1531 /// This is an associated function that needs to be 1532 /// used as `RwLockWriteGuard::map(...)`. A method would interfere with methods of 1533 /// the same name on the contents of the locked data. 1534 #[inline] map<U: ?Sized, F>(s: Self, f: F) -> MappedRwLockWriteGuard<'a, R, U> where F: FnOnce(&mut T) -> &mut U,1535 pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedRwLockWriteGuard<'a, R, U> 1536 where 1537 F: FnOnce(&mut T) -> &mut U, 1538 { 1539 let raw = &s.rwlock.raw; 1540 let data = f(unsafe { &mut *s.rwlock.data.get() }); 1541 mem::forget(s); 1542 MappedRwLockWriteGuard { 1543 raw, 1544 data, 1545 marker: PhantomData, 1546 } 1547 } 1548 1549 /// Attempts to make a new `MappedRwLockWriteGuard` for a component of the 1550 /// locked data. The original guard is return if the closure returns `None`. 1551 /// 1552 /// This operation cannot fail as the `RwLockWriteGuard` passed 1553 /// in already locked the data. 1554 /// 1555 /// This is an associated function that needs to be 1556 /// used as `RwLockWriteGuard::try_map(...)`. A method would interfere with methods of 1557 /// the same name on the contents of the locked data. 1558 #[inline] try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, R, U>, Self> where F: FnOnce(&mut T) -> Option<&mut U>,1559 pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, R, U>, Self> 1560 where 1561 F: FnOnce(&mut T) -> Option<&mut U>, 1562 { 1563 let raw = &s.rwlock.raw; 1564 let data = match f(unsafe { &mut *s.rwlock.data.get() }) { 1565 Some(data) => data, 1566 None => return Err(s), 1567 }; 1568 mem::forget(s); 1569 Ok(MappedRwLockWriteGuard { 1570 raw, 1571 data, 1572 marker: PhantomData, 1573 }) 1574 } 1575 1576 /// Temporarily unlocks the `RwLock` to execute the given function. 1577 /// 1578 /// This is safe because `&mut` guarantees that there exist no other 1579 /// references to the data protected by the `RwLock`. 1580 #[inline] unlocked<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,1581 pub fn unlocked<F, U>(s: &mut Self, f: F) -> U 1582 where 1583 F: FnOnce() -> U, 1584 { 1585 // Safety: An RwLockReadGuard always holds a shared lock. 1586 unsafe { 1587 s.rwlock.raw.unlock_exclusive(); 1588 } 1589 defer!(s.rwlock.raw.lock_exclusive()); 1590 f() 1591 } 1592 } 1593 1594 impl<'a, R: RawRwLockDowngrade + 'a, T: ?Sized + 'a> RwLockWriteGuard<'a, R, T> { 1595 /// Atomically downgrades a write lock into a read lock without allowing any 1596 /// writers to take exclusive access of the lock in the meantime. 1597 /// 1598 /// Note that if there are any writers currently waiting to take the lock 1599 /// then other readers may not be able to acquire the lock even if it was 1600 /// downgraded. downgrade(s: Self) -> RwLockReadGuard<'a, R, T>1601 pub fn downgrade(s: Self) -> RwLockReadGuard<'a, R, T> { 1602 // Safety: An RwLockWriteGuard always holds an exclusive lock. 1603 unsafe { 1604 s.rwlock.raw.downgrade(); 1605 } 1606 let rwlock = s.rwlock; 1607 mem::forget(s); 1608 RwLockReadGuard { 1609 rwlock, 1610 marker: PhantomData, 1611 } 1612 } 1613 } 1614 1615 impl<'a, R: RawRwLockUpgradeDowngrade + 'a, T: ?Sized + 'a> RwLockWriteGuard<'a, R, T> { 1616 /// Atomically downgrades a write lock into an upgradable read lock without allowing any 1617 /// writers to take exclusive access of the lock in the meantime. 1618 /// 1619 /// Note that if there are any writers currently waiting to take the lock 1620 /// then other readers may not be able to acquire the lock even if it was 1621 /// downgraded. downgrade_to_upgradable(s: Self) -> RwLockUpgradableReadGuard<'a, R, T>1622 pub fn downgrade_to_upgradable(s: Self) -> RwLockUpgradableReadGuard<'a, R, T> { 1623 // Safety: An RwLockWriteGuard always holds an exclusive lock. 1624 unsafe { 1625 s.rwlock.raw.downgrade_to_upgradable(); 1626 } 1627 let rwlock = s.rwlock; 1628 mem::forget(s); 1629 RwLockUpgradableReadGuard { 1630 rwlock, 1631 marker: PhantomData, 1632 } 1633 } 1634 } 1635 1636 impl<'a, R: RawRwLockFair + 'a, T: ?Sized + 'a> RwLockWriteGuard<'a, R, T> { 1637 /// Unlocks the `RwLock` using a fair unlock protocol. 1638 /// 1639 /// By default, `RwLock` is unfair and allow the current thread to re-lock 1640 /// the `RwLock` before another has the chance to acquire the lock, even if 1641 /// that thread has been blocked on the `RwLock` for a long time. This is 1642 /// the default because it allows much higher throughput as it avoids 1643 /// forcing a context switch on every `RwLock` unlock. This can result in one 1644 /// thread acquiring a `RwLock` many more times than other threads. 1645 /// 1646 /// However in some cases it can be beneficial to ensure fairness by forcing 1647 /// the lock to pass on to a waiting thread if there is one. This is done by 1648 /// using this method instead of dropping the `RwLockWriteGuard` normally. 1649 #[inline] unlock_fair(s: Self)1650 pub fn unlock_fair(s: Self) { 1651 // Safety: An RwLockWriteGuard always holds an exclusive lock. 1652 unsafe { 1653 s.rwlock.raw.unlock_exclusive_fair(); 1654 } 1655 mem::forget(s); 1656 } 1657 1658 /// Temporarily unlocks the `RwLock` to execute the given function. 1659 /// 1660 /// The `RwLock` is unlocked a fair unlock protocol. 1661 /// 1662 /// This is safe because `&mut` guarantees that there exist no other 1663 /// references to the data protected by the `RwLock`. 1664 #[inline] unlocked_fair<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,1665 pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U 1666 where 1667 F: FnOnce() -> U, 1668 { 1669 // Safety: An RwLockWriteGuard always holds an exclusive lock. 1670 unsafe { 1671 s.rwlock.raw.unlock_exclusive_fair(); 1672 } 1673 defer!(s.rwlock.raw.lock_exclusive()); 1674 f() 1675 } 1676 1677 /// Temporarily yields the `RwLock` to a waiting thread if there is one. 1678 /// 1679 /// This method is functionally equivalent to calling `unlock_fair` followed 1680 /// by `write`, however it can be much more efficient in the case where there 1681 /// are no waiting threads. 1682 #[inline] bump(s: &mut Self)1683 pub fn bump(s: &mut Self) { 1684 // Safety: An RwLockWriteGuard always holds an exclusive lock. 1685 unsafe { 1686 s.rwlock.raw.bump_exclusive(); 1687 } 1688 } 1689 } 1690 1691 impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Deref for RwLockWriteGuard<'a, R, T> { 1692 type Target = T; 1693 #[inline] deref(&self) -> &T1694 fn deref(&self) -> &T { 1695 unsafe { &*self.rwlock.data.get() } 1696 } 1697 } 1698 1699 impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> DerefMut for RwLockWriteGuard<'a, R, T> { 1700 #[inline] deref_mut(&mut self) -> &mut T1701 fn deref_mut(&mut self) -> &mut T { 1702 unsafe { &mut *self.rwlock.data.get() } 1703 } 1704 } 1705 1706 impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Drop for RwLockWriteGuard<'a, R, T> { 1707 #[inline] drop(&mut self)1708 fn drop(&mut self) { 1709 // Safety: An RwLockWriteGuard always holds an exclusive lock. 1710 unsafe { 1711 self.rwlock.raw.unlock_exclusive(); 1712 } 1713 } 1714 } 1715 1716 impl<'a, R: RawRwLock + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for RwLockWriteGuard<'a, R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1717 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1718 fmt::Debug::fmt(&**self, f) 1719 } 1720 } 1721 1722 impl<'a, R: RawRwLock + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display 1723 for RwLockWriteGuard<'a, R, T> 1724 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1725 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1726 (**self).fmt(f) 1727 } 1728 } 1729 1730 #[cfg(feature = "owning_ref")] 1731 unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> StableAddress for RwLockWriteGuard<'a, R, T> {} 1732 1733 /// An RAII rwlock guard returned by the `Arc` locking operations on `RwLock`. 1734 /// This is similar to the `RwLockWriteGuard` struct, except instead of using a reference to unlock the `RwLock` 1735 /// it uses an `Arc<RwLock>`. This has several advantages, most notably that it has an `'static` lifetime. 1736 #[cfg(feature = "arc_lock")] 1737 #[clippy::has_significant_drop] 1738 #[must_use = "if unused the RwLock will immediately unlock"] 1739 pub struct ArcRwLockWriteGuard<R: RawRwLock, T: ?Sized> { 1740 rwlock: Arc<RwLock<R, T>>, 1741 marker: PhantomData<R::GuardMarker>, 1742 } 1743 1744 #[cfg(feature = "arc_lock")] 1745 impl<R: RawRwLock, T: ?Sized> ArcRwLockWriteGuard<R, T> { 1746 /// Returns a reference to the rwlock, contained in its `Arc`. rwlock(s: &Self) -> &Arc<RwLock<R, T>>1747 pub fn rwlock(s: &Self) -> &Arc<RwLock<R, T>> { 1748 &s.rwlock 1749 } 1750 1751 /// Temporarily unlocks the `RwLock` to execute the given function. 1752 /// 1753 /// This is functionally equivalent to the `unlocked` method on [`RwLockWriteGuard`]. 1754 #[inline] unlocked<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,1755 pub fn unlocked<F, U>(s: &mut Self, f: F) -> U 1756 where 1757 F: FnOnce() -> U, 1758 { 1759 // Safety: An RwLockWriteGuard always holds a shared lock. 1760 unsafe { 1761 s.rwlock.raw.unlock_exclusive(); 1762 } 1763 defer!(s.rwlock.raw.lock_exclusive()); 1764 f() 1765 } 1766 } 1767 1768 #[cfg(feature = "arc_lock")] 1769 impl<R: RawRwLockDowngrade, T: ?Sized> ArcRwLockWriteGuard<R, T> { 1770 /// Atomically downgrades a write lock into a read lock without allowing any 1771 /// writers to take exclusive access of the lock in the meantime. 1772 /// 1773 /// This is functionally equivalent to the `downgrade` method on [`RwLockWriteGuard`]. downgrade(s: Self) -> ArcRwLockReadGuard<R, T>1774 pub fn downgrade(s: Self) -> ArcRwLockReadGuard<R, T> { 1775 // Safety: An RwLockWriteGuard always holds an exclusive lock. 1776 unsafe { 1777 s.rwlock.raw.downgrade(); 1778 } 1779 1780 // SAFETY: prevent the arc's refcount from changing using ManuallyDrop and ptr::read 1781 let s = ManuallyDrop::new(s); 1782 let rwlock = unsafe { ptr::read(&s.rwlock) }; 1783 1784 ArcRwLockReadGuard { 1785 rwlock, 1786 marker: PhantomData, 1787 } 1788 } 1789 } 1790 1791 #[cfg(feature = "arc_lock")] 1792 impl<R: RawRwLockUpgradeDowngrade, T: ?Sized> ArcRwLockWriteGuard<R, T> { 1793 /// Atomically downgrades a write lock into an upgradable read lock without allowing any 1794 /// writers to take exclusive access of the lock in the meantime. 1795 /// 1796 /// This is functionally identical to the `downgrade_to_upgradable` method on [`RwLockWriteGuard`]. downgrade_to_upgradable(s: Self) -> ArcRwLockUpgradableReadGuard<R, T>1797 pub fn downgrade_to_upgradable(s: Self) -> ArcRwLockUpgradableReadGuard<R, T> { 1798 // Safety: An RwLockWriteGuard always holds an exclusive lock. 1799 unsafe { 1800 s.rwlock.raw.downgrade_to_upgradable(); 1801 } 1802 1803 // SAFETY: same as above 1804 let s = ManuallyDrop::new(s); 1805 let rwlock = unsafe { ptr::read(&s.rwlock) }; 1806 1807 ArcRwLockUpgradableReadGuard { 1808 rwlock, 1809 marker: PhantomData, 1810 } 1811 } 1812 } 1813 1814 #[cfg(feature = "arc_lock")] 1815 impl<R: RawRwLockFair, T: ?Sized> ArcRwLockWriteGuard<R, T> { 1816 /// Unlocks the `RwLock` using a fair unlock protocol. 1817 /// 1818 /// This is functionally equivalent to the `unlock_fair` method on [`RwLockWriteGuard`]. 1819 #[inline] unlock_fair(s: Self)1820 pub fn unlock_fair(s: Self) { 1821 // Safety: An RwLockWriteGuard always holds an exclusive lock. 1822 unsafe { 1823 s.rwlock.raw.unlock_exclusive_fair(); 1824 } 1825 1826 // SAFETY: prevent the Arc from leaking memory 1827 let mut s = ManuallyDrop::new(s); 1828 unsafe { ptr::drop_in_place(&mut s.rwlock) }; 1829 } 1830 1831 /// Temporarily unlocks the `RwLock` to execute the given function. 1832 /// 1833 /// This is functionally equivalent to the `unlocked_fair` method on [`RwLockWriteGuard`]. 1834 #[inline] unlocked_fair<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,1835 pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U 1836 where 1837 F: FnOnce() -> U, 1838 { 1839 // Safety: An RwLockWriteGuard always holds an exclusive lock. 1840 unsafe { 1841 s.rwlock.raw.unlock_exclusive_fair(); 1842 } 1843 defer!(s.rwlock.raw.lock_exclusive()); 1844 f() 1845 } 1846 1847 /// Temporarily yields the `RwLock` to a waiting thread if there is one. 1848 /// 1849 /// This method is functionally equivalent to the `bump` method on [`RwLockWriteGuard`]. 1850 #[inline] bump(s: &mut Self)1851 pub fn bump(s: &mut Self) { 1852 // Safety: An RwLockWriteGuard always holds an exclusive lock. 1853 unsafe { 1854 s.rwlock.raw.bump_exclusive(); 1855 } 1856 } 1857 } 1858 1859 #[cfg(feature = "arc_lock")] 1860 impl<R: RawRwLock, T: ?Sized> Deref for ArcRwLockWriteGuard<R, T> { 1861 type Target = T; 1862 #[inline] deref(&self) -> &T1863 fn deref(&self) -> &T { 1864 unsafe { &*self.rwlock.data.get() } 1865 } 1866 } 1867 1868 #[cfg(feature = "arc_lock")] 1869 impl<R: RawRwLock, T: ?Sized> DerefMut for ArcRwLockWriteGuard<R, T> { 1870 #[inline] deref_mut(&mut self) -> &mut T1871 fn deref_mut(&mut self) -> &mut T { 1872 unsafe { &mut *self.rwlock.data.get() } 1873 } 1874 } 1875 1876 #[cfg(feature = "arc_lock")] 1877 impl<R: RawRwLock, T: ?Sized> Drop for ArcRwLockWriteGuard<R, T> { 1878 #[inline] drop(&mut self)1879 fn drop(&mut self) { 1880 // Safety: An RwLockWriteGuard always holds an exclusive lock. 1881 unsafe { 1882 self.rwlock.raw.unlock_exclusive(); 1883 } 1884 } 1885 } 1886 1887 #[cfg(feature = "arc_lock")] 1888 impl<R: RawRwLock, T: fmt::Debug + ?Sized> fmt::Debug for ArcRwLockWriteGuard<R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1889 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1890 fmt::Debug::fmt(&**self, f) 1891 } 1892 } 1893 1894 #[cfg(feature = "arc_lock")] 1895 impl<R: RawRwLock, T: fmt::Display + ?Sized> fmt::Display for ArcRwLockWriteGuard<R, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1896 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1897 (**self).fmt(f) 1898 } 1899 } 1900 1901 /// RAII structure used to release the upgradable read access of a lock when 1902 /// dropped. 1903 #[clippy::has_significant_drop] 1904 #[must_use = "if unused the RwLock will immediately unlock"] 1905 pub struct RwLockUpgradableReadGuard<'a, R: RawRwLockUpgrade, T: ?Sized> { 1906 rwlock: &'a RwLock<R, T>, 1907 marker: PhantomData<(&'a T, R::GuardMarker)>, 1908 } 1909 1910 unsafe impl<'a, R: RawRwLockUpgrade + 'a, T: ?Sized + Sync + 'a> Sync 1911 for RwLockUpgradableReadGuard<'a, R, T> 1912 { 1913 } 1914 1915 impl<'a, R: RawRwLockUpgrade + 'a, T: ?Sized + 'a> RwLockUpgradableReadGuard<'a, R, T> { 1916 /// Returns a reference to the original reader-writer lock object. rwlock(s: &Self) -> &'a RwLock<R, T>1917 pub fn rwlock(s: &Self) -> &'a RwLock<R, T> { 1918 s.rwlock 1919 } 1920 1921 /// Temporarily unlocks the `RwLock` to execute the given function. 1922 /// 1923 /// This is safe because `&mut` guarantees that there exist no other 1924 /// references to the data protected by the `RwLock`. 1925 #[inline] unlocked<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,1926 pub fn unlocked<F, U>(s: &mut Self, f: F) -> U 1927 where 1928 F: FnOnce() -> U, 1929 { 1930 // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. 1931 unsafe { 1932 s.rwlock.raw.unlock_upgradable(); 1933 } 1934 defer!(s.rwlock.raw.lock_upgradable()); 1935 f() 1936 } 1937 1938 /// Atomically upgrades an upgradable read lock lock into an exclusive write lock, 1939 /// blocking the current thread until it can be acquired. upgrade(s: Self) -> RwLockWriteGuard<'a, R, T>1940 pub fn upgrade(s: Self) -> RwLockWriteGuard<'a, R, T> { 1941 // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. 1942 unsafe { 1943 s.rwlock.raw.upgrade(); 1944 } 1945 let rwlock = s.rwlock; 1946 mem::forget(s); 1947 RwLockWriteGuard { 1948 rwlock, 1949 marker: PhantomData, 1950 } 1951 } 1952 1953 /// Tries to atomically upgrade an upgradable read lock into an exclusive write lock. 1954 /// 1955 /// If the access could not be granted at this time, then the current guard is returned. try_upgrade(s: Self) -> Result<RwLockWriteGuard<'a, R, T>, Self>1956 pub fn try_upgrade(s: Self) -> Result<RwLockWriteGuard<'a, R, T>, Self> { 1957 // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. 1958 if unsafe { s.rwlock.raw.try_upgrade() } { 1959 let rwlock = s.rwlock; 1960 mem::forget(s); 1961 Ok(RwLockWriteGuard { 1962 rwlock, 1963 marker: PhantomData, 1964 }) 1965 } else { 1966 Err(s) 1967 } 1968 } 1969 } 1970 1971 impl<'a, R: RawRwLockUpgradeFair + 'a, T: ?Sized + 'a> RwLockUpgradableReadGuard<'a, R, T> { 1972 /// Unlocks the `RwLock` using a fair unlock protocol. 1973 /// 1974 /// By default, `RwLock` is unfair and allow the current thread to re-lock 1975 /// the `RwLock` before another has the chance to acquire the lock, even if 1976 /// that thread has been blocked on the `RwLock` for a long time. This is 1977 /// the default because it allows much higher throughput as it avoids 1978 /// forcing a context switch on every `RwLock` unlock. This can result in one 1979 /// thread acquiring a `RwLock` many more times than other threads. 1980 /// 1981 /// However in some cases it can be beneficial to ensure fairness by forcing 1982 /// the lock to pass on to a waiting thread if there is one. This is done by 1983 /// using this method instead of dropping the `RwLockUpgradableReadGuard` normally. 1984 #[inline] unlock_fair(s: Self)1985 pub fn unlock_fair(s: Self) { 1986 // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. 1987 unsafe { 1988 s.rwlock.raw.unlock_upgradable_fair(); 1989 } 1990 mem::forget(s); 1991 } 1992 1993 /// Temporarily unlocks the `RwLock` to execute the given function. 1994 /// 1995 /// The `RwLock` is unlocked a fair unlock protocol. 1996 /// 1997 /// This is safe because `&mut` guarantees that there exist no other 1998 /// references to the data protected by the `RwLock`. 1999 #[inline] unlocked_fair<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,2000 pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U 2001 where 2002 F: FnOnce() -> U, 2003 { 2004 // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. 2005 unsafe { 2006 s.rwlock.raw.unlock_upgradable_fair(); 2007 } 2008 defer!(s.rwlock.raw.lock_upgradable()); 2009 f() 2010 } 2011 2012 /// Temporarily yields the `RwLock` to a waiting thread if there is one. 2013 /// 2014 /// This method is functionally equivalent to calling `unlock_fair` followed 2015 /// by `upgradable_read`, however it can be much more efficient in the case where there 2016 /// are no waiting threads. 2017 #[inline] bump(s: &mut Self)2018 pub fn bump(s: &mut Self) { 2019 // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. 2020 unsafe { 2021 s.rwlock.raw.bump_upgradable(); 2022 } 2023 } 2024 } 2025 2026 impl<'a, R: RawRwLockUpgradeDowngrade + 'a, T: ?Sized + 'a> RwLockUpgradableReadGuard<'a, R, T> { 2027 /// Atomically downgrades an upgradable read lock lock into a shared read lock 2028 /// without allowing any writers to take exclusive access of the lock in the 2029 /// meantime. 2030 /// 2031 /// Note that if there are any writers currently waiting to take the lock 2032 /// then other readers may not be able to acquire the lock even if it was 2033 /// downgraded. downgrade(s: Self) -> RwLockReadGuard<'a, R, T>2034 pub fn downgrade(s: Self) -> RwLockReadGuard<'a, R, T> { 2035 // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. 2036 unsafe { 2037 s.rwlock.raw.downgrade_upgradable(); 2038 } 2039 let rwlock = s.rwlock; 2040 mem::forget(s); 2041 RwLockReadGuard { 2042 rwlock, 2043 marker: PhantomData, 2044 } 2045 } 2046 2047 /// First, atomically upgrades an upgradable read lock lock into an exclusive write lock, 2048 /// blocking the current thread until it can be acquired. 2049 /// 2050 /// Then, calls the provided closure with an exclusive reference to the lock's data. 2051 /// 2052 /// Finally, atomically downgrades the lock back to an upgradable read lock. 2053 /// The closure's return value is wrapped in `Some` and returned. 2054 /// 2055 /// This function only requires a mutable reference to the guard, unlike 2056 /// `upgrade` which takes the guard by value. with_upgraded<Ret, F: FnOnce(&mut T) -> Ret>(&mut self, f: F) -> Ret2057 pub fn with_upgraded<Ret, F: FnOnce(&mut T) -> Ret>(&mut self, f: F) -> Ret { 2058 unsafe { 2059 self.rwlock.raw.upgrade(); 2060 } 2061 2062 // Safety: We just upgraded the lock, so we have mutable access to the data. 2063 // This will restore the state the lock was in at the start of the function. 2064 defer!(unsafe { self.rwlock.raw.downgrade_to_upgradable() }); 2065 2066 // Safety: We upgraded the lock, so we have mutable access to the data. 2067 // When this function returns, whether by drop or panic, 2068 // the drop guard will downgrade it back to an upgradeable lock. 2069 f(unsafe { &mut *self.rwlock.data.get() }) 2070 } 2071 2072 /// First, tries to atomically upgrade an upgradable read lock into an exclusive write lock. 2073 /// 2074 /// If the access could not be granted at this time, then `None` is returned. 2075 /// 2076 /// Otherwise, calls the provided closure with an exclusive reference to the lock's data, 2077 /// and finally downgrades the lock back to an upgradable read lock. 2078 /// The closure's return value is wrapped in `Some` and returned. 2079 /// 2080 /// This function only requires a mutable reference to the guard, unlike 2081 /// `try_upgrade` which takes the guard by value. try_with_upgraded<Ret, F: FnOnce(&mut T) -> Ret>(&mut self, f: F) -> Option<Ret>2082 pub fn try_with_upgraded<Ret, F: FnOnce(&mut T) -> Ret>(&mut self, f: F) -> Option<Ret> { 2083 if unsafe { self.rwlock.raw.try_upgrade() } { 2084 // Safety: We just upgraded the lock, so we have mutable access to the data. 2085 // This will restore the state the lock was in at the start of the function. 2086 defer!(unsafe { self.rwlock.raw.downgrade_to_upgradable() }); 2087 2088 // Safety: We upgraded the lock, so we have mutable access to the data. 2089 // When this function returns, whether by drop or panic, 2090 // the drop guard will downgrade it back to an upgradeable lock. 2091 Some(f(unsafe { &mut *self.rwlock.data.get() })) 2092 } else { 2093 None 2094 } 2095 } 2096 } 2097 2098 impl<'a, R: RawRwLockUpgradeTimed + 'a, T: ?Sized + 'a> RwLockUpgradableReadGuard<'a, R, T> { 2099 /// Tries to atomically upgrade an upgradable read lock into an exclusive 2100 /// write lock, until a timeout is reached. 2101 /// 2102 /// If the access could not be granted before the timeout expires, then 2103 /// the current guard is returned. try_upgrade_for( s: Self, timeout: R::Duration, ) -> Result<RwLockWriteGuard<'a, R, T>, Self>2104 pub fn try_upgrade_for( 2105 s: Self, 2106 timeout: R::Duration, 2107 ) -> Result<RwLockWriteGuard<'a, R, T>, Self> { 2108 // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. 2109 if unsafe { s.rwlock.raw.try_upgrade_for(timeout) } { 2110 let rwlock = s.rwlock; 2111 mem::forget(s); 2112 Ok(RwLockWriteGuard { 2113 rwlock, 2114 marker: PhantomData, 2115 }) 2116 } else { 2117 Err(s) 2118 } 2119 } 2120 2121 /// Tries to atomically upgrade an upgradable read lock into an exclusive 2122 /// write lock, until a timeout is reached. 2123 /// 2124 /// If the access could not be granted before the timeout expires, then 2125 /// the current guard is returned. 2126 #[inline] try_upgrade_until( s: Self, timeout: R::Instant, ) -> Result<RwLockWriteGuard<'a, R, T>, Self>2127 pub fn try_upgrade_until( 2128 s: Self, 2129 timeout: R::Instant, 2130 ) -> Result<RwLockWriteGuard<'a, R, T>, Self> { 2131 // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. 2132 if unsafe { s.rwlock.raw.try_upgrade_until(timeout) } { 2133 let rwlock = s.rwlock; 2134 mem::forget(s); 2135 Ok(RwLockWriteGuard { 2136 rwlock, 2137 marker: PhantomData, 2138 }) 2139 } else { 2140 Err(s) 2141 } 2142 } 2143 } 2144 2145 impl<'a, R: RawRwLockUpgradeTimed + RawRwLockUpgradeDowngrade + 'a, T: ?Sized + 'a> 2146 RwLockUpgradableReadGuard<'a, R, T> 2147 { 2148 /// Tries to atomically upgrade an upgradable read lock into an exclusive 2149 /// write lock, until a timeout is reached. 2150 /// 2151 /// If the access could not be granted before the timeout expires, then 2152 /// `None` is returned. 2153 /// 2154 /// Otherwise, calls the provided closure with an exclusive reference to the lock's data, 2155 /// and finally downgrades the lock back to an upgradable read lock. 2156 /// The closure's return value is wrapped in `Some` and returned. 2157 /// 2158 /// This function only requires a mutable reference to the guard, unlike 2159 /// `try_upgrade_for` which takes the guard by value. try_with_upgraded_for<Ret, F: FnOnce(&mut T) -> Ret>( &mut self, timeout: R::Duration, f: F, ) -> Option<Ret>2160 pub fn try_with_upgraded_for<Ret, F: FnOnce(&mut T) -> Ret>( 2161 &mut self, 2162 timeout: R::Duration, 2163 f: F, 2164 ) -> Option<Ret> { 2165 if unsafe { self.rwlock.raw.try_upgrade_for(timeout) } { 2166 // Safety: We just upgraded the lock, so we have mutable access to the data. 2167 // This will restore the state the lock was in at the start of the function. 2168 defer!(unsafe { self.rwlock.raw.downgrade_upgradable() }); 2169 2170 // Safety: We upgraded the lock, so we have mutable access to the data. 2171 // When this function returns, whether by drop or panic, 2172 // the drop guard will downgrade it back to an upgradeable lock. 2173 Some(f(unsafe { &mut *self.rwlock.data.get() })) 2174 } else { 2175 None 2176 } 2177 } 2178 2179 /// Tries to atomically upgrade an upgradable read lock into an exclusive 2180 /// write lock, until a timeout is reached. 2181 /// 2182 /// If the access could not be granted before the timeout expires, then 2183 /// `None` is returned. 2184 /// 2185 /// Otherwise, calls the provided closure with an exclusive reference to the lock's data, 2186 /// and finally downgrades the lock back to an upgradable read lock. 2187 /// The closure's return value is wrapped in `Some` and returned. 2188 /// 2189 /// This function only requires a mutable reference to the guard, unlike 2190 /// `try_upgrade_until` which takes the guard by value. try_with_upgraded_until<Ret, F: FnOnce(&mut T) -> Ret>( &mut self, timeout: R::Instant, f: F, ) -> Option<Ret>2191 pub fn try_with_upgraded_until<Ret, F: FnOnce(&mut T) -> Ret>( 2192 &mut self, 2193 timeout: R::Instant, 2194 f: F, 2195 ) -> Option<Ret> { 2196 if unsafe { self.rwlock.raw.try_upgrade_until(timeout) } { 2197 // Safety: We just upgraded the lock, so we have mutable access to the data. 2198 // This will restore the state the lock was in at the start of the function. 2199 defer!(unsafe { self.rwlock.raw.downgrade_upgradable() }); 2200 2201 // Safety: We upgraded the lock, so we have mutable access to the data. 2202 // When this function returns, whether by drop or panic, 2203 // the drop guard will downgrade it back to an upgradeable lock. 2204 Some(f(unsafe { &mut *self.rwlock.data.get() })) 2205 } else { 2206 None 2207 } 2208 } 2209 } 2210 2211 impl<'a, R: RawRwLockUpgrade + 'a, T: ?Sized + 'a> Deref for RwLockUpgradableReadGuard<'a, R, T> { 2212 type Target = T; 2213 #[inline] deref(&self) -> &T2214 fn deref(&self) -> &T { 2215 unsafe { &*self.rwlock.data.get() } 2216 } 2217 } 2218 2219 impl<'a, R: RawRwLockUpgrade + 'a, T: ?Sized + 'a> Drop for RwLockUpgradableReadGuard<'a, R, T> { 2220 #[inline] drop(&mut self)2221 fn drop(&mut self) { 2222 // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. 2223 unsafe { 2224 self.rwlock.raw.unlock_upgradable(); 2225 } 2226 } 2227 } 2228 2229 impl<'a, R: RawRwLockUpgrade + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug 2230 for RwLockUpgradableReadGuard<'a, R, T> 2231 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result2232 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 2233 fmt::Debug::fmt(&**self, f) 2234 } 2235 } 2236 2237 impl<'a, R: RawRwLockUpgrade + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display 2238 for RwLockUpgradableReadGuard<'a, R, T> 2239 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result2240 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 2241 (**self).fmt(f) 2242 } 2243 } 2244 2245 #[cfg(feature = "owning_ref")] 2246 unsafe impl<'a, R: RawRwLockUpgrade + 'a, T: ?Sized + 'a> StableAddress 2247 for RwLockUpgradableReadGuard<'a, R, T> 2248 { 2249 } 2250 2251 /// An RAII rwlock guard returned by the `Arc` locking operations on `RwLock`. 2252 /// This is similar to the `RwLockUpgradableReadGuard` struct, except instead of using a reference to unlock the 2253 /// `RwLock` it uses an `Arc<RwLock>`. This has several advantages, most notably that it has an `'static` 2254 /// lifetime. 2255 #[cfg(feature = "arc_lock")] 2256 #[clippy::has_significant_drop] 2257 #[must_use = "if unused the RwLock will immediately unlock"] 2258 pub struct ArcRwLockUpgradableReadGuard<R: RawRwLockUpgrade, T: ?Sized> { 2259 rwlock: Arc<RwLock<R, T>>, 2260 marker: PhantomData<R::GuardMarker>, 2261 } 2262 2263 #[cfg(feature = "arc_lock")] 2264 impl<R: RawRwLockUpgrade, T: ?Sized> ArcRwLockUpgradableReadGuard<R, T> { 2265 /// Returns a reference to the rwlock, contained in its original `Arc`. rwlock(s: &Self) -> &Arc<RwLock<R, T>>2266 pub fn rwlock(s: &Self) -> &Arc<RwLock<R, T>> { 2267 &s.rwlock 2268 } 2269 2270 /// Temporarily unlocks the `RwLock` to execute the given function. 2271 /// 2272 /// This is functionally identical to the `unlocked` method on [`RwLockUpgradableReadGuard`]. 2273 #[inline] unlocked<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,2274 pub fn unlocked<F, U>(s: &mut Self, f: F) -> U 2275 where 2276 F: FnOnce() -> U, 2277 { 2278 // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. 2279 unsafe { 2280 s.rwlock.raw.unlock_upgradable(); 2281 } 2282 defer!(s.rwlock.raw.lock_upgradable()); 2283 f() 2284 } 2285 2286 /// Atomically upgrades an upgradable read lock lock into an exclusive write lock, 2287 /// blocking the current thread until it can be acquired. upgrade(s: Self) -> ArcRwLockWriteGuard<R, T>2288 pub fn upgrade(s: Self) -> ArcRwLockWriteGuard<R, T> { 2289 // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. 2290 unsafe { 2291 s.rwlock.raw.upgrade(); 2292 } 2293 2294 // SAFETY: avoid incrementing or decrementing the refcount using ManuallyDrop and reading the Arc out 2295 // of the struct 2296 let s = ManuallyDrop::new(s); 2297 let rwlock = unsafe { ptr::read(&s.rwlock) }; 2298 2299 ArcRwLockWriteGuard { 2300 rwlock, 2301 marker: PhantomData, 2302 } 2303 } 2304 2305 /// Tries to atomically upgrade an upgradable read lock into an exclusive write lock. 2306 /// 2307 /// If the access could not be granted at this time, then the current guard is returned. try_upgrade(s: Self) -> Result<ArcRwLockWriteGuard<R, T>, Self>2308 pub fn try_upgrade(s: Self) -> Result<ArcRwLockWriteGuard<R, T>, Self> { 2309 // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. 2310 if unsafe { s.rwlock.raw.try_upgrade() } { 2311 // SAFETY: same as above 2312 let s = ManuallyDrop::new(s); 2313 let rwlock = unsafe { ptr::read(&s.rwlock) }; 2314 2315 Ok(ArcRwLockWriteGuard { 2316 rwlock, 2317 marker: PhantomData, 2318 }) 2319 } else { 2320 Err(s) 2321 } 2322 } 2323 } 2324 2325 #[cfg(feature = "arc_lock")] 2326 impl<R: RawRwLockUpgradeFair, T: ?Sized> ArcRwLockUpgradableReadGuard<R, T> { 2327 /// Unlocks the `RwLock` using a fair unlock protocol. 2328 /// 2329 /// This is functionally identical to the `unlock_fair` method on [`RwLockUpgradableReadGuard`]. 2330 #[inline] unlock_fair(s: Self)2331 pub fn unlock_fair(s: Self) { 2332 // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. 2333 unsafe { 2334 s.rwlock.raw.unlock_upgradable_fair(); 2335 } 2336 2337 // SAFETY: make sure we decrement the refcount properly 2338 let mut s = ManuallyDrop::new(s); 2339 unsafe { ptr::drop_in_place(&mut s.rwlock) }; 2340 } 2341 2342 /// Temporarily unlocks the `RwLock` to execute the given function. 2343 /// 2344 /// This is functionally equivalent to the `unlocked_fair` method on [`RwLockUpgradableReadGuard`]. 2345 #[inline] unlocked_fair<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,2346 pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U 2347 where 2348 F: FnOnce() -> U, 2349 { 2350 // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. 2351 unsafe { 2352 s.rwlock.raw.unlock_upgradable_fair(); 2353 } 2354 defer!(s.rwlock.raw.lock_upgradable()); 2355 f() 2356 } 2357 2358 /// Temporarily yields the `RwLock` to a waiting thread if there is one. 2359 /// 2360 /// This method is functionally equivalent to calling `bump` on [`RwLockUpgradableReadGuard`]. 2361 #[inline] bump(s: &mut Self)2362 pub fn bump(s: &mut Self) { 2363 // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. 2364 unsafe { 2365 s.rwlock.raw.bump_upgradable(); 2366 } 2367 } 2368 } 2369 2370 #[cfg(feature = "arc_lock")] 2371 impl<R: RawRwLockUpgradeDowngrade, T: ?Sized> ArcRwLockUpgradableReadGuard<R, T> { 2372 /// Atomically downgrades an upgradable read lock lock into a shared read lock 2373 /// without allowing any writers to take exclusive access of the lock in the 2374 /// meantime. 2375 /// 2376 /// Note that if there are any writers currently waiting to take the lock 2377 /// then other readers may not be able to acquire the lock even if it was 2378 /// downgraded. downgrade(s: Self) -> ArcRwLockReadGuard<R, T>2379 pub fn downgrade(s: Self) -> ArcRwLockReadGuard<R, T> { 2380 // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. 2381 unsafe { 2382 s.rwlock.raw.downgrade_upgradable(); 2383 } 2384 2385 // SAFETY: use ManuallyDrop and ptr::read to ensure the refcount is not changed 2386 let s = ManuallyDrop::new(s); 2387 let rwlock = unsafe { ptr::read(&s.rwlock) }; 2388 2389 ArcRwLockReadGuard { 2390 rwlock, 2391 marker: PhantomData, 2392 } 2393 } 2394 2395 /// First, atomically upgrades an upgradable read lock lock into an exclusive write lock, 2396 /// blocking the current thread until it can be acquired. 2397 /// 2398 /// Then, calls the provided closure with an exclusive reference to the lock's data. 2399 /// 2400 /// Finally, atomically downgrades the lock back to an upgradable read lock. 2401 /// The closure's return value is returned. 2402 /// 2403 /// This function only requires a mutable reference to the guard, unlike 2404 /// `upgrade` which takes the guard by value. with_upgraded<Ret, F: FnOnce(&mut T) -> Ret>(&mut self, f: F) -> Ret2405 pub fn with_upgraded<Ret, F: FnOnce(&mut T) -> Ret>(&mut self, f: F) -> Ret { 2406 unsafe { 2407 self.rwlock.raw.upgrade(); 2408 } 2409 2410 // Safety: We just upgraded the lock, so we have mutable access to the data. 2411 // This will restore the state the lock was in at the start of the function. 2412 defer!(unsafe { self.rwlock.raw.downgrade_upgradable() }); 2413 2414 // Safety: We upgraded the lock, so we have mutable access to the data. 2415 // When this function returns, whether by drop or panic, 2416 // the drop guard will downgrade it back to an upgradeable lock. 2417 f(unsafe { &mut *self.rwlock.data.get() }) 2418 } 2419 2420 /// First, tries to atomically upgrade an upgradable read lock into an exclusive write lock. 2421 /// 2422 /// If the access could not be granted at this time, then `None` is returned. 2423 /// 2424 /// Otherwise, calls the provided closure with an exclusive reference to the lock's data, 2425 /// and finally downgrades the lock back to an upgradable read lock. 2426 /// The closure's return value is wrapped in `Some` and returned. 2427 /// 2428 /// This function only requires a mutable reference to the guard, unlike 2429 /// `try_upgrade` which takes the guard by value. try_with_upgraded<Ret, F: FnOnce(&mut T) -> Ret>(&mut self, f: F) -> Option<Ret>2430 pub fn try_with_upgraded<Ret, F: FnOnce(&mut T) -> Ret>(&mut self, f: F) -> Option<Ret> { 2431 if unsafe { self.rwlock.raw.try_upgrade() } { 2432 // Safety: We just upgraded the lock, so we have mutable access to the data. 2433 // This will restore the state the lock was in at the start of the function. 2434 defer!(unsafe { self.rwlock.raw.downgrade_upgradable() }); 2435 2436 // Safety: We upgraded the lock, so we have mutable access to the data. 2437 // When this function returns, whether by drop or panic, 2438 // the drop guard will downgrade it back to an upgradeable lock. 2439 Some(f(unsafe { &mut *self.rwlock.data.get() })) 2440 } else { 2441 None 2442 } 2443 } 2444 } 2445 2446 #[cfg(feature = "arc_lock")] 2447 impl<R: RawRwLockUpgradeTimed, T: ?Sized> ArcRwLockUpgradableReadGuard<R, T> { 2448 /// Tries to atomically upgrade an upgradable read lock into an exclusive 2449 /// write lock, until a timeout is reached. 2450 /// 2451 /// If the access could not be granted before the timeout expires, then 2452 /// the current guard is returned. try_upgrade_for( s: Self, timeout: R::Duration, ) -> Result<ArcRwLockWriteGuard<R, T>, Self>2453 pub fn try_upgrade_for( 2454 s: Self, 2455 timeout: R::Duration, 2456 ) -> Result<ArcRwLockWriteGuard<R, T>, Self> { 2457 // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. 2458 if unsafe { s.rwlock.raw.try_upgrade_for(timeout) } { 2459 // SAFETY: same as above 2460 let s = ManuallyDrop::new(s); 2461 let rwlock = unsafe { ptr::read(&s.rwlock) }; 2462 2463 Ok(ArcRwLockWriteGuard { 2464 rwlock, 2465 marker: PhantomData, 2466 }) 2467 } else { 2468 Err(s) 2469 } 2470 } 2471 2472 /// Tries to atomically upgrade an upgradable read lock into an exclusive 2473 /// write lock, until a timeout is reached. 2474 /// 2475 /// If the access could not be granted before the timeout expires, then 2476 /// the current guard is returned. 2477 #[inline] try_upgrade_until( s: Self, timeout: R::Instant, ) -> Result<ArcRwLockWriteGuard<R, T>, Self>2478 pub fn try_upgrade_until( 2479 s: Self, 2480 timeout: R::Instant, 2481 ) -> Result<ArcRwLockWriteGuard<R, T>, Self> { 2482 // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. 2483 if unsafe { s.rwlock.raw.try_upgrade_until(timeout) } { 2484 // SAFETY: same as above 2485 let s = ManuallyDrop::new(s); 2486 let rwlock = unsafe { ptr::read(&s.rwlock) }; 2487 2488 Ok(ArcRwLockWriteGuard { 2489 rwlock, 2490 marker: PhantomData, 2491 }) 2492 } else { 2493 Err(s) 2494 } 2495 } 2496 } 2497 2498 #[cfg(feature = "arc_lock")] 2499 impl<R: RawRwLockUpgradeTimed + RawRwLockUpgradeDowngrade, T: ?Sized> 2500 ArcRwLockUpgradableReadGuard<R, T> 2501 { 2502 /// Tries to atomically upgrade an upgradable read lock into an exclusive 2503 /// write lock, until a timeout is reached. 2504 /// 2505 /// If the access could not be granted before the timeout expires, then 2506 /// `None` is returned. 2507 /// 2508 /// Otherwise, calls the provided closure with an exclusive reference to the lock's data, 2509 /// and finally downgrades the lock back to an upgradable read lock. 2510 /// The closure's return value is wrapped in `Some` and returned. 2511 /// 2512 /// This function only requires a mutable reference to the guard, unlike 2513 /// `try_upgrade_for` which takes the guard by value. try_with_upgraded_for<Ret, F: FnOnce(&mut T) -> Ret>( &mut self, timeout: R::Duration, f: F, ) -> Option<Ret>2514 pub fn try_with_upgraded_for<Ret, F: FnOnce(&mut T) -> Ret>( 2515 &mut self, 2516 timeout: R::Duration, 2517 f: F, 2518 ) -> Option<Ret> { 2519 if unsafe { self.rwlock.raw.try_upgrade_for(timeout) } { 2520 // Safety: We just upgraded the lock, so we have mutable access to the data. 2521 // This will restore the state the lock was in at the start of the function. 2522 defer!(unsafe { self.rwlock.raw.downgrade_upgradable() }); 2523 2524 // Safety: We upgraded the lock, so we have mutable access to the data. 2525 // When this function returns, whether by drop or panic, 2526 // the drop guard will downgrade it back to an upgradeable lock. 2527 Some(f(unsafe { &mut *self.rwlock.data.get() })) 2528 } else { 2529 None 2530 } 2531 } 2532 2533 /// Tries to atomically upgrade an upgradable read lock into an exclusive 2534 /// write lock, until a timeout is reached. 2535 /// 2536 /// If the access could not be granted before the timeout expires, then 2537 /// `None` is returned. 2538 /// 2539 /// Otherwise, calls the provided closure with an exclusive reference to the lock's data, 2540 /// and finally downgrades the lock back to an upgradable read lock. 2541 /// The closure's return value is wrapped in `Some` and returned. 2542 /// 2543 /// This function only requires a mutable reference to the guard, unlike 2544 /// `try_upgrade_until` which takes the guard by value. try_with_upgraded_until<Ret, F: FnOnce(&mut T) -> Ret>( &mut self, timeout: R::Instant, f: F, ) -> Option<Ret>2545 pub fn try_with_upgraded_until<Ret, F: FnOnce(&mut T) -> Ret>( 2546 &mut self, 2547 timeout: R::Instant, 2548 f: F, 2549 ) -> Option<Ret> { 2550 if unsafe { self.rwlock.raw.try_upgrade_until(timeout) } { 2551 // Safety: We just upgraded the lock, so we have mutable access to the data. 2552 // This will restore the state the lock was in at the start of the function. 2553 defer!(unsafe { self.rwlock.raw.downgrade_upgradable() }); 2554 2555 // Safety: We upgraded the lock, so we have mutable access to the data. 2556 // When this function returns, whether by drop or panic, 2557 // the drop guard will downgrade it back to an upgradeable lock. 2558 Some(f(unsafe { &mut *self.rwlock.data.get() })) 2559 } else { 2560 None 2561 } 2562 } 2563 } 2564 2565 #[cfg(feature = "arc_lock")] 2566 impl<R: RawRwLockUpgrade, T: ?Sized> Deref for ArcRwLockUpgradableReadGuard<R, T> { 2567 type Target = T; 2568 #[inline] deref(&self) -> &T2569 fn deref(&self) -> &T { 2570 unsafe { &*self.rwlock.data.get() } 2571 } 2572 } 2573 2574 #[cfg(feature = "arc_lock")] 2575 impl<R: RawRwLockUpgrade, T: ?Sized> Drop for ArcRwLockUpgradableReadGuard<R, T> { 2576 #[inline] drop(&mut self)2577 fn drop(&mut self) { 2578 // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. 2579 unsafe { 2580 self.rwlock.raw.unlock_upgradable(); 2581 } 2582 } 2583 } 2584 2585 #[cfg(feature = "arc_lock")] 2586 impl<R: RawRwLockUpgrade, T: fmt::Debug + ?Sized> fmt::Debug 2587 for ArcRwLockUpgradableReadGuard<R, T> 2588 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result2589 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 2590 fmt::Debug::fmt(&**self, f) 2591 } 2592 } 2593 2594 #[cfg(feature = "arc_lock")] 2595 impl<R: RawRwLockUpgrade, T: fmt::Display + ?Sized> fmt::Display 2596 for ArcRwLockUpgradableReadGuard<R, T> 2597 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result2598 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 2599 (**self).fmt(f) 2600 } 2601 } 2602 2603 /// An RAII read lock guard returned by `RwLockReadGuard::map`, which can point to a 2604 /// subfield of the protected data. 2605 /// 2606 /// The main difference between `MappedRwLockReadGuard` and `RwLockReadGuard` is that the 2607 /// former doesn't support temporarily unlocking and re-locking, since that 2608 /// could introduce soundness issues if the locked object is modified by another 2609 /// thread. 2610 #[clippy::has_significant_drop] 2611 #[must_use = "if unused the RwLock will immediately unlock"] 2612 pub struct MappedRwLockReadGuard<'a, R: RawRwLock, T: ?Sized> { 2613 raw: &'a R, 2614 data: *const T, 2615 marker: PhantomData<&'a T>, 2616 } 2617 2618 unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + Sync + 'a> Sync for MappedRwLockReadGuard<'a, R, T> {} 2619 unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + Sync + 'a> Send for MappedRwLockReadGuard<'a, R, T> where 2620 R::GuardMarker: Send 2621 { 2622 } 2623 2624 impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> MappedRwLockReadGuard<'a, R, T> { 2625 /// Make a new `MappedRwLockReadGuard` for a component of the locked data. 2626 /// 2627 /// This operation cannot fail as the `MappedRwLockReadGuard` passed 2628 /// in already locked the data. 2629 /// 2630 /// This is an associated function that needs to be 2631 /// used as `MappedRwLockReadGuard::map(...)`. A method would interfere with methods of 2632 /// the same name on the contents of the locked data. 2633 #[inline] map<U: ?Sized, F>(s: Self, f: F) -> MappedRwLockReadGuard<'a, R, U> where F: FnOnce(&T) -> &U,2634 pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedRwLockReadGuard<'a, R, U> 2635 where 2636 F: FnOnce(&T) -> &U, 2637 { 2638 let raw = s.raw; 2639 let data = f(unsafe { &*s.data }); 2640 mem::forget(s); 2641 MappedRwLockReadGuard { 2642 raw, 2643 data, 2644 marker: PhantomData, 2645 } 2646 } 2647 2648 /// Attempts to make a new `MappedRwLockReadGuard` for a component of the 2649 /// locked data. The original guard is return if the closure returns `None`. 2650 /// 2651 /// This operation cannot fail as the `MappedRwLockReadGuard` passed 2652 /// in already locked the data. 2653 /// 2654 /// This is an associated function that needs to be 2655 /// used as `MappedRwLockReadGuard::try_map(...)`. A method would interfere with methods of 2656 /// the same name on the contents of the locked data. 2657 #[inline] try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedRwLockReadGuard<'a, R, U>, Self> where F: FnOnce(&T) -> Option<&U>,2658 pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedRwLockReadGuard<'a, R, U>, Self> 2659 where 2660 F: FnOnce(&T) -> Option<&U>, 2661 { 2662 let raw = s.raw; 2663 let data = match f(unsafe { &*s.data }) { 2664 Some(data) => data, 2665 None => return Err(s), 2666 }; 2667 mem::forget(s); 2668 Ok(MappedRwLockReadGuard { 2669 raw, 2670 data, 2671 marker: PhantomData, 2672 }) 2673 } 2674 } 2675 2676 impl<'a, R: RawRwLockFair + 'a, T: ?Sized + 'a> MappedRwLockReadGuard<'a, R, T> { 2677 /// Unlocks the `RwLock` using a fair unlock protocol. 2678 /// 2679 /// By default, `RwLock` is unfair and allow the current thread to re-lock 2680 /// the `RwLock` before another has the chance to acquire the lock, even if 2681 /// that thread has been blocked on the `RwLock` for a long time. This is 2682 /// the default because it allows much higher throughput as it avoids 2683 /// forcing a context switch on every `RwLock` unlock. This can result in one 2684 /// thread acquiring a `RwLock` many more times than other threads. 2685 /// 2686 /// However in some cases it can be beneficial to ensure fairness by forcing 2687 /// the lock to pass on to a waiting thread if there is one. This is done by 2688 /// using this method instead of dropping the `MappedRwLockReadGuard` normally. 2689 #[inline] unlock_fair(s: Self)2690 pub fn unlock_fair(s: Self) { 2691 // Safety: A MappedRwLockReadGuard always holds a shared lock. 2692 unsafe { 2693 s.raw.unlock_shared_fair(); 2694 } 2695 mem::forget(s); 2696 } 2697 } 2698 2699 impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Deref for MappedRwLockReadGuard<'a, R, T> { 2700 type Target = T; 2701 #[inline] deref(&self) -> &T2702 fn deref(&self) -> &T { 2703 unsafe { &*self.data } 2704 } 2705 } 2706 2707 impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Drop for MappedRwLockReadGuard<'a, R, T> { 2708 #[inline] drop(&mut self)2709 fn drop(&mut self) { 2710 // Safety: A MappedRwLockReadGuard always holds a shared lock. 2711 unsafe { 2712 self.raw.unlock_shared(); 2713 } 2714 } 2715 } 2716 2717 impl<'a, R: RawRwLock + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug 2718 for MappedRwLockReadGuard<'a, R, T> 2719 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result2720 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 2721 fmt::Debug::fmt(&**self, f) 2722 } 2723 } 2724 2725 impl<'a, R: RawRwLock + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display 2726 for MappedRwLockReadGuard<'a, R, T> 2727 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result2728 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 2729 (**self).fmt(f) 2730 } 2731 } 2732 2733 #[cfg(feature = "owning_ref")] 2734 unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> StableAddress 2735 for MappedRwLockReadGuard<'a, R, T> 2736 { 2737 } 2738 2739 /// An RAII write lock guard returned by `RwLockWriteGuard::map`, which can point to a 2740 /// subfield of the protected data. 2741 /// 2742 /// The main difference between `MappedRwLockWriteGuard` and `RwLockWriteGuard` is that the 2743 /// former doesn't support temporarily unlocking and re-locking, since that 2744 /// could introduce soundness issues if the locked object is modified by another 2745 /// thread. 2746 #[clippy::has_significant_drop] 2747 #[must_use = "if unused the RwLock will immediately unlock"] 2748 pub struct MappedRwLockWriteGuard<'a, R: RawRwLock, T: ?Sized> { 2749 raw: &'a R, 2750 data: *mut T, 2751 marker: PhantomData<&'a mut T>, 2752 } 2753 2754 unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + Sync + 'a> Sync 2755 for MappedRwLockWriteGuard<'a, R, T> 2756 { 2757 } 2758 unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + Send + 'a> Send for MappedRwLockWriteGuard<'a, R, T> where 2759 R::GuardMarker: Send 2760 { 2761 } 2762 2763 impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> MappedRwLockWriteGuard<'a, R, T> { 2764 /// Make a new `MappedRwLockWriteGuard` for a component of the locked data. 2765 /// 2766 /// This operation cannot fail as the `MappedRwLockWriteGuard` passed 2767 /// in already locked the data. 2768 /// 2769 /// This is an associated function that needs to be 2770 /// used as `MappedRwLockWriteGuard::map(...)`. A method would interfere with methods of 2771 /// the same name on the contents of the locked data. 2772 #[inline] map<U: ?Sized, F>(s: Self, f: F) -> MappedRwLockWriteGuard<'a, R, U> where F: FnOnce(&mut T) -> &mut U,2773 pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedRwLockWriteGuard<'a, R, U> 2774 where 2775 F: FnOnce(&mut T) -> &mut U, 2776 { 2777 let raw = s.raw; 2778 let data = f(unsafe { &mut *s.data }); 2779 mem::forget(s); 2780 MappedRwLockWriteGuard { 2781 raw, 2782 data, 2783 marker: PhantomData, 2784 } 2785 } 2786 2787 /// Attempts to make a new `MappedRwLockWriteGuard` for a component of the 2788 /// locked data. The original guard is return if the closure returns `None`. 2789 /// 2790 /// This operation cannot fail as the `MappedRwLockWriteGuard` passed 2791 /// in already locked the data. 2792 /// 2793 /// This is an associated function that needs to be 2794 /// used as `MappedRwLockWriteGuard::try_map(...)`. A method would interfere with methods of 2795 /// the same name on the contents of the locked data. 2796 #[inline] try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, R, U>, Self> where F: FnOnce(&mut T) -> Option<&mut U>,2797 pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, R, U>, Self> 2798 where 2799 F: FnOnce(&mut T) -> Option<&mut U>, 2800 { 2801 let raw = s.raw; 2802 let data = match f(unsafe { &mut *s.data }) { 2803 Some(data) => data, 2804 None => return Err(s), 2805 }; 2806 mem::forget(s); 2807 Ok(MappedRwLockWriteGuard { 2808 raw, 2809 data, 2810 marker: PhantomData, 2811 }) 2812 } 2813 } 2814 2815 impl<'a, R: RawRwLockFair + 'a, T: ?Sized + 'a> MappedRwLockWriteGuard<'a, R, T> { 2816 /// Unlocks the `RwLock` using a fair unlock protocol. 2817 /// 2818 /// By default, `RwLock` is unfair and allow the current thread to re-lock 2819 /// the `RwLock` before another has the chance to acquire the lock, even if 2820 /// that thread has been blocked on the `RwLock` for a long time. This is 2821 /// the default because it allows much higher throughput as it avoids 2822 /// forcing a context switch on every `RwLock` unlock. This can result in one 2823 /// thread acquiring a `RwLock` many more times than other threads. 2824 /// 2825 /// However in some cases it can be beneficial to ensure fairness by forcing 2826 /// the lock to pass on to a waiting thread if there is one. This is done by 2827 /// using this method instead of dropping the `MappedRwLockWriteGuard` normally. 2828 #[inline] unlock_fair(s: Self)2829 pub fn unlock_fair(s: Self) { 2830 // Safety: A MappedRwLockWriteGuard always holds an exclusive lock. 2831 unsafe { 2832 s.raw.unlock_exclusive_fair(); 2833 } 2834 mem::forget(s); 2835 } 2836 } 2837 2838 impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Deref for MappedRwLockWriteGuard<'a, R, T> { 2839 type Target = T; 2840 #[inline] deref(&self) -> &T2841 fn deref(&self) -> &T { 2842 unsafe { &*self.data } 2843 } 2844 } 2845 2846 impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> DerefMut for MappedRwLockWriteGuard<'a, R, T> { 2847 #[inline] deref_mut(&mut self) -> &mut T2848 fn deref_mut(&mut self) -> &mut T { 2849 unsafe { &mut *self.data } 2850 } 2851 } 2852 2853 impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Drop for MappedRwLockWriteGuard<'a, R, T> { 2854 #[inline] drop(&mut self)2855 fn drop(&mut self) { 2856 // Safety: A MappedRwLockWriteGuard always holds an exclusive lock. 2857 unsafe { 2858 self.raw.unlock_exclusive(); 2859 } 2860 } 2861 } 2862 2863 impl<'a, R: RawRwLock + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug 2864 for MappedRwLockWriteGuard<'a, R, T> 2865 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result2866 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 2867 fmt::Debug::fmt(&**self, f) 2868 } 2869 } 2870 2871 impl<'a, R: RawRwLock + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display 2872 for MappedRwLockWriteGuard<'a, R, T> 2873 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result2874 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 2875 (**self).fmt(f) 2876 } 2877 } 2878 2879 #[cfg(feature = "owning_ref")] 2880 unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> StableAddress 2881 for MappedRwLockWriteGuard<'a, R, T> 2882 { 2883 } 2884