Skip to content

Commit 90dc513

Browse files
authored
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>
1 parent f2b822a commit 90dc513

File tree

3 files changed

+33
-18
lines changed

3 files changed

+33
-18
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ jobs:
4949
matrix:
5050
# When updating this, the reminder to update the minimum supported
5151
# Rust version in Cargo.toml.
52-
rust: ['1.41.0']
52+
rust: ['1.59.0']
5353
steps:
5454
- uses: actions/checkout@v4
5555
- name: Install Rust

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ name = "async-dup"
66
version = "1.2.3"
77
authors = ["Stjepan Glavina <stjepang@gmail.com>"]
88
edition = "2018"
9-
rust-version = "1.41"
9+
rust-version = "1.59"
1010
description = "Duplicate an async I/O handle"
1111
license = "Apache-2.0 OR MIT"
1212
repository = "https://github.com/smol-rs/async-dup"
@@ -17,6 +17,7 @@ categories = ["asynchronous", "concurrency"]
1717
exclude = ["/.*"]
1818

1919
[dependencies]
20+
async-lock = "3.1.0"
2021
futures-io = "0.3.5"
2122

2223
[dev-dependencies]

src/lib.rs

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ use std::hash::{Hash, Hasher};
6060
use std::io::{self, IoSlice, IoSliceMut, SeekFrom};
6161
use std::ops::{Deref, DerefMut};
6262
use std::pin::Pin;
63-
use std::sync::TryLockError;
6463
use std::task::{Context, Poll};
6564

6665
use futures_io::{AsyncRead, AsyncSeek, AsyncWrite};
@@ -227,7 +226,7 @@ where
227226
/// - `impl<T> AsyncWrite for &Mutex<T> where T: AsyncWrite + Unpin {}`
228227
/// - `impl<T> AsyncSeek for Mutex<T> where T: AsyncSeek + Unpin {}`
229228
/// - `impl<T> AsyncSeek for &Mutex<T> where T: AsyncSeek + Unpin {}`
230-
pub struct Mutex<T>(std::sync::Mutex<T>);
229+
pub struct Mutex<T>(async_lock::Mutex<T>);
231230

232231
impl<T> Mutex<T> {
233232
/// Creates a new mutex.
@@ -257,7 +256,7 @@ impl<T> Mutex<T> {
257256
/// assert_eq!(*guard, 10);
258257
/// ```
259258
pub fn lock(&self) -> MutexGuard<'_, T> {
260-
MutexGuard(self.0.lock().unwrap_or_else(|e| e.into_inner()))
259+
MutexGuard(self.0.lock_blocking())
261260
}
262261

263262
/// Attempts to acquire the mutex.
@@ -279,16 +278,7 @@ impl<T> Mutex<T> {
279278
/// # ;
280279
/// ```
281280
pub fn try_lock(&self) -> Option<MutexGuard<'_, T>> {
282-
self.0
283-
.try_lock()
284-
.map_or_else(
285-
|e| match e {
286-
TryLockError::Poisoned(e) => Some(e.into_inner()),
287-
TryLockError::WouldBlock => None,
288-
},
289-
Some,
290-
)
291-
.map(MutexGuard)
281+
self.0.try_lock().map(MutexGuard)
292282
}
293283

294284
/// Consumes the mutex, returning the underlying data.
@@ -302,7 +292,7 @@ impl<T> Mutex<T> {
302292
/// assert_eq!(mutex.into_inner(), 10);
303293
/// ```
304294
pub fn into_inner(self) -> T {
305-
self.0.into_inner().unwrap_or_else(|e| e.into_inner())
295+
self.0.into_inner()
306296
}
307297

308298
/// Returns a mutable reference to the underlying data.
@@ -320,7 +310,7 @@ impl<T> Mutex<T> {
320310
/// assert_eq!(*mutex.lock(), 10);
321311
/// ```
322312
pub fn get_mut(&mut self) -> &mut T {
323-
self.0.get_mut().unwrap_or_else(|e| e.into_inner())
313+
self.0.get_mut()
324314
}
325315
}
326316

@@ -461,7 +451,7 @@ impl<T: AsyncSeek + Unpin> AsyncSeek for &Mutex<T> {
461451
}
462452

463453
/// A guard that releases the mutex when dropped.
464-
pub struct MutexGuard<'a, T>(std::sync::MutexGuard<'a, T>);
454+
pub struct MutexGuard<'a, T>(async_lock::MutexGuard<'a, T>);
465455

466456
impl<T: fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
467457
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -488,3 +478,27 @@ impl<T> DerefMut for MutexGuard<'_, T> {
488478
&mut self.0
489479
}
490480
}
481+
482+
#[cfg(test)]
483+
mod tests {
484+
use super::*;
485+
486+
fn is_send<T: Send>(_: &T) {}
487+
fn is_sync<T: Sync>(_: &T) {}
488+
489+
#[test]
490+
fn is_send_sync() {
491+
let arc = Arc::new(());
492+
let mutex = Mutex::new(());
493+
494+
is_send(&arc);
495+
is_sync(&arc);
496+
497+
is_send(&mutex);
498+
is_sync(&mutex);
499+
500+
let guard = mutex.lock();
501+
is_send(&guard);
502+
is_sync(&guard);
503+
}
504+
}

0 commit comments

Comments
 (0)