From ee3884fe1d712eb8597e4fea069ea76186ef8d78 Mon Sep 17 00:00:00 2001 From: Thomas Nind Date: Fri, 29 Apr 2022 10:01:12 +0100 Subject: [PATCH] Adjusted lock so it does not cover the timeout Callback --- Terminal.Gui/Core/MainLoop.cs | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/Terminal.Gui/Core/MainLoop.cs b/Terminal.Gui/Core/MainLoop.cs index 4fcdf2e8d..7c4076eec 100644 --- a/Terminal.Gui/Core/MainLoop.cs +++ b/Terminal.Gui/Core/MainLoop.cs @@ -171,23 +171,31 @@ namespace Terminal.Gui { void RunTimers () { - lock (timeoutsLockToken) { - long now = DateTime.UtcNow.Ticks; + long now = DateTime.UtcNow.Ticks; + SortedList copy; - var copy = timeouts; + // lock prevents new timeouts being added + // after we have taken the copy but before + // we have allocated a new list (which would + // result in lost timeouts or errors during enumeration) + lock (timeoutsLockToken) { + copy = timeouts; timeouts = new SortedList (); - foreach (var t in copy) { - var k = t.Key; - var timeout = t.Value; - if (k < now) { - if (timeout.Callback (this)) - AddTimeout (timeout.Span, timeout); - } else { - timeouts.Add (k, timeout); - + } + + foreach (var t in copy) { + var k = t.Key; + var timeout = t.Value; + if (k < now) { + if (timeout.Callback (this)) + AddTimeout (timeout.Span, timeout); + } else { + lock (timeoutsLockToken) { + timeouts.Add (k, timeout); } } } + } void RunIdle ()