aboutsummaryrefslogtreecommitdiff
path: root/src/sync/tests/notify.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/sync/tests/notify.rs')
-rw-r--r--src/sync/tests/notify.rs52
1 files changed, 45 insertions, 7 deletions
diff --git a/src/sync/tests/notify.rs b/src/sync/tests/notify.rs
index eb0da8f..323b5c6 100644
--- a/src/sync/tests/notify.rs
+++ b/src/sync/tests/notify.rs
@@ -1,10 +1,9 @@
use crate::sync::Notify;
use std::future::Future;
-use std::mem::ManuallyDrop;
use std::sync::Arc;
use std::task::{Context, RawWaker, RawWakerVTable, Waker};
-#[cfg(tokio_wasm_not_wasi)]
+#[cfg(all(target_family = "wasm", not(target_os = "wasi")))]
use wasm_bindgen_test::wasm_bindgen_test as test;
#[test]
@@ -12,16 +11,16 @@ fn notify_clones_waker_before_lock() {
const VTABLE: &RawWakerVTable = &RawWakerVTable::new(clone_w, wake, wake_by_ref, drop_w);
unsafe fn clone_w(data: *const ()) -> RawWaker {
- let arc = ManuallyDrop::new(Arc::<Notify>::from_raw(data as *const Notify));
+ let ptr = data as *const Notify;
+ Arc::<Notify>::increment_strong_count(ptr);
// Or some other arbitrary code that shouldn't be executed while the
// Notify wait list is locked.
- arc.notify_one();
- let _arc_clone: ManuallyDrop<_> = arc.clone();
+ (*ptr).notify_one();
RawWaker::new(data, VTABLE)
}
unsafe fn drop_w(data: *const ()) {
- let _ = Arc::<Notify>::from_raw(data as *const Notify);
+ drop(Arc::<Notify>::from_raw(data as *const Notify));
}
unsafe fn wake(_data: *const ()) {
@@ -46,6 +45,45 @@ fn notify_clones_waker_before_lock() {
let _ = future.poll(&mut cx);
}
+#[cfg(panic = "unwind")]
+#[test]
+fn notify_waiters_handles_panicking_waker() {
+ use futures::task::ArcWake;
+
+ let notify = Arc::new(Notify::new());
+
+ struct PanickingWaker(Arc<Notify>);
+
+ impl ArcWake for PanickingWaker {
+ fn wake_by_ref(_arc_self: &Arc<Self>) {
+ panic!("waker panicked");
+ }
+ }
+
+ let bad_fut = notify.notified();
+ pin!(bad_fut);
+
+ let waker = futures::task::waker(Arc::new(PanickingWaker(notify.clone())));
+ let mut cx = Context::from_waker(&waker);
+ let _ = bad_fut.poll(&mut cx);
+
+ let mut futs = Vec::new();
+ for _ in 0..32 {
+ let mut fut = tokio_test::task::spawn(notify.notified());
+ assert!(fut.poll().is_pending());
+ futs.push(fut);
+ }
+
+ assert!(std::panic::catch_unwind(|| {
+ notify.notify_waiters();
+ })
+ .is_err());
+
+ for mut fut in futs {
+ assert!(fut.poll().is_ready());
+ }
+}
+
#[test]
fn notify_simple() {
let notify = Notify::new();
@@ -63,7 +101,7 @@ fn notify_simple() {
}
#[test]
-#[cfg(not(tokio_wasm))]
+#[cfg(not(target_family = "wasm"))]
fn watch_test() {
let rt = crate::runtime::Builder::new_current_thread()
.build()