Skip to content

When waiting on a task, escalate it before enqueuing the waiting task #59377

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

Merged

Conversation

rjmccall
Copy link
Contributor

As soon as the waiting task is successfully enqueued on the blocking task, both tasks have to be considered invalidated because the blocking task can concurrently complete and resume its waiters:

  • The waiting task ensures that the blocking task is valid while it's waiting. However, that's measured from the perspective of the waiting task, not from the perspective of the thread that was previously executing it. As soon as the waiting task is resumed, the wait call completes and the validity guarantee on the blocking task disappears, so the blocking task must be treated as invalidated.

  • The waiting task ensures that it is valid as long as it isn't complete. Since it's trying to wait, it must not be complete. However, as soon we resume it, it can complete, so the waiting task must also be treated as invalidated.

This is one of those things that's not really easy to test, and the need for a fix is pretty urgent, so I'm submitting this patch without a test. I'll try to land a race test that demonstrates the bug in the next few days.

@kavon deserves all the credit here for some truly heroic debugging and finally recognizing the flaw in the code; I'm just popping in at the last minute to sheepishly patch the bug.

Fixes rdar://92666987

As soon as the waiting task is successfully enqueued on the blocking
task, both tasks have to be considered invalidated because the
blocking task can concurrently complete and resume its waiters:

- The waiting task ensures that the blocking task is valid while
  it's waiting.  However, that's measured from the perspective of
  the waiting task, not from the perspective of the thread that was
  previously executing it.  As soon as the waiting task is resumed,
  the wait call completes and the validity guarantee on the blocking
  task disappears, so the blocking task must be treated as
  invalidated.

- The waiting task ensures that it is valid as long as it isn't
  complete.  Since it's trying to wait, it must not be complete.
  However, as soon we resume it, it can complete, so the waiting
  task must also be treated as invalidated.

This is one of those things that's not really easy to test, and the
need for a fix is pretty urgent, so I'm submitting this patch without
a test.  I'll try to land a race test that demonstrates the bug in
the next few days.

@kavon deserves all the credit here for some truly heroic debugging
and finally recognizing the flaw in the code; I'm just popping in
at the last minute to sheepishly patch the bug.

Fixes rdar://92666987
@rjmccall rjmccall requested review from kavon and rokhinip June 11, 2022 04:03
@rjmccall
Copy link
Contributor Author

@swift-ci Please test

@rjmccall rjmccall merged commit 54f6516 into swiftlang:main Jun 11, 2022
@rjmccall rjmccall deleted the escalate-task-before-wait-enqueueing branch June 11, 2022 19:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant