Skip to content

Commit

Permalink
RavenDB-21888 Make sure the timer callback won't start before we assi…
Browse files Browse the repository at this point in the history
…gn the timer instance to internal state. Catch and ignore exceptions on the timer disposal in the callback.
  • Loading branch information
arekpalinski committed Jan 8, 2024
1 parent 84ca565 commit d5517af
Showing 1 changed file with 36 additions and 8 deletions.
44 changes: 36 additions & 8 deletions src/Raven.Client/Util/WeakReferencingTimer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,13 @@ public WeakReferencingTimer(WeakReferencingTimerCallback callback, object state,
Callback = new WeakReference<WeakReferencingTimerCallback>(callback)
};

_timer = new Timer(StaticCallback, internalTimerState, dueTime, period);
const uint infinite = unchecked((uint)-1); // register the timer but do not activate it yet

internalTimerState.Timer = _timer;
_timer = new Timer(StaticCallback, internalTimerState, infinite, infinite);

internalTimerState.Timer = _timer; // assign timer instance to the state

_timer.Change(dueTime, period); // now let's activate the timer
}

private static void StaticCallback(object state)
Expand All @@ -32,13 +36,37 @@ private static void StaticCallback(object state)

if (timerState.State is not null && timerState.State.TryGetTarget(out stateObj) == false)
{
timerState.Timer.Dispose();
try
{
timerState.Timer.Dispose();
}
#pragma warning disable CS0168
catch (Exception e)
#pragma warning restore CS0168
{
#if DEBUG
Console.WriteLine($"Disposal of timer instance got an exception:{Environment.NewLine}{e}");
#endif
// ignored
}
return;
}

if (timerState.Callback.TryGetTarget(out var callback) == false)
{
timerState.Timer.Dispose();
try
{
timerState.Timer.Dispose();
}
#pragma warning disable CS0168
catch (Exception e)
#pragma warning restore CS0168
{
#if DEBUG
Console.WriteLine($"Disposal of timer instance got an exception:{Environment.NewLine}{e}");
#endif
// ignored
}
return;
}

Expand All @@ -52,13 +80,13 @@ private class TimerState
public Timer Timer;
}

public void Dispose()
public void Change(TimeSpan dueTime, TimeSpan period)
{
_timer?.Dispose();
_timer?.Change(dueTime, period);
}

public void Change(TimeSpan dueTime, TimeSpan period)
public void Dispose()
{
_timer?.Change(dueTime, period);
_timer?.Dispose();
}
}

0 comments on commit d5517af

Please sign in to comment.