Skip to content
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

Prevent basic_scheduler from panicking if a task is aborted from another thread #3672

Merged
merged 4 commits into from
Apr 8, 2021

Conversation

udoprog
Copy link
Contributor

@udoprog udoprog commented Apr 4, 2021

Motivation

This purports to fix the bug reported in #3662

Solution

The first commit simply ignores that the context is missing. What happens then (to the best of my understanding) is that the task header stays linked in the scheduler until the the scheduler is dropped. Any future polls of the task will simply never reach the scheduler, but be stopped by the harness and report the cancellation since it's already aware of the task state.

That leads us to the second commit, where I try to add a mechanism for remotely notifying the scheduler to remove the linked task. This is similar to how tokio::spawn notifies the thread about new tasks if run from a different thread (as it would if used from inside a tokio::spawn_blocking). This should result in the task eventually being cleaned under one of the following circumstances:

  • Immediately by the current thread being unparked and has nothing else to do.
  • The thread is woken, but the task it's waiting for is also ready. Then the task won't be cleaned up until the scheduler is waiting for some other task being blocked on to report Poll::Pending.
  • Ultimately if the scheduler is dropped like before.

The sketchy part here is that the shared task header is being sent from the thread releasing the task. Which should be fine in principle but it's a bit messy.

This is the first time I'm fiddling w/ basic_scheduler. So please pay close attention to if I've misunderstood something!

@Darksonn Darksonn added A-tokio Area: The main tokio crate M-task Module: tokio/task labels Apr 4, 2021
Copy link
Contributor

@Darksonn Darksonn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any problems in the implementation, but it would be nice with another set of eyes.

tokio/tests/task_abort.rs Outdated Show resolved Hide resolved
tokio/tests/task_abort.rs Show resolved Hide resolved
tokio/tests/task_abort.rs Outdated Show resolved Hide resolved
Comment on lines +64 to +71
// This runs in a separate thread so it doesn't have immediate
// thread-local access to the executor. It does however transition
// the underlying task to be completed, which will cause it to be
// dropped (in this thread no less).
assert!(!drop_flag2.load(Ordering::SeqCst));
j.abort();
// TODO: is this guaranteed at this point?
// assert!(drop_flag2.load(Ordering::SeqCst));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well if the task's destructor runs in this thread, it would be, but it's unclear to me that the destructor would necessarily run here.

tokio/tests/task_abort.rs Outdated Show resolved Hide resolved
Co-authored-by: Alice Ryhl <alice@ryhl.io>
@udoprog
Copy link
Contributor Author

udoprog commented Apr 4, 2021

@Darksonn great suggestions. Thanks for taking a look!

@udoprog
Copy link
Contributor Author

udoprog commented Apr 4, 2021

Hm, std::future::pending is outside of MSRV (https://github.com/tokio-rs/tokio/pull/3672/checks?check_run_id=2265253675#step:5:190). I'll revert it.

@Darksonn
Copy link
Contributor

Darksonn commented Apr 4, 2021

Ah, I thought tests were outside of MSRV, but clippy is still on MSRV, so.

Copy link
Member

@carllerche carllerche left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, it looks a lot like how the multi-threaded scheduler handles this.

@carllerche
Copy link
Member

I pinged the original issue author to see if they could verify the fix, but looks good to me. Thanks all ❤️

@carllerche carllerche merged commit 1a72b28 into tokio-rs:master Apr 8, 2021
@udoprog udoprog deleted the issue-3662 branch April 8, 2021 20:54
@Darksonn Darksonn mentioned this pull request Apr 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio Area: The main tokio crate M-task Module: tokio/task
Projects
None yet
Development

Successfully merging this pull request may close these issues.

JoinHandle::abort() panics with "scheduler context missing" when using basic scheduler
3 participants