-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
implement try_join_next #6280
implement try_join_next #6280
Changes from 5 commits
f20d21b
12ca484
f575b0c
a59de4a
e3ab761
350a787
bc28eb2
92a835b
fc679bb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,7 +12,7 @@ use std::task::{Context, Poll}; | |
use crate::runtime::Handle; | ||
#[cfg(tokio_unstable)] | ||
use crate::task::Id; | ||
use crate::task::{AbortHandle, JoinError, JoinHandle, LocalSet}; | ||
use crate::task::{unconstrained, AbortHandle, JoinError, JoinHandle, LocalSet}; | ||
use crate::util::IdleNotifiedSet; | ||
|
||
/// A collection of tasks spawned on a Tokio runtime. | ||
|
@@ -306,6 +306,31 @@ impl<T: 'static> JoinSet<T> { | |
crate::future::poll_fn(|cx| self.poll_join_next_with_id(cx)).await | ||
} | ||
|
||
/// Tries to join one of the tasks in the set that has completed and return its output. | ||
/// | ||
/// Returns `None` if the set is empty. | ||
pub fn try_join_next(&mut self) -> Option<Result<T, JoinError>> { | ||
// Loop over all notified `JoinHandle`s to find one that's ready, or until none are left. | ||
loop { | ||
let mut entry = self.inner.try_pop_notified()?; | ||
|
||
let res = entry.with_value_and_context(|jh, ctx| { | ||
// Since this function is not async and cannot be forced to yield, we should | ||
// disable budgeting when we want to check for the `JoinHandle` readiness. | ||
let fut = unconstrained(jh); | ||
pin!(fut); | ||
|
||
fut.poll(ctx) | ||
}); | ||
|
||
if let Poll::Ready(res) = res { | ||
let _entry = entry.remove(); | ||
|
||
return Some(res); | ||
} | ||
Comment on lines
+323
to
+327
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a comment about why you go around the loop when it returns There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. // Loop over all notified `JoinHandle`s to find one that's ready, or until none are left. I've added this comment at the top of the function to explain why the loop exists. Is it too concise? |
||
} | ||
} | ||
|
||
/// Aborts all tasks and waits for them to finish shutting down. | ||
/// | ||
/// Calling this method is equivalent to calling [`abort_all`] and then calling [`join_next`] in | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The test is nice. Especially the fact that you cover the case with coop budgeting. You don't have any tests that handle the case where it returns None even though there are tasks, because all the tasks are still running. Could you do that? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this will work: