mirror of https://github.com/smol-rs/async-dup
bugfix: Use async-lock as the locking mechanism
We can't use `std::sync::Mutex` without further unsafe code, and we can't use `simple-mutex` since it is unmaintained. Therefore we use the `async-lock` crate, since it has a good blocking mutex. Closes #12 Signed-off-by: John Nunley <dev@notgull.net>
This commit is contained in:
parent
f2b822a618
commit
90dc513458
|
@ -49,7 +49,7 @@ jobs:
|
|||
matrix:
|
||||
# When updating this, the reminder to update the minimum supported
|
||||
# Rust version in Cargo.toml.
|
||||
rust: ['1.41.0']
|
||||
rust: ['1.59.0']
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Rust
|
||||
|
|
|
@ -6,7 +6,7 @@ name = "async-dup"
|
|||
version = "1.2.3"
|
||||
authors = ["Stjepan Glavina <stjepang@gmail.com>"]
|
||||
edition = "2018"
|
||||
rust-version = "1.41"
|
||||
rust-version = "1.59"
|
||||
description = "Duplicate an async I/O handle"
|
||||
license = "Apache-2.0 OR MIT"
|
||||
repository = "https://github.com/smol-rs/async-dup"
|
||||
|
@ -17,6 +17,7 @@ categories = ["asynchronous", "concurrency"]
|
|||
exclude = ["/.*"]
|
||||
|
||||
[dependencies]
|
||||
async-lock = "3.1.0"
|
||||
futures-io = "0.3.5"
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
46
src/lib.rs
46
src/lib.rs
|
@ -60,7 +60,6 @@ use std::hash::{Hash, Hasher};
|
|||
use std::io::{self, IoSlice, IoSliceMut, SeekFrom};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::pin::Pin;
|
||||
use std::sync::TryLockError;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use futures_io::{AsyncRead, AsyncSeek, AsyncWrite};
|
||||
|
@ -227,7 +226,7 @@ where
|
|||
/// - `impl<T> AsyncWrite for &Mutex<T> where T: AsyncWrite + Unpin {}`
|
||||
/// - `impl<T> AsyncSeek for Mutex<T> where T: AsyncSeek + Unpin {}`
|
||||
/// - `impl<T> AsyncSeek for &Mutex<T> where T: AsyncSeek + Unpin {}`
|
||||
pub struct Mutex<T>(std::sync::Mutex<T>);
|
||||
pub struct Mutex<T>(async_lock::Mutex<T>);
|
||||
|
||||
impl<T> Mutex<T> {
|
||||
/// Creates a new mutex.
|
||||
|
@ -257,7 +256,7 @@ impl<T> Mutex<T> {
|
|||
/// assert_eq!(*guard, 10);
|
||||
/// ```
|
||||
pub fn lock(&self) -> MutexGuard<'_, T> {
|
||||
MutexGuard(self.0.lock().unwrap_or_else(|e| e.into_inner()))
|
||||
MutexGuard(self.0.lock_blocking())
|
||||
}
|
||||
|
||||
/// Attempts to acquire the mutex.
|
||||
|
@ -279,16 +278,7 @@ impl<T> Mutex<T> {
|
|||
/// # ;
|
||||
/// ```
|
||||
pub fn try_lock(&self) -> Option<MutexGuard<'_, T>> {
|
||||
self.0
|
||||
.try_lock()
|
||||
.map_or_else(
|
||||
|e| match e {
|
||||
TryLockError::Poisoned(e) => Some(e.into_inner()),
|
||||
TryLockError::WouldBlock => None,
|
||||
},
|
||||
Some,
|
||||
)
|
||||
.map(MutexGuard)
|
||||
self.0.try_lock().map(MutexGuard)
|
||||
}
|
||||
|
||||
/// Consumes the mutex, returning the underlying data.
|
||||
|
@ -302,7 +292,7 @@ impl<T> Mutex<T> {
|
|||
/// assert_eq!(mutex.into_inner(), 10);
|
||||
/// ```
|
||||
pub fn into_inner(self) -> T {
|
||||
self.0.into_inner().unwrap_or_else(|e| e.into_inner())
|
||||
self.0.into_inner()
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the underlying data.
|
||||
|
@ -320,7 +310,7 @@ impl<T> Mutex<T> {
|
|||
/// assert_eq!(*mutex.lock(), 10);
|
||||
/// ```
|
||||
pub fn get_mut(&mut self) -> &mut T {
|
||||
self.0.get_mut().unwrap_or_else(|e| e.into_inner())
|
||||
self.0.get_mut()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -461,7 +451,7 @@ impl<T: AsyncSeek + Unpin> AsyncSeek for &Mutex<T> {
|
|||
}
|
||||
|
||||
/// A guard that releases the mutex when dropped.
|
||||
pub struct MutexGuard<'a, T>(std::sync::MutexGuard<'a, T>);
|
||||
pub struct MutexGuard<'a, T>(async_lock::MutexGuard<'a, T>);
|
||||
|
||||
impl<T: fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
|
@ -488,3 +478,27 @@ impl<T> DerefMut for MutexGuard<'_, T> {
|
|||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn is_send<T: Send>(_: &T) {}
|
||||
fn is_sync<T: Sync>(_: &T) {}
|
||||
|
||||
#[test]
|
||||
fn is_send_sync() {
|
||||
let arc = Arc::new(());
|
||||
let mutex = Mutex::new(());
|
||||
|
||||
is_send(&arc);
|
||||
is_sync(&arc);
|
||||
|
||||
is_send(&mutex);
|
||||
is_sync(&mutex);
|
||||
|
||||
let guard = mutex.lock();
|
||||
is_send(&guard);
|
||||
is_sync(&guard);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue