Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Miri reports a deadlock in async-lock #123

Closed
notgull opened this issue Mar 3, 2024 · 2 comments
Closed

Miri reports a deadlock in async-lock #123

notgull opened this issue Mar 3, 2024 · 2 comments

Comments

@notgull
Copy link
Member

notgull commented Mar 3, 2024

smol-rs/async-lock#80 (comment)

Given that this only cropped up after the v5.0 update, it's probably this crate's fault.

notgull added a commit that referenced this issue Mar 31, 2024
Miri appears to have issues tracking the unparker when it's stored in a
thread-local variable. For now, we can just create a fresh parker for
every wait when it comes to Miri.

cc #123

Signed-off-by: John Nunley <dev@notgull.net>
@notgull
Copy link
Member Author

notgull commented May 26, 2024

Verified that this bug was introduced in commit smol-rs/async-lock@ff4c96fe4dc72f423 or commit 86b7780, as the combination of these two commits are the first commits that observe this bug.

Diff applies to async-lock:

diff --git a/Cargo.toml b/Cargo.toml
index 88a24be..8062767 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,7 +15,7 @@ categories = ["asynchronous", "concurrency"]
 exclude = ["/.*"]
 
 [dependencies]
-event-listener = { version = "5.0.0", default-features = false }
+event-listener = { version = "4.0.0", default-features = false }
 event-listener-strategy = { version = "0.5.0", default-features = false }
 pin-project-lite = "0.2.11"
 
@@ -31,3 +31,7 @@ waker-fn = "1.1.0"
 
 [target.'cfg(target_family = "wasm")'.dev-dependencies]
 wasm-bindgen-test = "0.3"
+
+[patch.crates-io]
+event-listener = { git = "https://github.com/smol-rs/event-listener", rev = "86b7780" }
+event-listener-strategy = { path = "../event-listener-strategy" }
diff --git a/src/lib.rs b/src/lib.rs
index 6d64aa3..4debf8c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -73,13 +73,13 @@ macro_rules! pin {
 
 mod barrier;
 mod mutex;
-mod once_cell;
+//mod once_cell;
 mod rwlock;
 mod semaphore;
 
 pub use barrier::{Barrier, BarrierWaitResult};
 pub use mutex::{Mutex, MutexGuard, MutexGuardArc};
-pub use once_cell::OnceCell;
+//pub use once_cell::OnceCell;
 pub use rwlock::{
     RwLock, RwLockReadGuard, RwLockReadGuardArc, RwLockUpgradableReadGuard,
     RwLockUpgradableReadGuardArc, RwLockWriteGuard, RwLockWriteGuardArc,

Diff applied to event-listener-strategy:

diff --git a/Cargo.toml b/Cargo.toml
index fe6bf0d..13e6170 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@ categories = ["asynchronous", "concurrency"]
 exclude = ["/.*"]
 
 [dependencies]
-event-listener = { version = "5.0.0", default-features = false }
+event-listener = { version = "4.0.0", default-features = false }
 pin-project-lite = "0.2.12"
 
 [features]
diff --git a/src/lib.rs b/src/lib.rs
index e36210a..4ca69cf 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -74,7 +74,7 @@ use core::marker::PhantomData;
 use core::pin::Pin;
 use core::task::{Context, Poll};
 
-use event_listener::{EventListener, Listener};
+use event_listener::EventListener;
 
 #[doc(hidden)]
 pub use pin_project_lite::pin_project;
@@ -434,11 +434,11 @@ pub trait Strategy<'a> {
     type Future: Future + 'a;
 
     /// Poll the event listener until it is ready.
-    fn poll<T, L: Listener<T> + Unpin>(
+    fn poll(
         &mut self,
-        event_listener: &mut Option<L>,
+        event_listener: &mut Option<EventListener>,
         context: &mut Self::Context,
-    ) -> Poll<T>;
+    ) -> Poll<()>;
 
     /// Wait for the event listener to become ready.
     fn wait(&mut self, evl: EventListener) -> Self::Future;
@@ -466,11 +466,11 @@ impl<'a, 'evl> Strategy<'evl> for NonBlocking<'a> {
     }
 
     #[inline]
-    fn poll<T, L: Listener<T> + Unpin>(
+    fn poll(
         &mut self,
-        event_listener: &mut Option<L>,
+        event_listener: &mut Option<EventListener>,
         context: &mut Self::Context,
-    ) -> Poll<T> {
+    ) -> Poll<()> {
         let poll = Pin::new(
             event_listener
                 .as_mut()
@@ -503,11 +503,11 @@ impl<'evl> Strategy<'evl> for Blocking {
     }
 
     #[inline]
-    fn poll<T, L: Listener<T> + Unpin>(
+    fn poll(
         &mut self,
-        event_listener: &mut Option<L>,
+        event_listener: &mut Option<EventListener>,
         _context: &mut Self::Context,
-    ) -> Poll<T> {
+    ) -> Poll<()> {
         let result = event_listener
             .take()
             .expect("`event_listener` should never be `None`")

@notgull
Copy link
Member Author

notgull commented May 26, 2024

...then again, these race conditions have a habit of only popping up when the stars align. At this point I think instrumenting async-lock with loom is the only option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant