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