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

Context switching can affect timer triggering #4859

Closed
mapogolions opened this issue Jan 6, 2024 · 0 comments · Fixed by #4861
Closed

Context switching can affect timer triggering #4859

mapogolions opened this issue Jan 6, 2024 · 0 comments · Fixed by #4861
Labels
bug This issue describes a behavior which is not expected - a bug.

Comments

@mapogolions
Copy link
Contributor

Description

There is a possibility that a registered timer callback will never be called, and this can happen if context switching between threads occurs in a certain way.

Reproduction Steps

Please use the following snippet to reproduce the problem.

DateTimeOffset now = new(2000, 1, 1, 0, 0, 0, 0, TimeSpan.Zero);
var provider = new FakeTimeProvider(now) { AutoAdvanceAmount = TimeSpan.FromSeconds(2) };
using var timer = provider.CreateTimer(
    callback: Console.WriteLine,
    state: "waiter-1",
    dueTime: TimeSpan.FromSeconds(3),
    period: TimeSpan.Zero);

var threads = Enumerable.Range(start: 0, count: 5)
    .Select(x => new Thread(() =>
    {
        if (x != 0) Thread.Sleep(TimeSpan.FromMilliseconds(400));
        provider.GetUtcNow();
    }))
    .ToList();
threads.ForEach(t => t.Start());
threads.ForEach(t => t.Join());
Console.WriteLine(provider); // Print `_now` to confirm that 10 seconds have passed

Important: Please add some kind of delay to the FakeTimeProvider before the following line of code to emulate context switching.

Thread.Sleep(TimeSpan.FromSeconds(2));
if (candidate == null)
{
    // didn't find a candidate to wake, we're done
    _wakeWaitersGate = 0;
    return;
}

Expected behavior

The timer callback should be triggered, and the message 'waiter-1' should be printed to the console.

Actual behavior

Despite making 5 calls to advance the clock by 10 seconds, the timer callback has not been called.

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response

@mapogolions mapogolions added bug This issue describes a behavior which is not expected - a bug. untriaged labels Jan 6, 2024
@ghost ghost added the work in progress 🚧 label Jan 6, 2024
@mapogolions mapogolions changed the title Context switching may affect timer triggering Context switching can affect timer triggering Jan 8, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Feb 9, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug This issue describes a behavior which is not expected - a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant