Change the behavior of JoinHandle
diff --git a/src/join_handle.rs b/src/join_handle.rs
index 487adf5..745c786 100644
--- a/src/join_handle.rs
+++ b/src/join_handle.rs
@@ -1,6 +1,7 @@
use core::fmt;
use core::future::Future;
use core::marker::{PhantomData, Unpin};
+use core::mem;
use core::pin::Pin;
use core::ptr::NonNull;
use core::sync::atomic::Ordering;
@@ -29,130 +30,131 @@
impl<R> Unpin for JoinHandle<R> {}
impl<R> JoinHandle<R> {
- /// Cancels the task.
- ///
- /// If the task has already completed, calling this method will have no effect.
- ///
- /// When a task is canceled, its future will not be polled again.
- pub fn cancel(&self) {
+ pub fn detach(self) {
let ptr = self.raw_task.as_ptr();
+ mem::forget(self);
+ unsafe {
+ Self::drop_raw(ptr);
+ }
+ }
+
+ pub async fn cancel(self) -> Option<R> {
+ unsafe {
+ Self::cancel_raw(self.raw_task.as_ptr());
+ }
+ self.await
+ }
+
+ unsafe fn cancel_raw(ptr: *const ()) {
let header = ptr as *const Header;
- unsafe {
- let mut state = (*header).state.load(Ordering::Acquire);
+ let mut state = (*header).state.load(Ordering::Acquire);
- loop {
- // If the task has been completed or closed, it can't be canceled.
- if state & (COMPLETED | CLOSED) != 0 {
+ loop {
+ // If the task has been completed or closed, it can't be canceled.
+ if state & (COMPLETED | CLOSED) != 0 {
+ break;
+ }
+
+ // If the task is not scheduled nor running, we'll need to schedule it.
+ let new = if state & (SCHEDULED | RUNNING) == 0 {
+ (state | SCHEDULED | CLOSED) + REFERENCE
+ } else {
+ state | CLOSED
+ };
+
+ // Mark the task as closed.
+ match (*header).state.compare_exchange_weak(
+ state,
+ new,
+ Ordering::AcqRel,
+ Ordering::Acquire,
+ ) {
+ Ok(_) => {
+ // If the task is not scheduled nor running, schedule it one more time so
+ // that its future gets dropped by the executor.
+ if state & (SCHEDULED | RUNNING) == 0 {
+ ((*header).vtable.schedule)(ptr);
+ }
+
+ // Notify the awaiter that the task has been closed.
+ if state & AWAITER != 0 {
+ (*header).notify(None);
+ }
+
break;
}
-
- // If the task is not scheduled nor running, we'll need to schedule it.
- let new = if state & (SCHEDULED | RUNNING) == 0 {
- (state | SCHEDULED | CLOSED) + REFERENCE
- } else {
- state | CLOSED
- };
-
- // Mark the task as closed.
- match (*header).state.compare_exchange_weak(
- state,
- new,
- Ordering::AcqRel,
- Ordering::Acquire,
- ) {
- Ok(_) => {
- // If the task is not scheduled nor running, schedule it one more time so
- // that its future gets dropped by the executor.
- if state & (SCHEDULED | RUNNING) == 0 {
- ((*header).vtable.schedule)(ptr);
- }
-
- // Notify the awaiter that the task has been closed.
- if state & AWAITER != 0 {
- (*header).notify(None);
- }
-
- break;
- }
- Err(s) => state = s,
- }
+ Err(s) => state = s,
}
}
}
-}
-impl<R> Drop for JoinHandle<R> {
- fn drop(&mut self) {
- let ptr = self.raw_task.as_ptr();
+ unsafe fn drop_raw(ptr: *const ()) {
let header = ptr as *const Header;
// A place where the output will be stored in case it needs to be dropped.
let mut output = None;
- unsafe {
- // Optimistically assume the `JoinHandle` is being dropped just after creating the
- // task. This is a common case so if the handle is not used, the overhead of it is only
- // one compare-exchange operation.
- if let Err(mut state) = (*header).state.compare_exchange_weak(
- SCHEDULED | HANDLE | REFERENCE,
- SCHEDULED | REFERENCE,
- Ordering::AcqRel,
- Ordering::Acquire,
- ) {
- loop {
- // If the task has been completed but not yet closed, that means its output
- // must be dropped.
- if state & COMPLETED != 0 && state & CLOSED == 0 {
- // Mark the task as closed in order to grab its output.
- match (*header).state.compare_exchange_weak(
- state,
- state | CLOSED,
- Ordering::AcqRel,
- Ordering::Acquire,
- ) {
- Ok(_) => {
- // Read the output.
- output =
- Some((((*header).vtable.get_output)(ptr) as *mut R).read());
+ // Optimistically assume the `JoinHandle` is being detached just after creating the
+ // task. This is a common case so if the handle is not used, the overhead of it is only
+ // one compare-exchange operation.
+ if let Err(mut state) = (*header).state.compare_exchange_weak(
+ SCHEDULED | HANDLE | REFERENCE,
+ SCHEDULED | REFERENCE,
+ Ordering::AcqRel,
+ Ordering::Acquire,
+ ) {
+ loop {
+ // If the task has been completed but not yet closed, that means its output
+ // must be dropped.
+ if state & COMPLETED != 0 && state & CLOSED == 0 {
+ // Mark the task as closed in order to grab its output.
+ match (*header).state.compare_exchange_weak(
+ state,
+ state | CLOSED,
+ Ordering::AcqRel,
+ Ordering::Acquire,
+ ) {
+ Ok(_) => {
+ // Read the output.
+ output = Some((((*header).vtable.get_output)(ptr) as *mut R).read());
- // Update the state variable because we're continuing the loop.
- state |= CLOSED;
- }
- Err(s) => state = s,
+ // Update the state variable because we're continuing the loop.
+ state |= CLOSED;
}
+ Err(s) => state = s,
+ }
+ } else {
+ // If this is the last reference to the task and it's not closed, then
+ // close it and schedule one more time so that its future gets dropped by
+ // the executor.
+ let new = if state & (!(REFERENCE - 1) | CLOSED) == 0 {
+ SCHEDULED | CLOSED | REFERENCE
} else {
- // If this is the last reference to the task and it's not closed, then
- // close it and schedule one more time so that its future gets dropped by
- // the executor.
- let new = if state & (!(REFERENCE - 1) | CLOSED) == 0 {
- SCHEDULED | CLOSED | REFERENCE
- } else {
- state & !HANDLE
- };
+ state & !HANDLE
+ };
- // Unset the handle flag.
- match (*header).state.compare_exchange_weak(
- state,
- new,
- Ordering::AcqRel,
- Ordering::Acquire,
- ) {
- Ok(_) => {
- // If this is the last reference to the task, we need to either
- // schedule dropping its future or destroy it.
- if state & !(REFERENCE - 1) == 0 {
- if state & CLOSED == 0 {
- ((*header).vtable.schedule)(ptr);
- } else {
- ((*header).vtable.destroy)(ptr);
- }
+ // Unset the handle flag.
+ match (*header).state.compare_exchange_weak(
+ state,
+ new,
+ Ordering::AcqRel,
+ Ordering::Acquire,
+ ) {
+ Ok(_) => {
+ // If this is the last reference to the task, we need to either
+ // schedule dropping its future or destroy it.
+ if state & !(REFERENCE - 1) == 0 {
+ if state & CLOSED == 0 {
+ ((*header).vtable.schedule)(ptr);
+ } else {
+ ((*header).vtable.destroy)(ptr);
}
-
- break;
}
- Err(s) => state = s,
+
+ break;
}
+ Err(s) => state = s,
}
}
}
@@ -163,6 +165,16 @@
}
}
+impl<R> Drop for JoinHandle<R> {
+ fn drop(&mut self) {
+ let ptr = self.raw_task.as_ptr();
+ unsafe {
+ Self::cancel_raw(ptr);
+ Self::drop_raw(ptr);
+ }
+ }
+}
+
impl<R> Future for JoinHandle<R> {
type Output = Option<R>;
diff --git a/src/task.rs b/src/task.rs
index 10f9a34..0f7e4ea 100644
--- a/src/task.rs
+++ b/src/task.rs
@@ -254,18 +254,14 @@
unsafe { ((*header).vtable.run)(ptr) }
}
- /// Cancels the task.
- ///
- /// When canceled, the task won't be scheduled again even if a [`Waker`] wakes it. An attempt
- /// to run it won't do anything.
- ///
- /// [`Waker`]: https://doc.rust-lang.org/std/task/struct.Waker.html
- pub fn cancel(&self) {
+ /// Returns a waker associated with this task.
+ pub fn waker(&self) -> Waker {
let ptr = self.raw_task.as_ptr();
let header = ptr as *const Header;
unsafe {
- (*header).cancel();
+ let raw_waker = ((*header).vtable.clone_waker)(ptr);
+ Waker::from_raw(raw_waker)
}
}
@@ -286,17 +282,6 @@
raw_task: NonNull::new_unchecked(raw as *mut ()),
}
}
-
- /// Returns a waker associated with this task.
- pub fn waker(&self) -> Waker {
- let ptr = self.raw_task.as_ptr();
- let header = ptr as *const Header;
-
- unsafe {
- let raw_waker = ((*header).vtable.clone_waker)(ptr);
- Waker::from_raw(raw_waker)
- }
- }
}
impl Drop for Task {
diff --git a/tests/basic.rs b/tests/basic.rs
index 14621fe..47dd075 100644
--- a/tests/basic.rs
+++ b/tests/basic.rs
@@ -79,7 +79,7 @@
}
#[test]
-fn cancel_and_drop_handle() {
+fn drop_and_detach() {
future!(f, POLL, DROP_F);
schedule!(s, SCHEDULE, DROP_S);
let (task, handle) = async_task::spawn(f, s);
@@ -89,13 +89,26 @@
assert_eq!(DROP_F.load(), 0);
assert_eq!(DROP_S.load(), 0);
- task.cancel();
+ drop(task);
assert_eq!(POLL.load(), 0);
assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
+ assert_eq!(DROP_F.load(), 1);
assert_eq!(DROP_S.load(), 0);
- drop(handle);
+ handle.detach();
+ assert_eq!(POLL.load(), 0);
+ assert_eq!(SCHEDULE.load(), 0);
+ assert_eq!(DROP_F.load(), 1);
+ assert_eq!(DROP_S.load(), 1);
+}
+
+#[test]
+fn detach_and_drop() {
+ future!(f, POLL, DROP_F);
+ schedule!(s, SCHEDULE, DROP_S);
+ let (task, handle) = async_task::spawn(f, s);
+
+ handle.detach();
assert_eq!(POLL.load(), 0);
assert_eq!(SCHEDULE.load(), 0);
assert_eq!(DROP_F.load(), 0);
@@ -109,12 +122,12 @@
}
#[test]
-fn run_and_drop_handle() {
+fn detach_and_run() {
future!(f, POLL, DROP_F);
schedule!(s, SCHEDULE, DROP_S);
let (task, handle) = async_task::spawn(f, s);
- drop(handle);
+ handle.detach();
assert_eq!(POLL.load(), 0);
assert_eq!(SCHEDULE.load(), 0);
assert_eq!(DROP_F.load(), 0);
@@ -128,18 +141,18 @@
}
#[test]
-fn drop_handle_and_run() {
+fn run_and_detach() {
future!(f, POLL, DROP_F);
schedule!(s, SCHEDULE, DROP_S);
let (task, handle) = async_task::spawn(f, s);
- drop(handle);
- assert_eq!(POLL.load(), 0);
+ task.run();
+ assert_eq!(POLL.load(), 1);
assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
+ assert_eq!(DROP_F.load(), 1);
assert_eq!(DROP_S.load(), 0);
- task.run();
+ handle.detach();
assert_eq!(POLL.load(), 1);
assert_eq!(SCHEDULE.load(), 0);
assert_eq!(DROP_F.load(), 1);
@@ -152,12 +165,6 @@
schedule!(s, SCHEDULE, DROP_S);
let (task, handle) = async_task::spawn(f, s);
- handle.cancel();
- assert_eq!(POLL.load(), 0);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
-
drop(handle);
assert_eq!(POLL.load(), 0);
assert_eq!(SCHEDULE.load(), 0);
@@ -183,12 +190,6 @@
assert_eq!(DROP_F.load(), 1);
assert_eq!(DROP_S.load(), 0);
- handle.cancel();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
-
drop(handle);
assert_eq!(POLL.load(), 1);
assert_eq!(SCHEDULE.load(), 0);
@@ -200,31 +201,28 @@
fn cancel_and_poll() {
future!(f, POLL, DROP_F);
schedule!(s, SCHEDULE, DROP_S);
- let (task, handle) = async_task::spawn(f, s);
+ let (task, mut handle) = async_task::spawn(f, s);
- handle.cancel();
+ assert!((&mut handle).now_or_never().is_none());
assert_eq!(POLL.load(), 0);
assert_eq!(SCHEDULE.load(), 0);
assert_eq!(DROP_F.load(), 0);
assert_eq!(DROP_S.load(), 0);
- let mut handle = handle;
- assert!((&mut handle).now_or_never().is_none());
-
task.run();
- assert_eq!(POLL.load(), 0);
+ assert_eq!(POLL.load(), 1);
assert_eq!(SCHEDULE.load(), 0);
assert_eq!(DROP_F.load(), 1);
assert_eq!(DROP_S.load(), 0);
assert!((&mut handle).now_or_never().is_some());
- assert_eq!(POLL.load(), 0);
+ assert_eq!(POLL.load(), 1);
assert_eq!(SCHEDULE.load(), 0);
assert_eq!(DROP_F.load(), 1);
assert_eq!(DROP_S.load(), 0);
drop(handle);
- assert_eq!(POLL.load(), 0);
+ assert_eq!(POLL.load(), 1);
assert_eq!(SCHEDULE.load(), 0);
assert_eq!(DROP_F.load(), 1);
assert_eq!(DROP_S.load(), 1);
diff --git a/tests/join.rs b/tests/join.rs
index e7f0972..ca0ef54 100644
--- a/tests/join.rs
+++ b/tests/join.rs
@@ -96,14 +96,13 @@
}
#[test]
-fn cancel_and_join() {
+fn drop_and_join() {
future!(f, POLL, DROP_F, DROP_O);
schedule!(s, SCHEDULE, DROP_S);
let (task, handle) = async_task::spawn(f, s);
assert_eq!(DROP_O.load(), 0);
- task.cancel();
drop(task);
assert_eq!(DROP_O.load(), 0);
@@ -135,14 +134,14 @@
}
#[test]
-fn drop_handle_and_run() {
+fn detach_and_run() {
future!(f, POLL, DROP_F, DROP_O);
schedule!(s, SCHEDULE, DROP_S);
let (task, handle) = async_task::spawn(f, s);
assert_eq!(DROP_O.load(), 0);
- drop(handle);
+ handle.detach();
assert_eq!(DROP_O.load(), 0);
task.run();
@@ -178,7 +177,7 @@
assert_eq!(DROP_S.load(), 0);
assert_eq!(DROP_O.load(), 1);
- drop(handle);
+ handle.detach();
assert_eq!(DROP_S.load(), 1);
}
@@ -191,8 +190,6 @@
crossbeam::scope(|scope| {
scope.spawn(|_| {
thread::sleep(ms(200));
-
- task.cancel();
drop(task);
thread::sleep(ms(400));
@@ -292,7 +289,7 @@
crossbeam::scope(|scope| {
scope.spawn(|_| {
- thread::sleep(ms(400));
+ thread::sleep(ms(200));
task.run();
assert_eq!(POLL.load(), 0);
@@ -308,13 +305,6 @@
assert_eq!(DROP_S.load(), 0);
assert_eq!(DROP_O.load(), 0);
- handle.cancel();
- assert_eq!(POLL.load(), 0);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(DROP_O.load(), 0);
-
drop(handle);
assert_eq!(POLL.load(), 0);
assert_eq!(SCHEDULE.load(), 0);
@@ -351,13 +341,6 @@
thread::sleep(ms(400));
- handle.cancel();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(DROP_O.load(), 0);
-
drop(handle);
assert_eq!(POLL.load(), 1);
assert_eq!(SCHEDULE.load(), 0);
diff --git a/tests/panic.rs b/tests/panic.rs
index 19c5f2b..6641025 100644
--- a/tests/panic.rs
+++ b/tests/panic.rs
@@ -102,12 +102,6 @@
thread::sleep(ms(200));
- handle.cancel();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
-
drop(handle);
assert_eq!(POLL.load(), 1);
assert_eq!(SCHEDULE.load(), 0);
@@ -219,7 +213,7 @@
}
#[test]
-fn drop_handle_during_run() {
+fn detach_during_run() {
future!(f, POLL, DROP_F);
schedule!(s, SCHEDULE, DROP_S);
let (task, handle) = async_task::spawn(f, s);
@@ -235,7 +229,7 @@
thread::sleep(ms(200));
- drop(handle);
+ handle.detach();
assert_eq!(POLL.load(), 1);
assert_eq!(SCHEDULE.load(), 0);
assert_eq!(DROP_F.load(), 0);
diff --git a/tests/ready.rs b/tests/ready.rs
index 5f0efe1..12b3f06 100644
--- a/tests/ready.rs
+++ b/tests/ready.rs
@@ -106,13 +106,19 @@
assert_eq!(POLL.load(), 1);
assert_eq!(SCHEDULE.load(), 0);
assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(DROP_S.load(), 1);
assert_eq!(DROP_O.load(), 1);
});
thread::sleep(ms(200));
- handle.cancel();
+ assert_eq!(POLL.load(), 1);
+ assert_eq!(SCHEDULE.load(), 0);
+ assert_eq!(DROP_F.load(), 0);
+ assert_eq!(DROP_S.load(), 0);
+ assert_eq!(DROP_O.load(), 0);
+
+ drop(handle);
assert_eq!(POLL.load(), 1);
assert_eq!(SCHEDULE.load(), 0);
assert_eq!(DROP_F.load(), 0);
@@ -124,13 +130,6 @@
assert_eq!(POLL.load(), 1);
assert_eq!(SCHEDULE.load(), 0);
assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(DROP_O.load(), 1);
-
- drop(handle);
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
assert_eq!(DROP_S.load(), 1);
assert_eq!(DROP_O.load(), 1);
})
@@ -151,6 +150,7 @@
assert_eq!(DROP_F.load(), 1);
thread::sleep(ms(200));
+
assert_eq!(DROP_S.load(), 1);
});
@@ -163,6 +163,7 @@
assert_eq!(DROP_O.load(), 1);
thread::sleep(ms(200));
+
assert_eq!(DROP_S.load(), 1);
})
.unwrap();
@@ -198,7 +199,7 @@
}
#[test]
-fn drop_handle_during_run() {
+fn detach_during_run() {
future!(f, POLL, DROP_F, DROP_O);
schedule!(s, SCHEDULE, DROP_S);
let (task, handle) = async_task::spawn(f, s);
@@ -215,7 +216,7 @@
thread::sleep(ms(200));
- drop(handle);
+ handle.detach();
assert_eq!(POLL.load(), 1);
assert_eq!(SCHEDULE.load(), 0);
assert_eq!(DROP_F.load(), 0);
diff --git a/tests/waker_panic.rs b/tests/waker_panic.rs
index b090d00..457e69b 100644
--- a/tests/waker_panic.rs
+++ b/tests/waker_panic.rs
@@ -132,7 +132,7 @@
thread::sleep(ms(200));
w.wake();
- drop(handle);
+ handle.detach();
assert_eq!(POLL.load(), 2);
assert_eq!(SCHEDULE.load(), 1);
assert_eq!(DROP_F.load(), 0);
@@ -174,13 +174,6 @@
thread::sleep(ms(200));
- handle.cancel();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(chan.len(), 0);
-
drop(handle);
assert_eq!(POLL.load(), 2);
assert_eq!(SCHEDULE.load(), 1);
@@ -230,13 +223,6 @@
assert_eq!(DROP_S.load(), 0);
assert_eq!(chan.len(), 0);
- handle.cancel();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(chan.len(), 0);
-
drop(handle);
assert_eq!(POLL.load(), 2);
assert_eq!(SCHEDULE.load(), 1);
@@ -279,13 +265,6 @@
thread::sleep(ms(200));
- handle.cancel();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(chan.len(), 0);
-
drop(handle);
assert_eq!(POLL.load(), 2);
assert_eq!(SCHEDULE.load(), 1);
diff --git a/tests/waker_pending.rs b/tests/waker_pending.rs
index 8887264..683e595 100644
--- a/tests/waker_pending.rs
+++ b/tests/waker_pending.rs
@@ -164,13 +164,6 @@
thread::sleep(ms(200));
- handle.cancel();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(chan.len(), 0);
-
drop(handle);
assert_eq!(POLL.load(), 2);
assert_eq!(SCHEDULE.load(), 1);
@@ -220,13 +213,6 @@
assert_eq!(DROP_S.load(), 0);
assert_eq!(chan.len(), 0);
- handle.cancel();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(chan.len(), 0);
-
drop(handle);
assert_eq!(POLL.load(), 2);
assert_eq!(SCHEDULE.load(), 1);
@@ -269,13 +255,6 @@
thread::sleep(ms(200));
- handle.cancel();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(chan.len(), 0);
-
drop(handle);
assert_eq!(POLL.load(), 2);
assert_eq!(SCHEDULE.load(), 1);
@@ -310,7 +289,7 @@
task.run();
let w = waker();
- drop(handle);
+ handle.detach();
assert_eq!(POLL.load(), 1);
assert_eq!(SCHEDULE.load(), 0);
assert_eq!(DROP_F.load(), 0);
@@ -346,7 +325,7 @@
assert_eq!(DROP_S.load(), 0);
assert_eq!(chan.len(), 0);
- handle.cancel();
+ drop(handle);
assert_eq!(POLL.load(), 1);
assert_eq!(SCHEDULE.load(), 1);
assert_eq!(DROP_F.load(), 0);
@@ -357,13 +336,6 @@
assert_eq!(POLL.load(), 1);
assert_eq!(SCHEDULE.load(), 1);
assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(chan.len(), 0);
-
- drop(handle);
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
assert_eq!(DROP_S.load(), 1);
assert_eq!(chan.len(), 0);
}
@@ -382,7 +354,7 @@
assert_eq!(DROP_S.load(), 0);
assert_eq!(chan.len(), 0);
- drop(handle);
+ handle.detach();
assert_eq!(POLL.load(), 1);
assert_eq!(SCHEDULE.load(), 1);
assert_eq!(DROP_F.load(), 0);
diff --git a/tests/waker_ready.rs b/tests/waker_ready.rs
index bf92960..b97425a 100644
--- a/tests/waker_ready.rs
+++ b/tests/waker_ready.rs
@@ -109,7 +109,8 @@
fn wake() {
future!(f, waker, POLL, DROP_F);
schedule!(s, chan, SCHEDULE, DROP_S);
- let (mut task, _) = async_task::spawn(f, s);
+ let (mut task, handle) = async_task::spawn(f, s);
+ handle.detach();
assert!(chan.is_empty());
@@ -147,7 +148,8 @@
fn wake_by_ref() {
future!(f, waker, POLL, DROP_F);
schedule!(s, chan, SCHEDULE, DROP_S);
- let (mut task, _) = async_task::spawn(f, s);
+ let (mut task, handle) = async_task::spawn(f, s);
+ handle.detach();
assert!(chan.is_empty());
@@ -185,7 +187,8 @@
fn clone() {
future!(f, waker, POLL, DROP_F);
schedule!(s, chan, SCHEDULE, DROP_S);
- let (mut task, _) = async_task::spawn(f, s);
+ let (mut task, handle) = async_task::spawn(f, s);
+ handle.detach();
task.run();
assert_eq!(POLL.load(), 1);
@@ -220,10 +223,11 @@
}
#[test]
-fn wake_canceled() {
+fn wake_dropped() {
future!(f, waker, POLL, DROP_F);
schedule!(s, chan, SCHEDULE, DROP_S);
- let (task, _) = async_task::spawn(f, s);
+ let (task, handle) = async_task::spawn(f, s);
+ handle.detach();
task.run();
assert_eq!(POLL.load(), 1);
@@ -235,7 +239,7 @@
let w = waker();
w.wake_by_ref();
- chan.recv().unwrap().cancel();
+ drop(chan.recv().unwrap());
assert_eq!(POLL.load(), 1);
assert_eq!(SCHEDULE.load(), 1);
assert_eq!(DROP_F.load(), 1);
@@ -254,7 +258,8 @@
fn wake_completed() {
future!(f, waker, POLL, DROP_F);
schedule!(s, chan, SCHEDULE, DROP_S);
- let (task, _) = async_task::spawn(f, s);
+ let (task, handle) = async_task::spawn(f, s);
+ handle.detach();
task.run();
let w = waker();