fd_lock/sys/unix/
rw_lock.rs1use rustix::fd::AsFd;
2use rustix::fs::{flock, FlockOperation};
3use std::io::{self, Error, ErrorKind};
4
5use super::{RwLockReadGuard, RwLockWriteGuard};
6
7#[derive(Debug)]
8pub struct RwLock<T: AsFd> {
9 pub(crate) inner: T,
10}
11
12impl<T: AsFd> RwLock<T> {
13 #[inline]
14 pub fn new(inner: T) -> Self {
15 RwLock { inner }
16 }
17
18 #[inline]
19 pub fn write(&mut self) -> io::Result<RwLockWriteGuard<'_, T>> {
20 flock(&self.inner.as_fd(), FlockOperation::LockExclusive)?;
21 Ok(RwLockWriteGuard::new(self))
22 }
23
24 #[inline]
25 pub fn try_write(&mut self) -> Result<RwLockWriteGuard<'_, T>, Error> {
26 flock(
27 &self.inner.as_fd(),
28 FlockOperation::NonBlockingLockExclusive,
29 )
30 .map_err(|err| match err.kind() {
31 ErrorKind::AlreadyExists => ErrorKind::WouldBlock.into(),
32 _ => Error::from(err),
33 })?;
34 Ok(RwLockWriteGuard::new(self))
35 }
36
37 #[inline]
38 pub fn read(&self) -> io::Result<RwLockReadGuard<'_, T>> {
39 flock(&self.inner.as_fd(), FlockOperation::LockShared)?;
40 Ok(RwLockReadGuard::new(self))
41 }
42
43 #[inline]
44 pub fn try_read(&self) -> Result<RwLockReadGuard<'_, T>, Error> {
45 flock(&self.inner.as_fd(), FlockOperation::NonBlockingLockShared).map_err(
46 |err| match err.kind() {
47 ErrorKind::AlreadyExists => ErrorKind::WouldBlock.into(),
48 _ => Error::from(err),
49 },
50 )?;
51 Ok(RwLockReadGuard::new(self))
52 }
53
54 #[inline]
55 pub fn into_inner(self) -> T
56 where
57 T: Sized,
58 {
59 self.inner
60 }
61}