From 75dd3d7654df227a472a22bbfaf00cda0f8a034d Mon Sep 17 00:00:00 2001 From: name1e5s Date: Sat, 21 May 2022 20:01:56 +0800 Subject: [PATCH 1/7] chore(runtime): add `is_finished` method for `JoinHandle` and `AbortHandle` --- tokio/src/runtime/task/abort.rs | 16 ++++++++++++++++ tokio/src/runtime/task/join.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/tokio/src/runtime/task/abort.rs b/tokio/src/runtime/task/abort.rs index 4977377880d..4076e98ba59 100644 --- a/tokio/src/runtime/task/abort.rs +++ b/tokio/src/runtime/task/abort.rs @@ -49,6 +49,22 @@ impl AbortHandle { } } + /// Checks if the task associated with the handle has finished(whether completed or cancelled). + /// Like [`JoinHandle::is_finished`] this function does not block. + /// Once this returns true, the task is expected to finish quickly, + /// without blocking for any significant amount of time. + /// + /// [`JoinHandle::is_finished`]: method@super::JoinHandle::is_finished + #[cfg_attr(not(tokio_unstable), allow(unreachable_pub))] + pub fn is_finished(&self) -> bool { + if let Some(raw) = self.raw { + let state = raw.header().state.load(); + state.is_complete() || state.is_cancelled() + } else { + true + } + } + /// Returns a [task ID] that uniquely identifies this task relative to other /// currently spawned tasks. /// diff --git a/tokio/src/runtime/task/join.rs b/tokio/src/runtime/task/join.rs index 86580c84b59..0b0cfce558a 100644 --- a/tokio/src/runtime/task/join.rs +++ b/tokio/src/runtime/task/join.rs @@ -203,6 +203,38 @@ impl JoinHandle { } } + /// Checks if the task associated with the handle has finished(whether completed or cancelled). + /// This function does not block. Once this returns true, the task is expected + /// to finish quickly, without blocking for any significant amount of time. + /// + /// ```rust + /// use tokio::time; + /// + /// #[tokio::main] + /// async fn main() { + /// let handle1 = tokio::spawn(async { + /// // do some stuff here + /// }); + /// let handle2 = tokio::spawn(async { + /// // do some other stuff here + /// time::sleep(time::Duration::from_secs(10)).await; + /// }); + /// // Wait for the task to finish + /// time::sleep(time::Duration::from_secs(1)).await; + /// assert!(handle1.is_finished()); + /// handle2.abort(); + /// assert!(handle2.is_finished()); + /// } + /// ``` + pub fn is_finished(&self) -> bool { + if let Some(raw) = self.raw { + let state = raw.header().state.load(); + state.is_complete() || state.is_cancelled() + } else { + true + } + } + /// Set the waker that is notified when the task completes. pub(crate) fn set_join_waker(&mut self, waker: &Waker) { if let Some(raw) = self.raw { From dd8c93e8a5a5cab8cea4694f538678de9fb7891a Mon Sep 17 00:00:00 2001 From: name1e5s Date: Sat, 21 May 2022 21:45:19 +0800 Subject: [PATCH 2/7] check is_complete only --- tokio/src/runtime/task/abort.rs | 6 ++---- tokio/src/runtime/task/join.rs | 5 ++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/tokio/src/runtime/task/abort.rs b/tokio/src/runtime/task/abort.rs index 4076e98ba59..3a0018e0b91 100644 --- a/tokio/src/runtime/task/abort.rs +++ b/tokio/src/runtime/task/abort.rs @@ -50,16 +50,14 @@ impl AbortHandle { } /// Checks if the task associated with the handle has finished(whether completed or cancelled). - /// Like [`JoinHandle::is_finished`] this function does not block. - /// Once this returns true, the task is expected to finish quickly, - /// without blocking for any significant amount of time. + /// Like [`JoinHandle::is_finished`], this function does not block. /// /// [`JoinHandle::is_finished`]: method@super::JoinHandle::is_finished #[cfg_attr(not(tokio_unstable), allow(unreachable_pub))] pub fn is_finished(&self) -> bool { if let Some(raw) = self.raw { let state = raw.header().state.load(); - state.is_complete() || state.is_cancelled() + state.is_complete() } else { true } diff --git a/tokio/src/runtime/task/join.rs b/tokio/src/runtime/task/join.rs index 0b0cfce558a..b5f296c9ff6 100644 --- a/tokio/src/runtime/task/join.rs +++ b/tokio/src/runtime/task/join.rs @@ -204,8 +204,7 @@ impl JoinHandle { } /// Checks if the task associated with the handle has finished(whether completed or cancelled). - /// This function does not block. Once this returns true, the task is expected - /// to finish quickly, without blocking for any significant amount of time. + /// This function does not block. /// /// ```rust /// use tokio::time; @@ -229,7 +228,7 @@ impl JoinHandle { pub fn is_finished(&self) -> bool { if let Some(raw) = self.raw { let state = raw.header().state.load(); - state.is_complete() || state.is_cancelled() + state.is_complete() } else { true } From f103c162bf10e896f9b59537759cad6aeb97243c Mon Sep 17 00:00:00 2001 From: name1e5s Date: Sat, 21 May 2022 22:06:23 +0800 Subject: [PATCH 3/7] fix test --- tokio/src/runtime/task/join.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tokio/src/runtime/task/join.rs b/tokio/src/runtime/task/join.rs index b5f296c9ff6..2a001a9c336 100644 --- a/tokio/src/runtime/task/join.rs +++ b/tokio/src/runtime/task/join.rs @@ -219,9 +219,9 @@ impl JoinHandle { /// time::sleep(time::Duration::from_secs(10)).await; /// }); /// // Wait for the task to finish + /// handle2.abort(); /// time::sleep(time::Duration::from_secs(1)).await; /// assert!(handle1.is_finished()); - /// handle2.abort(); /// assert!(handle2.is_finished()); /// } /// ``` From db9ec1fff08a7a7347fd48560e1bdaab78bf94b9 Mon Sep 17 00:00:00 2001 From: name1e5s Date: Sat, 21 May 2022 23:37:58 +0800 Subject: [PATCH 4/7] doc the cancellation behavior --- tokio/src/runtime/task/abort.rs | 5 +++++ tokio/src/runtime/task/join.rs | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/tokio/src/runtime/task/abort.rs b/tokio/src/runtime/task/abort.rs index 3a0018e0b91..8be83f06e88 100644 --- a/tokio/src/runtime/task/abort.rs +++ b/tokio/src/runtime/task/abort.rs @@ -52,6 +52,11 @@ impl AbortHandle { /// Checks if the task associated with the handle has finished(whether completed or cancelled). /// Like [`JoinHandle::is_finished`], this function does not block. /// + /// # Notes + /// + /// Cancelling a task may need some time to take effect. This function only returns true + /// when the task has completed the cancellation process. + /// /// [`JoinHandle::is_finished`]: method@super::JoinHandle::is_finished #[cfg_attr(not(tokio_unstable), allow(unreachable_pub))] pub fn is_finished(&self) -> bool { diff --git a/tokio/src/runtime/task/join.rs b/tokio/src/runtime/task/join.rs index 2a001a9c336..0f42921e08c 100644 --- a/tokio/src/runtime/task/join.rs +++ b/tokio/src/runtime/task/join.rs @@ -206,11 +206,17 @@ impl JoinHandle { /// Checks if the task associated with the handle has finished(whether completed or cancelled). /// This function does not block. /// + /// # Notes + /// + /// Cancelling a task may need some time to take effect. This function only returns true + /// when the task has completed the cancellation process. + /// /// ```rust /// use tokio::time; /// - /// #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// async fn main() { + /// # time::pause(); /// let handle1 = tokio::spawn(async { /// // do some stuff here /// }); From dad821e04afdcd766316d32ef6fa69968ebb8bb9 Mon Sep 17 00:00:00 2001 From: name1e5s Date: Sun, 22 May 2022 01:28:58 +0800 Subject: [PATCH 5/7] better doc --- tokio/src/runtime/task/abort.rs | 13 +++++-------- tokio/src/runtime/task/join.rs | 12 ++++++------ 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/tokio/src/runtime/task/abort.rs b/tokio/src/runtime/task/abort.rs index 8be83f06e88..6c96f607d9b 100644 --- a/tokio/src/runtime/task/abort.rs +++ b/tokio/src/runtime/task/abort.rs @@ -49,15 +49,12 @@ impl AbortHandle { } } - /// Checks if the task associated with the handle has finished(whether completed or cancelled). - /// Like [`JoinHandle::is_finished`], this function does not block. + /// Checks if the task associated with this `JoinHandle` has finished. /// - /// # Notes - /// - /// Cancelling a task may need some time to take effect. This function only returns true - /// when the task has completed the cancellation process. - /// - /// [`JoinHandle::is_finished`]: method@super::JoinHandle::is_finished + /// Please note that this method can return `false` even if `abort` has been + /// called on the task. This is because the cancellation process may take + /// some time, and this method does not return `true` until it has + /// completed. #[cfg_attr(not(tokio_unstable), allow(unreachable_pub))] pub fn is_finished(&self) -> bool { if let Some(raw) = self.raw { diff --git a/tokio/src/runtime/task/join.rs b/tokio/src/runtime/task/join.rs index 0f42921e08c..077974a6a1e 100644 --- a/tokio/src/runtime/task/join.rs +++ b/tokio/src/runtime/task/join.rs @@ -203,13 +203,12 @@ impl JoinHandle { } } - /// Checks if the task associated with the handle has finished(whether completed or cancelled). - /// This function does not block. + /// Checks if the task associated with this `JoinHandle` has finished. /// - /// # Notes - /// - /// Cancelling a task may need some time to take effect. This function only returns true - /// when the task has completed the cancellation process. + /// Please note that this method can return `false` even if `abort` has been + /// called on the task. This is because the cancellation process may take + /// some time, and this method does not return `true` until it has + /// completed. /// /// ```rust /// use tokio::time; @@ -231,6 +230,7 @@ impl JoinHandle { /// assert!(handle2.is_finished()); /// } /// ``` + /// [`abort`]: method@JoinHandle::abort pub fn is_finished(&self) -> bool { if let Some(raw) = self.raw { let state = raw.header().state.load(); From 87c15737de6ab60c39a9fea89c1ec4d4bb745276 Mon Sep 17 00:00:00 2001 From: name1e5s Date: Sun, 22 May 2022 20:50:03 +0800 Subject: [PATCH 6/7] update doc --- tokio/src/runtime/task/abort.rs | 2 +- tokio/src/runtime/task/join.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tokio/src/runtime/task/abort.rs b/tokio/src/runtime/task/abort.rs index 6c96f607d9b..3188394a8ea 100644 --- a/tokio/src/runtime/task/abort.rs +++ b/tokio/src/runtime/task/abort.rs @@ -49,7 +49,7 @@ impl AbortHandle { } } - /// Checks if the task associated with this `JoinHandle` has finished. + /// Checks if the task associated with this `AbortHandle` has finished. /// /// Please note that this method can return `false` even if `abort` has been /// called on the task. This is because the cancellation process may take diff --git a/tokio/src/runtime/task/join.rs b/tokio/src/runtime/task/join.rs index 077974a6a1e..2ef4728c940 100644 --- a/tokio/src/runtime/task/join.rs +++ b/tokio/src/runtime/task/join.rs @@ -205,7 +205,7 @@ impl JoinHandle { /// Checks if the task associated with this `JoinHandle` has finished. /// - /// Please note that this method can return `false` even if `abort` has been + /// Please note that this method can return `false` even if [`abort`] has been /// called on the task. This is because the cancellation process may take /// some time, and this method does not return `true` until it has /// completed. From 0b9e7458f1cc4930715dc9dd4c925d9f12f2a3da Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Tue, 31 May 2022 11:03:36 +0200 Subject: [PATCH 7/7] Update tokio/src/runtime/task/join.rs --- tokio/src/runtime/task/join.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tokio/src/runtime/task/join.rs b/tokio/src/runtime/task/join.rs index 2ef4728c940..a04ec956a56 100644 --- a/tokio/src/runtime/task/join.rs +++ b/tokio/src/runtime/task/join.rs @@ -214,21 +214,21 @@ impl JoinHandle { /// use tokio::time; /// /// # #[tokio::main(flavor = "current_thread")] - /// async fn main() { - /// # time::pause(); - /// let handle1 = tokio::spawn(async { - /// // do some stuff here - /// }); - /// let handle2 = tokio::spawn(async { - /// // do some other stuff here - /// time::sleep(time::Duration::from_secs(10)).await; - /// }); - /// // Wait for the task to finish - /// handle2.abort(); - /// time::sleep(time::Duration::from_secs(1)).await; - /// assert!(handle1.is_finished()); - /// assert!(handle2.is_finished()); - /// } + /// # async fn main() { + /// # time::pause(); + /// let handle1 = tokio::spawn(async { + /// // do some stuff here + /// }); + /// let handle2 = tokio::spawn(async { + /// // do some other stuff here + /// time::sleep(time::Duration::from_secs(10)).await; + /// }); + /// // Wait for the task to finish + /// handle2.abort(); + /// time::sleep(time::Duration::from_secs(1)).await; + /// assert!(handle1.is_finished()); + /// assert!(handle2.is_finished()); + /// # } /// ``` /// [`abort`]: method@JoinHandle::abort pub fn is_finished(&self) -> bool {