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
Immediately drop new task when runtime is shut down #3752
Merged
Merged
Changes from 2 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
f387080
task: add test for joining a JoinHandle after dropping the runtime
Darksonn 96bfefe
Fix test for basic_scheduler
Darksonn 688f83e
Try to fix multi-threaded runtime
Darksonn b5947a4
Use futures rather than std pending
Darksonn bac93e0
Merge 'upstream/master' into 'runtime-shutdown-join'
Darksonn 4725042
Add loom test
Darksonn 63e54c4
rustfmt
Darksonn 85d40b7
Fix loom test
Darksonn 0bc95a2
Add comments
Darksonn File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -84,13 +84,13 @@ unsafe impl Send for Entry {} | |
|
||
/// Scheduler state shared between threads. | ||
struct Shared { | ||
/// Remote run queue | ||
queue: Mutex<VecDeque<Entry>>, | ||
/// Remote run queue. None if the `Runtime` has been dropped. | ||
queue: Mutex<Option<VecDeque<Entry>>>, | ||
|
||
/// Unpark the blocked thread | ||
/// Unpark the blocked thread. | ||
unpark: Box<dyn Unpark>, | ||
|
||
// indicates whether the blocked on thread was woken | ||
/// Indicates whether the blocked on thread was woken. | ||
woken: AtomicBool, | ||
} | ||
|
||
|
@@ -124,7 +124,7 @@ impl<P: Park> BasicScheduler<P> { | |
|
||
let spawner = Spawner { | ||
shared: Arc::new(Shared { | ||
queue: Mutex::new(VecDeque::with_capacity(INITIAL_CAPACITY)), | ||
queue: Mutex::new(Some(VecDeque::with_capacity(INITIAL_CAPACITY))), | ||
unpark: unpark as Box<dyn Unpark>, | ||
woken: AtomicBool::new(false), | ||
}), | ||
|
@@ -352,17 +352,21 @@ impl<P: Park> Drop for BasicScheduler<P> { | |
} | ||
|
||
// Drain remote queue | ||
for entry in scheduler.spawner.shared.queue.lock().drain(..) { | ||
match entry { | ||
Entry::Schedule(task) => { | ||
task.shutdown(); | ||
} | ||
Entry::Release(..) => { | ||
// Do nothing, each entry in the linked list was *just* | ||
// dropped by the scheduler above. | ||
let mut remote_queue = scheduler.spawner.shared.queue.lock(); | ||
if let Some(remote_queue) = remote_queue.take() { | ||
for entry in remote_queue { | ||
match entry { | ||
Entry::Schedule(task) => { | ||
task.shutdown(); | ||
} | ||
Entry::Release(..) => { | ||
// Do nothing, each entry in the linked list was *just* | ||
// dropped by the scheduler above. | ||
} | ||
} | ||
} | ||
} | ||
drop(remote_queue); | ||
|
||
assert!(context.tasks.borrow().owned.is_empty()); | ||
}); | ||
|
@@ -390,7 +394,10 @@ impl Spawner { | |
} | ||
|
||
fn pop(&self) -> Option<Entry> { | ||
self.shared.queue.lock().pop_front() | ||
match self.shared.queue.lock().as_mut() { | ||
Some(queue) => queue.pop_front(), | ||
None => None, | ||
} | ||
} | ||
|
||
fn waker_ref(&self) -> WakerRef<'_> { | ||
|
@@ -429,7 +436,9 @@ impl Schedule for Arc<Shared> { | |
// safety: the task is inserted in the list in `bind`. | ||
unsafe { cx.tasks.borrow_mut().owned.remove(ptr) } | ||
} else { | ||
self.queue.lock().push_back(Entry::Release(ptr)); | ||
if let Some(queue) = self.queue.lock().as_mut() { | ||
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. So what happens if this is 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. After digging in, this looks fine, a comment explaining why would be nice. |
||
queue.push_back(Entry::Release(ptr)); | ||
} | ||
self.unpark.unpark(); | ||
// Returning `None` here prevents the task plumbing from being | ||
// freed. It is then up to the scheduler through the queue we | ||
|
@@ -445,8 +454,17 @@ impl Schedule for Arc<Shared> { | |
cx.tasks.borrow_mut().queue.push_back(task); | ||
} | ||
_ => { | ||
self.queue.lock().push_back(Entry::Schedule(task)); | ||
self.unpark.unpark(); | ||
let mut guard = self.queue.lock(); | ||
if let Some(queue) = guard.as_mut() { | ||
queue.push_back(Entry::Schedule(task)); | ||
drop(guard); | ||
self.unpark.unpark(); | ||
} else { | ||
// The runtime has shut down. We drop the new task | ||
// immediately. | ||
drop(guard); | ||
task.shutdown(); | ||
} | ||
} | ||
}); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
If the drop here is significant (which it probably is because this is a lock guard), it probably is worth adding a comment saying so to avoid removing it in the future by accident.
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.
Does the drop here in interact with the assert below?
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.
No, I only put it in to make it more visually clear where the lock is dropped.