Skip to content

Fix kqueue timer duration calculation#16581

Merged
ysbaddaden merged 2 commits intocrystal-lang:masterfrom
skuznetsov:fix/kqueue-timer-duration
Jan 19, 2026
Merged

Fix kqueue timer duration calculation#16581
ysbaddaden merged 2 commits intocrystal-lang:masterfrom
skuznetsov:fix/kqueue-timer-duration

Conversation

@skuznetsov
Copy link
Contributor

Fix

The timer duration was calculated incorrectly in commit 5bf7b19 (#16498), causing all timers to fire immediately instead of waiting.

Bug:

t = Crystal::System::Time.instant.duration_since(time)
# = (now - future).clamp(0) = 0 when time is in the future

Fix:

t = time.duration_since(Crystal::System::Time.instant)
# = (future - now).clamp(0) = remaining time until timer fires

Impact

This caused 100% CPU usage on macOS as the event loop would spin instead of blocking on kqueue. Every Crystal application on macOS is affected.

Testing

Added regression test to verify sleep actually takes time.

Fixes #16578

The timer duration was calculated incorrectly in commit 5bf7b19,
causing all timers to fire immediately instead of waiting.

The bug was:
```crystal
t = Crystal::System::Time.instant.duration_since(time)
# = (now - future).clamp(0) = 0 when time is in the future
```

Fixed to:
```crystal
t = time.duration_since(Crystal::System::Time.instant)
# = (future - now).clamp(0) = remaining time until timer fires
```

This caused 100% CPU usage on macOS as the event loop would spin
instead of blocking on kqueue.

Added regression test to verify sleep actually takes time.

Fixes crystal-lang#16578
@Blacksmoke16 Blacksmoke16 added topic:stdlib:concurrency platform:darwin kind:regression Something that used to correctly work but no longer works labels Jan 18, 2026
@skuznetsov
Copy link
Contributor Author

@ysbaddaden do you mind to look and approve?

@Sija
Copy link
Contributor

Sija commented Jan 18, 2026

We need 1.19.1 ASAP

Co-authored-by: Johannes Müller <straightshoota@gmail.com>
@ysbaddaden
Copy link
Collaborator

Reproduced on FreeBSD. The issue is fixed 👍

@ysbaddaden ysbaddaden added this to the 1.19.1 milestone Jan 19, 2026
@ysbaddaden ysbaddaden merged commit 7dff995 into crystal-lang:master Jan 19, 2026
42 checks passed
ysbaddaden pushed a commit that referenced this pull request Jan 20, 2026
The timer duration was calculated incorrectly in commit 5bf7b19,
causing all timers to fire immediately instead of waiting. This caused
100% CPU usage on macOS as the event loop would spin instead of
blocking on kqueue.

Added regression test to verify sleep actually takes time.

Co-authored-by: Sergey Kuznetsov <sergey@iterudit.com>
@straight-shoota straight-shoota added kind:bug A bug in the code. Does not apply to documentation, specs, etc. backport release/1.19 labels Jan 20, 2026
@crysbot
Copy link
Collaborator

crysbot commented Jan 20, 2026

Git push to origin failed for release/1.19 with exitcode 128

ysbaddaden pushed a commit to ysbaddaden/crystal that referenced this pull request Jan 20, 2026
The timer duration was calculated incorrectly in commit 5bf7b19,
causing all timers to fire immediately instead of waiting. This caused
100% CPU usage on macOS as the event loop would spin instead of
blocking on kqueue.

Added regression test to verify sleep actually takes time.

Co-authored-by: Sergey Kuznetsov <sergey@iterudit.com>
ysbaddaden pushed a commit that referenced this pull request Jan 20, 2026
The timer duration was calculated incorrectly in commit 5bf7b19,
causing all timers to fire immediately instead of waiting. This caused
100% CPU usage on macOS as the event loop would spin instead of
blocking on kqueue.

Added regression test to verify sleep actually takes time.

Co-authored-by: Sergey Kuznetsov <sergey@iterudit.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport release/1.19 kind:bug A bug in the code. Does not apply to documentation, specs, etc. kind:regression Something that used to correctly work but no longer works platform:bsd platform:darwin topic:stdlib:concurrency

Projects

None yet

6 participants