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

Fix UB in cancelled tasks #578

Merged
merged 2 commits into from
Oct 25, 2023
Merged

Fix UB in cancelled tasks #578

merged 2 commits into from
Oct 25, 2023

Conversation

ispeters
Copy link
Contributor

This diff fixes #577 by remembering which continuation would have been resumed if the deferred stop request had completed first. Later, when the deferred stop request completes, resume the remembered continuation (which might be unhandled_done()) instead of uncondtionally resuming the primary continuation.

This diff fixes #577 by remembering which continuation _would_ have been
resumed if the deferred stop request had completed first. Later, when
the deferred stop request completes, resume the remembered continuation
(which might be `unhandled_done()`) instead of uncondtionally resuming
the primary continuation.
@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 25, 2023
@ispeters ispeters requested a review from janondrusek October 25, 2023 16:45
@ispeters ispeters merged commit cd8b3a6 into main Oct 25, 2023
93 checks passed
@ispeters ispeters deleted the fix_ub_in_cancelled_tasks branch October 25, 2023 16:56
ispeters added a commit that referenced this pull request Oct 26, 2023
As reported in #577, #578 didn't fix the UB in cancelled tasks. There
were two bugs in that "fix":
 1. we were writing the coroutine handle to resume *after*
    synchronizing between the two racing operation states, leading to a
    data race when the deferred stop source completed second; and
 2. it's wrong to call `continuation_.done()` to store the coroutine
    handle to be resumed later because `done()` completes the operation
    with `set_done()` as a side effect.

This diff fixes both issues. Instead of storing a coroutine handle to be
resumed, we store an enum value that describes which coroutine handle to
resume (so we don't eagerly invoke `done()`), and we do the store before
synchronizing to eliminate the data race.

I've added a unit test that fails with a TSAN-detected data race without
the fix, and the fix silences the TSAN error.

I also clang-formatted `task.hpp` and the modified test file.
ispeters added a commit that referenced this pull request Oct 27, 2023
As reported in #577, #578 didn't fix the UB in cancelled tasks. There
were two bugs in that "fix":
 1. we were writing the coroutine handle to resume *after*
    synchronizing between the two racing operation states, leading to a
    data race when the deferred stop source completed second; and
 2. it's wrong to call `continuation_.done()` to store the coroutine
    handle to be resumed later because `done()` completes the operation
    with `set_done()` as a side effect.

This diff fixes both issues. Instead of storing a coroutine handle to be
resumed, we store an enum value that describes which coroutine handle to
resume (so we don't eagerly invoke `done()`), and we do the store before
synchronizing to eliminate the data race.

I've added a unit test that fails with a TSAN-detected data race without
the fix, and the fix silences the TSAN error.

I also clang-formatted `task.hpp` and the modified test file.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

task resumes after being cancelled causing UB
3 participants