浏览代码

Adjusted lock so it does not cover the timeout Callback

Thomas Nind 3 年之前
父节点
当前提交
ee3884fe1d
共有 1 个文件被更改,包括 20 次插入12 次删除
  1. 20 12
      Terminal.Gui/Core/MainLoop.cs

+ 20 - 12
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<long, Timeout> 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<long, 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 {
-							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 ()