Skip to content

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.

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.

@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