1 use crate::sync::batch_semaphore::{Semaphore, TryAcquireError};
2 use crate::sync::mutex::TryLockError;
3 use std::cell::UnsafeCell;
4 use std::marker;
5 use std::marker::PhantomData;
6 use std::mem::ManuallyDrop;
7 use std::sync::Arc;
8 
9 pub(crate) mod owned_read_guard;
10 pub(crate) mod owned_write_guard;
11 pub(crate) mod owned_write_guard_mapped;
12 pub(crate) mod read_guard;
13 pub(crate) mod write_guard;
14 pub(crate) mod write_guard_mapped;
15 pub(crate) use owned_read_guard::OwnedRwLockReadGuard;
16 pub(crate) use owned_write_guard::OwnedRwLockWriteGuard;
17 pub(crate) use owned_write_guard_mapped::OwnedRwLockMappedWriteGuard;
18 pub(crate) use read_guard::RwLockReadGuard;
19 pub(crate) use write_guard::RwLockWriteGuard;
20 pub(crate) use write_guard_mapped::RwLockMappedWriteGuard;
21 
22 #[cfg(not(loom))]
23 const MAX_READS: u32 = std::u32::MAX >> 3;
24 
25 #[cfg(loom)]
26 const MAX_READS: u32 = 10;
27 
28 /// An asynchronous reader-writer lock.
29 ///
30 /// This type of lock allows a number of readers or at most one writer at any
31 /// point in time. The write portion of this lock typically allows modification
32 /// of the underlying data (exclusive access) and the read portion of this lock
33 /// typically allows for read-only access (shared access).
34 ///
35 /// In comparison, a [`Mutex`] does not distinguish between readers or writers
36 /// that acquire the lock, therefore causing any tasks waiting for the lock to
37 /// become available to yield. An `RwLock` will allow any number of readers to
38 /// acquire the lock as long as a writer is not holding the lock.
39 ///
40 /// The priority policy of Tokio's read-write lock is _fair_ (or
41 /// [_write-preferring_]), in order to ensure that readers cannot starve
42 /// writers. Fairness is ensured using a first-in, first-out queue for the tasks
43 /// awaiting the lock; if a task that wishes to acquire the write lock is at the
44 /// head of the queue, read locks will not be given out until the write lock has
45 /// been released. This is in contrast to the Rust standard library's
46 /// `std::sync::RwLock`, where the priority policy is dependent on the
47 /// operating system's implementation.
48 ///
49 /// The type parameter `T` represents the data that this lock protects. It is
50 /// required that `T` satisfies [`Send`] to be shared across threads. The RAII guards
51 /// returned from the locking methods implement [`Deref`](trait@std::ops::Deref)
52 /// (and [`DerefMut`](trait@std::ops::DerefMut)
53 /// for the `write` methods) to allow access to the content of the lock.
54 ///
55 /// # Examples
56 ///
57 /// ```
58 /// use tokio::sync::RwLock;
59 ///
60 /// #[tokio::main]
61 /// async fn main() {
62 ///     let lock = RwLock::new(5);
63 ///
64 ///     // many reader locks can be held at once
65 ///     {
66 ///         let r1 = lock.read().await;
67 ///         let r2 = lock.read().await;
68 ///         assert_eq!(*r1, 5);
69 ///         assert_eq!(*r2, 5);
70 ///     } // read locks are dropped at this point
71 ///
72 ///     // only one write lock may be held, however
73 ///     {
74 ///         let mut w = lock.write().await;
75 ///         *w += 1;
76 ///         assert_eq!(*w, 6);
77 ///     } // write lock is dropped here
78 /// }
79 /// ```
80 ///
81 /// [`Mutex`]: struct@super::Mutex
82 /// [`RwLock`]: struct@RwLock
83 /// [`RwLockReadGuard`]: struct@RwLockReadGuard
84 /// [`RwLockWriteGuard`]: struct@RwLockWriteGuard
85 /// [`Send`]: trait@std::marker::Send
86 /// [_write-preferring_]: https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock#Priority_policies
87 #[derive(Debug)]
88 pub struct RwLock<T: ?Sized> {
89     // maximum number of concurrent readers
90     mr: u32,
91 
92     //semaphore to coordinate read and write access to T
93     s: Semaphore,
94 
95     //inner data T
96     c: UnsafeCell<T>,
97 }
98 
99 #[test]
100 #[cfg(not(loom))]
bounds()101 fn bounds() {
102     fn check_send<T: Send>() {}
103     fn check_sync<T: Sync>() {}
104     fn check_unpin<T: Unpin>() {}
105     // This has to take a value, since the async fn's return type is unnameable.
106     fn check_send_sync_val<T: Send + Sync>(_t: T) {}
107 
108     check_send::<RwLock<u32>>();
109     check_sync::<RwLock<u32>>();
110     check_unpin::<RwLock<u32>>();
111 
112     check_send::<RwLockReadGuard<'_, u32>>();
113     check_sync::<RwLockReadGuard<'_, u32>>();
114     check_unpin::<RwLockReadGuard<'_, u32>>();
115 
116     check_send::<OwnedRwLockReadGuard<u32, i32>>();
117     check_sync::<OwnedRwLockReadGuard<u32, i32>>();
118     check_unpin::<OwnedRwLockReadGuard<u32, i32>>();
119 
120     check_send::<RwLockWriteGuard<'_, u32>>();
121     check_sync::<RwLockWriteGuard<'_, u32>>();
122     check_unpin::<RwLockWriteGuard<'_, u32>>();
123 
124     check_send::<RwLockMappedWriteGuard<'_, u32>>();
125     check_sync::<RwLockMappedWriteGuard<'_, u32>>();
126     check_unpin::<RwLockMappedWriteGuard<'_, u32>>();
127 
128     check_send::<OwnedRwLockWriteGuard<u32>>();
129     check_sync::<OwnedRwLockWriteGuard<u32>>();
130     check_unpin::<OwnedRwLockWriteGuard<u32>>();
131 
132     check_send::<OwnedRwLockMappedWriteGuard<u32, i32>>();
133     check_sync::<OwnedRwLockMappedWriteGuard<u32, i32>>();
134     check_unpin::<OwnedRwLockMappedWriteGuard<u32, i32>>();
135 
136     let rwlock = Arc::new(RwLock::new(0));
137     check_send_sync_val(rwlock.read());
138     check_send_sync_val(Arc::clone(&rwlock).read_owned());
139     check_send_sync_val(rwlock.write());
140     check_send_sync_val(Arc::clone(&rwlock).write_owned());
141 }
142 
143 // As long as T: Send + Sync, it's fine to send and share RwLock<T> between threads.
144 // If T were not Send, sending and sharing a RwLock<T> would be bad, since you can access T through
145 // RwLock<T>.
146 unsafe impl<T> Send for RwLock<T> where T: ?Sized + Send {}
147 unsafe impl<T> Sync for RwLock<T> where T: ?Sized + Send + Sync {}
148 // NB: These impls need to be explicit since we're storing a raw pointer.
149 // Safety: Stores a raw pointer to `T`, so if `T` is `Sync`, the lock guard over
150 // `T` is `Send`.
151 unsafe impl<T> Send for RwLockReadGuard<'_, T> where T: ?Sized + Sync {}
152 unsafe impl<T> Sync for RwLockReadGuard<'_, T> where T: ?Sized + Send + Sync {}
153 // T is required to be `Send` because an OwnedRwLockReadGuard can be used to drop the value held in
154 // the RwLock, unlike RwLockReadGuard.
155 unsafe impl<T, U> Send for OwnedRwLockReadGuard<T, U>
156 where
157     T: ?Sized + Send + Sync,
158     U: ?Sized + Sync,
159 {
160 }
161 unsafe impl<T, U> Sync for OwnedRwLockReadGuard<T, U>
162 where
163     T: ?Sized + Send + Sync,
164     U: ?Sized + Send + Sync,
165 {
166 }
167 unsafe impl<T> Sync for RwLockWriteGuard<'_, T> where T: ?Sized + Send + Sync {}
168 unsafe impl<T> Sync for OwnedRwLockWriteGuard<T> where T: ?Sized + Send + Sync {}
169 unsafe impl<T> Sync for RwLockMappedWriteGuard<'_, T> where T: ?Sized + Send + Sync {}
170 unsafe impl<T, U> Sync for OwnedRwLockMappedWriteGuard<T, U>
171 where
172     T: ?Sized + Send + Sync,
173     U: ?Sized + Send + Sync,
174 {
175 }
176 // Safety: Stores a raw pointer to `T`, so if `T` is `Sync`, the lock guard over
177 // `T` is `Send` - but since this is also provides mutable access, we need to
178 // make sure that `T` is `Send` since its value can be sent across thread
179 // boundaries.
180 unsafe impl<T> Send for RwLockWriteGuard<'_, T> where T: ?Sized + Send + Sync {}
181 unsafe impl<T> Send for OwnedRwLockWriteGuard<T> where T: ?Sized + Send + Sync {}
182 unsafe impl<T> Send for RwLockMappedWriteGuard<'_, T> where T: ?Sized + Send + Sync {}
183 unsafe impl<T, U> Send for OwnedRwLockMappedWriteGuard<T, U>
184 where
185     T: ?Sized + Send + Sync,
186     U: ?Sized + Send + Sync,
187 {
188 }
189 
190 impl<T: ?Sized> RwLock<T> {
191     /// Creates a new instance of an `RwLock<T>` which is unlocked.
192     ///
193     /// # Examples
194     ///
195     /// ```
196     /// use tokio::sync::RwLock;
197     ///
198     /// let lock = RwLock::new(5);
199     /// ```
new(value: T) -> RwLock<T> where T: Sized,200     pub fn new(value: T) -> RwLock<T>
201     where
202         T: Sized,
203     {
204         RwLock {
205             mr: MAX_READS,
206             c: UnsafeCell::new(value),
207             s: Semaphore::new(MAX_READS as usize),
208         }
209     }
210 
211     /// Creates a new instance of an `RwLock<T>` which is unlocked
212     /// and allows a maximum of `max_reads` concurrent readers.
213     ///
214     /// # Examples
215     ///
216     /// ```
217     /// use tokio::sync::RwLock;
218     ///
219     /// let lock = RwLock::with_max_readers(5, 1024);
220     /// ```
221     ///
222     /// # Panics
223     ///
224     /// Panics if `max_reads` is more than `u32::MAX >> 3`.
with_max_readers(value: T, max_reads: u32) -> RwLock<T> where T: Sized,225     pub fn with_max_readers(value: T, max_reads: u32) -> RwLock<T>
226     where
227         T: Sized,
228     {
229         assert!(
230             max_reads <= MAX_READS,
231             "a RwLock may not be created with more than {} readers",
232             MAX_READS
233         );
234         RwLock {
235             mr: max_reads,
236             c: UnsafeCell::new(value),
237             s: Semaphore::new(max_reads as usize),
238         }
239     }
240 
241     /// Creates a new instance of an `RwLock<T>` which is unlocked.
242     ///
243     /// # Examples
244     ///
245     /// ```
246     /// use tokio::sync::RwLock;
247     ///
248     /// static LOCK: RwLock<i32> = RwLock::const_new(5);
249     /// ```
250     #[cfg(all(feature = "parking_lot", not(all(loom, test))))]
251     #[cfg_attr(docsrs, doc(cfg(feature = "parking_lot")))]
const_new(value: T) -> RwLock<T> where T: Sized,252     pub const fn const_new(value: T) -> RwLock<T>
253     where
254         T: Sized,
255     {
256         RwLock {
257             mr: MAX_READS,
258             c: UnsafeCell::new(value),
259             s: Semaphore::const_new(MAX_READS as usize),
260         }
261     }
262 
263     /// Creates a new instance of an `RwLock<T>` which is unlocked
264     /// and allows a maximum of `max_reads` concurrent readers.
265     ///
266     /// # Examples
267     ///
268     /// ```
269     /// use tokio::sync::RwLock;
270     ///
271     /// static LOCK: RwLock<i32> = RwLock::const_with_max_readers(5, 1024);
272     /// ```
273     #[cfg(all(feature = "parking_lot", not(all(loom, test))))]
274     #[cfg_attr(docsrs, doc(cfg(feature = "parking_lot")))]
const_with_max_readers(value: T, mut max_reads: u32) -> RwLock<T> where T: Sized,275     pub const fn const_with_max_readers(value: T, mut max_reads: u32) -> RwLock<T>
276     where
277         T: Sized,
278     {
279         max_reads &= MAX_READS;
280         RwLock {
281             mr: max_reads,
282             c: UnsafeCell::new(value),
283             s: Semaphore::const_new(max_reads as usize),
284         }
285     }
286 
287     /// Locks this `RwLock` with shared read access, causing the current task
288     /// to yield until the lock has been acquired.
289     ///
290     /// The calling task will yield until there are no writers which hold the
291     /// lock. There may be other readers inside the lock when the task resumes.
292     ///
293     /// Note that under the priority policy of [`RwLock`], read locks are not
294     /// granted until prior write locks, to prevent starvation. Therefore
295     /// deadlock may occur if a read lock is held by the current task, a write
296     /// lock attempt is made, and then a subsequent read lock attempt is made
297     /// by the current task.
298     ///
299     /// Returns an RAII guard which will drop this read access of the `RwLock`
300     /// when dropped.
301     ///
302     /// # Examples
303     ///
304     /// ```
305     /// use std::sync::Arc;
306     /// use tokio::sync::RwLock;
307     ///
308     /// #[tokio::main]
309     /// async fn main() {
310     ///     let lock = Arc::new(RwLock::new(1));
311     ///     let c_lock = lock.clone();
312     ///
313     ///     let n = lock.read().await;
314     ///     assert_eq!(*n, 1);
315     ///
316     ///     tokio::spawn(async move {
317     ///         // While main has an active read lock, we acquire one too.
318     ///         let r = c_lock.read().await;
319     ///         assert_eq!(*r, 1);
320     ///     }).await.expect("The spawned task has panicked");
321     ///
322     ///     // Drop the guard after the spawned task finishes.
323     ///     drop(n);
324     ///}
325     /// ```
read(&self) -> RwLockReadGuard<'_, T>326     pub async fn read(&self) -> RwLockReadGuard<'_, T> {
327         self.s.acquire(1).await.unwrap_or_else(|_| {
328             // The semaphore was closed. but, we never explicitly close it, and we have a
329             // handle to it through the Arc, which means that this can never happen.
330             unreachable!()
331         });
332         RwLockReadGuard {
333             s: &self.s,
334             data: self.c.get(),
335             marker: marker::PhantomData,
336         }
337     }
338 
339     /// Locks this `RwLock` with shared read access, causing the current task
340     /// to yield until the lock has been acquired.
341     ///
342     /// The calling task will yield until there are no writers which hold the
343     /// lock. There may be other readers inside the lock when the task resumes.
344     ///
345     /// This method is identical to [`RwLock::read`], except that the returned
346     /// guard references the `RwLock` with an [`Arc`] rather than by borrowing
347     /// it. Therefore, the `RwLock` must be wrapped in an `Arc` to call this
348     /// method, and the guard will live for the `'static` lifetime, as it keeps
349     /// the `RwLock` alive by holding an `Arc`.
350     ///
351     /// Note that under the priority policy of [`RwLock`], read locks are not
352     /// granted until prior write locks, to prevent starvation. Therefore
353     /// deadlock may occur if a read lock is held by the current task, a write
354     /// lock attempt is made, and then a subsequent read lock attempt is made
355     /// by the current task.
356     ///
357     /// Returns an RAII guard which will drop this read access of the `RwLock`
358     /// when dropped.
359     ///
360     /// # Examples
361     ///
362     /// ```
363     /// use std::sync::Arc;
364     /// use tokio::sync::RwLock;
365     ///
366     /// #[tokio::main]
367     /// async fn main() {
368     ///     let lock = Arc::new(RwLock::new(1));
369     ///     let c_lock = lock.clone();
370     ///
371     ///     let n = lock.read_owned().await;
372     ///     assert_eq!(*n, 1);
373     ///
374     ///     tokio::spawn(async move {
375     ///         // While main has an active read lock, we acquire one too.
376     ///         let r = c_lock.read_owned().await;
377     ///         assert_eq!(*r, 1);
378     ///     }).await.expect("The spawned task has panicked");
379     ///
380     ///     // Drop the guard after the spawned task finishes.
381     ///     drop(n);
382     ///}
383     /// ```
read_owned(self: Arc<Self>) -> OwnedRwLockReadGuard<T>384     pub async fn read_owned(self: Arc<Self>) -> OwnedRwLockReadGuard<T> {
385         self.s.acquire(1).await.unwrap_or_else(|_| {
386             // The semaphore was closed. but, we never explicitly close it, and we have a
387             // handle to it through the Arc, which means that this can never happen.
388             unreachable!()
389         });
390         OwnedRwLockReadGuard {
391             data: self.c.get(),
392             lock: ManuallyDrop::new(self),
393             _p: PhantomData,
394         }
395     }
396 
397     /// Attempts to acquire this `RwLock` with shared read access.
398     ///
399     /// If the access couldn't be acquired immediately, returns [`TryLockError`].
400     /// Otherwise, an RAII guard is returned which will release read access
401     /// when dropped.
402     ///
403     /// [`TryLockError`]: TryLockError
404     ///
405     /// # Examples
406     ///
407     /// ```
408     /// use std::sync::Arc;
409     /// use tokio::sync::RwLock;
410     ///
411     /// #[tokio::main]
412     /// async fn main() {
413     ///     let lock = Arc::new(RwLock::new(1));
414     ///     let c_lock = lock.clone();
415     ///
416     ///     let v = lock.try_read().unwrap();
417     ///     assert_eq!(*v, 1);
418     ///
419     ///     tokio::spawn(async move {
420     ///         // While main has an active read lock, we acquire one too.
421     ///         let n = c_lock.read().await;
422     ///         assert_eq!(*n, 1);
423     ///     }).await.expect("The spawned task has panicked");
424     ///
425     ///     // Drop the guard when spawned task finishes.
426     ///     drop(v);
427     /// }
428     /// ```
try_read(&self) -> Result<RwLockReadGuard<'_, T>, TryLockError>429     pub fn try_read(&self) -> Result<RwLockReadGuard<'_, T>, TryLockError> {
430         match self.s.try_acquire(1) {
431             Ok(permit) => permit,
432             Err(TryAcquireError::NoPermits) => return Err(TryLockError(())),
433             Err(TryAcquireError::Closed) => unreachable!(),
434         }
435 
436         Ok(RwLockReadGuard {
437             s: &self.s,
438             data: self.c.get(),
439             marker: marker::PhantomData,
440         })
441     }
442 
443     /// Attempts to acquire this `RwLock` with shared read access.
444     ///
445     /// If the access couldn't be acquired immediately, returns [`TryLockError`].
446     /// Otherwise, an RAII guard is returned which will release read access
447     /// when dropped.
448     ///
449     /// This method is identical to [`RwLock::try_read`], except that the
450     /// returned guard references the `RwLock` with an [`Arc`] rather than by
451     /// borrowing it. Therefore, the `RwLock` must be wrapped in an `Arc` to
452     /// call this method, and the guard will live for the `'static` lifetime,
453     /// as it keeps the `RwLock` alive by holding an `Arc`.
454     ///
455     /// [`TryLockError`]: TryLockError
456     ///
457     /// # Examples
458     ///
459     /// ```
460     /// use std::sync::Arc;
461     /// use tokio::sync::RwLock;
462     ///
463     /// #[tokio::main]
464     /// async fn main() {
465     ///     let lock = Arc::new(RwLock::new(1));
466     ///     let c_lock = lock.clone();
467     ///
468     ///     let v = lock.try_read_owned().unwrap();
469     ///     assert_eq!(*v, 1);
470     ///
471     ///     tokio::spawn(async move {
472     ///         // While main has an active read lock, we acquire one too.
473     ///         let n = c_lock.read_owned().await;
474     ///         assert_eq!(*n, 1);
475     ///     }).await.expect("The spawned task has panicked");
476     ///
477     ///     // Drop the guard when spawned task finishes.
478     ///     drop(v);
479     /// }
480     /// ```
try_read_owned(self: Arc<Self>) -> Result<OwnedRwLockReadGuard<T>, TryLockError>481     pub fn try_read_owned(self: Arc<Self>) -> Result<OwnedRwLockReadGuard<T>, TryLockError> {
482         match self.s.try_acquire(1) {
483             Ok(permit) => permit,
484             Err(TryAcquireError::NoPermits) => return Err(TryLockError(())),
485             Err(TryAcquireError::Closed) => unreachable!(),
486         }
487 
488         Ok(OwnedRwLockReadGuard {
489             data: self.c.get(),
490             lock: ManuallyDrop::new(self),
491             _p: PhantomData,
492         })
493     }
494 
495     /// Locks this `RwLock` with exclusive write access, causing the current
496     /// task to yield until the lock has been acquired.
497     ///
498     /// The calling task will yield while other writers or readers currently
499     /// have access to the lock.
500     ///
501     /// Returns an RAII guard which will drop the write access of this `RwLock`
502     /// when dropped.
503     ///
504     /// # Examples
505     ///
506     /// ```
507     /// use tokio::sync::RwLock;
508     ///
509     /// #[tokio::main]
510     /// async fn main() {
511     ///   let lock = RwLock::new(1);
512     ///
513     ///   let mut n = lock.write().await;
514     ///   *n = 2;
515     ///}
516     /// ```
write(&self) -> RwLockWriteGuard<'_, T>517     pub async fn write(&self) -> RwLockWriteGuard<'_, T> {
518         self.s.acquire(self.mr).await.unwrap_or_else(|_| {
519             // The semaphore was closed. but, we never explicitly close it, and we have a
520             // handle to it through the Arc, which means that this can never happen.
521             unreachable!()
522         });
523         RwLockWriteGuard {
524             permits_acquired: self.mr,
525             s: &self.s,
526             data: self.c.get(),
527             marker: marker::PhantomData,
528         }
529     }
530 
531     /// Locks this `RwLock` with exclusive write access, causing the current
532     /// task to yield until the lock has been acquired.
533     ///
534     /// The calling task will yield while other writers or readers currently
535     /// have access to the lock.
536     ///
537     /// This method is identical to [`RwLock::write`], except that the returned
538     /// guard references the `RwLock` with an [`Arc`] rather than by borrowing
539     /// it. Therefore, the `RwLock` must be wrapped in an `Arc` to call this
540     /// method, and the guard will live for the `'static` lifetime, as it keeps
541     /// the `RwLock` alive by holding an `Arc`.
542     ///
543     /// Returns an RAII guard which will drop the write access of this `RwLock`
544     /// when dropped.
545     ///
546     /// # Examples
547     ///
548     /// ```
549     /// use std::sync::Arc;
550     /// use tokio::sync::RwLock;
551     ///
552     /// #[tokio::main]
553     /// async fn main() {
554     ///   let lock = Arc::new(RwLock::new(1));
555     ///
556     ///   let mut n = lock.write_owned().await;
557     ///   *n = 2;
558     ///}
559     /// ```
write_owned(self: Arc<Self>) -> OwnedRwLockWriteGuard<T>560     pub async fn write_owned(self: Arc<Self>) -> OwnedRwLockWriteGuard<T> {
561         self.s.acquire(self.mr).await.unwrap_or_else(|_| {
562             // The semaphore was closed. but, we never explicitly close it, and we have a
563             // handle to it through the Arc, which means that this can never happen.
564             unreachable!()
565         });
566         OwnedRwLockWriteGuard {
567             permits_acquired: self.mr,
568             data: self.c.get(),
569             lock: ManuallyDrop::new(self),
570             _p: PhantomData,
571         }
572     }
573 
574     /// Attempts to acquire this `RwLock` with exclusive write access.
575     ///
576     /// If the access couldn't be acquired immediately, returns [`TryLockError`].
577     /// Otherwise, an RAII guard is returned which will release write access
578     /// when dropped.
579     ///
580     /// [`TryLockError`]: TryLockError
581     ///
582     /// # Examples
583     ///
584     /// ```
585     /// use tokio::sync::RwLock;
586     ///
587     /// #[tokio::main]
588     /// async fn main() {
589     ///     let rw = RwLock::new(1);
590     ///
591     ///     let v = rw.read().await;
592     ///     assert_eq!(*v, 1);
593     ///
594     ///     assert!(rw.try_write().is_err());
595     /// }
596     /// ```
try_write(&self) -> Result<RwLockWriteGuard<'_, T>, TryLockError>597     pub fn try_write(&self) -> Result<RwLockWriteGuard<'_, T>, TryLockError> {
598         match self.s.try_acquire(self.mr) {
599             Ok(permit) => permit,
600             Err(TryAcquireError::NoPermits) => return Err(TryLockError(())),
601             Err(TryAcquireError::Closed) => unreachable!(),
602         }
603 
604         Ok(RwLockWriteGuard {
605             permits_acquired: self.mr,
606             s: &self.s,
607             data: self.c.get(),
608             marker: marker::PhantomData,
609         })
610     }
611 
612     /// Attempts to acquire this `RwLock` with exclusive write access.
613     ///
614     /// If the access couldn't be acquired immediately, returns [`TryLockError`].
615     /// Otherwise, an RAII guard is returned which will release write access
616     /// when dropped.
617     ///
618     /// This method is identical to [`RwLock::try_write`], except that the
619     /// returned guard references the `RwLock` with an [`Arc`] rather than by
620     /// borrowing it. Therefore, the `RwLock` must be wrapped in an `Arc` to
621     /// call this method, and the guard will live for the `'static` lifetime,
622     /// as it keeps the `RwLock` alive by holding an `Arc`.
623     ///
624     /// [`TryLockError`]: TryLockError
625     ///
626     /// # Examples
627     ///
628     /// ```
629     /// use std::sync::Arc;
630     /// use tokio::sync::RwLock;
631     ///
632     /// #[tokio::main]
633     /// async fn main() {
634     ///     let rw = Arc::new(RwLock::new(1));
635     ///
636     ///     let v = Arc::clone(&rw).read_owned().await;
637     ///     assert_eq!(*v, 1);
638     ///
639     ///     assert!(rw.try_write_owned().is_err());
640     /// }
641     /// ```
try_write_owned(self: Arc<Self>) -> Result<OwnedRwLockWriteGuard<T>, TryLockError>642     pub fn try_write_owned(self: Arc<Self>) -> Result<OwnedRwLockWriteGuard<T>, TryLockError> {
643         match self.s.try_acquire(self.mr) {
644             Ok(permit) => permit,
645             Err(TryAcquireError::NoPermits) => return Err(TryLockError(())),
646             Err(TryAcquireError::Closed) => unreachable!(),
647         }
648 
649         Ok(OwnedRwLockWriteGuard {
650             permits_acquired: self.mr,
651             data: self.c.get(),
652             lock: ManuallyDrop::new(self),
653             _p: PhantomData,
654         })
655     }
656 
657     /// Returns a mutable reference to the underlying data.
658     ///
659     /// Since this call borrows the `RwLock` mutably, no actual locking needs to
660     /// take place -- the mutable borrow statically guarantees no locks exist.
661     ///
662     /// # Examples
663     ///
664     /// ```
665     /// use tokio::sync::RwLock;
666     ///
667     /// fn main() {
668     ///     let mut lock = RwLock::new(1);
669     ///
670     ///     let n = lock.get_mut();
671     ///     *n = 2;
672     /// }
673     /// ```
get_mut(&mut self) -> &mut T674     pub fn get_mut(&mut self) -> &mut T {
675         unsafe {
676             // Safety: This is https://github.com/rust-lang/rust/pull/76936
677             &mut *self.c.get()
678         }
679     }
680 
681     /// Consumes the lock, returning the underlying data.
into_inner(self) -> T where T: Sized,682     pub fn into_inner(self) -> T
683     where
684         T: Sized,
685     {
686         self.c.into_inner()
687     }
688 }
689 
690 impl<T> From<T> for RwLock<T> {
from(s: T) -> Self691     fn from(s: T) -> Self {
692         Self::new(s)
693     }
694 }
695 
696 impl<T: ?Sized> Default for RwLock<T>
697 where
698     T: Default,
699 {
default() -> Self700     fn default() -> Self {
701         Self::new(T::default())
702     }
703 }
704