Skip to content

Commit 80746af

Browse files
committed
AsyncSignal: Fix bug where work items weren't being properly reset
This caused them to throw "Dequeued work item somehow completed in back queue"
1 parent f0fbdde commit 80746af

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

src/CoroutineScheduler/AsyncSignal.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,17 @@ public void Invoke()
7171

7272
internal class RegisteredWorkItem
7373
{
74-
public WorkItem Item { get; set; }
74+
public WorkItem Item { get; private set; }
7575
public CancellationTokenRegistration CancellationTokenRegistration { get; set; }
7676
private volatile int completed;
7777

78+
public void Reset(WorkItem item)
79+
{
80+
Item = item;
81+
completed = 0;
82+
CancellationTokenRegistration = default;
83+
}
84+
7885
public bool TryComplete()
7986
{
8087
int was = Interlocked.Exchange(ref completed, 1);
@@ -114,7 +121,7 @@ public void NotifyAll()
114121

115122
workItem.CancellationTokenRegistration.Dispose();
116123
workItem.Item.Invoke();
117-
workItem.Item = default;
124+
workItem.Reset(default);
118125

119126
workItemPool.Add(workItem);
120127
}
@@ -135,8 +142,9 @@ internal void AddContinuation(int token, WorkItem item, CancellationToken ct)
135142
if (!workItemPool.TryTake(out var regItem))
136143
regItem = new();
137144

138-
regItem.Item = item;
145+
regItem.Reset(item);
139146
workQueueFront.Add(regItem);
147+
140148
if (ct.CanBeCanceled)
141149
regItem.CancellationTokenRegistration = ct.Register(TokenCancelled, regItem, false);
142150
return;
@@ -164,7 +172,8 @@ internal void TokenCancelled(object objItem)
164172
return;
165173

166174
var ret = item.Item;
167-
item.Item = default;
175+
item.Reset(default);
176+
168177
workItemPool.Add(item);
169178

170179
ret.Invoke();

0 commit comments

Comments
 (0)