Skip to content

Avoid ScheduledTask timer lock inversion - #1119

Merged
joshuay03 merged 2 commits into
ruby-concurrency:masterfrom
ac1982:fix/scheduled-task-lock-inversion
Oct 16, 2026
Merged

joshuay03 merged 2 commits into
ruby-concurrency:masterfrom
ac1982:fix/scheduled-task-lock-inversion

Conversation

@ac1982

@ac1982 ac1982 commented Oct 10, 2026

Copy link
Copy Markdown
Contributor

Fixes #1099.

ScheduledTask#reschedule and #reset acquire the task lock before entering TimerSet. Queue comparisons acquire the timer lock before calling schedule_time, which currently takes the task lock. These opposite orders can deadlock.

Use the library's existing attr_volatile for the schedule time, following the direction discussed by @snickell and @eregon in the issue. All reads/writes use its generated accessors, and the writer stays private. This removes the task-lock acquisition from queue comparisons while preserving the library's cross-interpreter visibility mechanism.

Two latch-coordinated regressions force the conflicting lock order for reset and reschedule. Both time out on master and pass with the change; they also check that the task stays pending with its updated delay and schedule time. Update the changelog as requested by the contribution guide.

Validation on CRuby 3.3.8 / Linux arm64:

  • Regression before fix: 2 examples, 2 failures; after fix: 2 examples, 0 failures.
  • ScheduledTask + TimerSet specs: 113 examples, 0 failures.
  • bundle exec rake (including native C-extension build): 2,802 examples, 0 failures, 16 pending.
  • git diff --check passed.

JRuby, TruffleRuby, Windows, and other CRuby versions were not run locally. Optional YARD documentation tasks were unavailable because YARD was not installed. AI assistance: OpenAI Codex investigated, implemented, and ran the checks above.

ac1982 and others added 2 commits October 10, 2026 14:47
Signed-off-by: AC <ac@fabtek.cn>
Keep the schedule_time rationale out of its YARD docstring, and drop the
CHANGELOG entry since release notes are generated from pull requests.
@joshuay03
joshuay03 force-pushed the fix/scheduled-task-lock-inversion branch from 0e113ce to bb92326 Compare October 16, 2026 23:08

@joshuay03 joshuay03 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks!

@joshuay03
joshuay03 merged commit 25c8cd1 into ruby-concurrency:master Oct 16, 2026
16 of 17 checks passed
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.

Deadlock race when calling ScheduledTask#reschedule

2 participants