Skip to content

Commit 1c0fe87

Browse files
committed
Fixed a freeze bug.
1 parent 6ad52bb commit 1c0fe87

File tree

1 file changed

+27
-6
lines changed

1 file changed

+27
-6
lines changed

src/AsyncFiberWorks/Procedures/FiberTaskWaiter.cs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ public class FiberTaskWaiter : IDisposable
1818
private readonly ManualResetEventSlim _notifierExecutionFinished = new ManualResetEventSlim();
1919
private readonly UserThreadPool _thread;
2020
private bool _inExecuting;
21-
private CancellationToken _cancellationToken;
21+
private CancellationToken _cancellationTokenExternal;
22+
private readonly CancellationTokenSource _onDispose = new CancellationTokenSource();
2223

2324
/// <summary>
2425
/// Register a task to the sequential task list.
@@ -28,7 +29,7 @@ public class FiberTaskWaiter : IDisposable
2829
public FiberTaskWaiter(ISequentialTaskListRegistry taskList, CancellationToken cancellationToken = default)
2930
{
3031
_thread = UserThreadPool.StartNew(1);
31-
_cancellationToken = cancellationToken;
32+
_cancellationTokenExternal = cancellationToken;
3233
_unsubscriber = taskList.Add(ExecuteAsync);
3334
}
3435

@@ -45,7 +46,7 @@ public async Task ExecuteAsync()
4546
{
4647
return;
4748
}
48-
if (_cancellationToken.IsCancellationRequested)
49+
if (_cancellationTokenExternal.IsCancellationRequested)
4950
{
5051
return;
5152
}
@@ -69,7 +70,8 @@ public async Task ExecuteAsync()
6970

7071
try
7172
{
72-
await _thread.RegisterWaitForSingleObjectAsync(_notifierExecutionFinished.WaitHandle, _cancellationToken).ConfigureAwait(false);
73+
var cancellation = CancellationTokenSource.CreateLinkedTokenSource(_cancellationTokenExternal, _onDispose.Token);
74+
await _thread.RegisterWaitForSingleObjectAsync(_notifierExecutionFinished.WaitHandle, cancellation.Token).ConfigureAwait(false);
7375
}
7476
catch (OperationCanceledException)
7577
{
@@ -95,7 +97,7 @@ public async Task ExecutionStarted()
9597
{
9698
throw new ObjectDisposedException(GetType().FullName);
9799
}
98-
if (_cancellationToken.IsCancellationRequested)
100+
if (_cancellationTokenExternal.IsCancellationRequested)
99101
{
100102
throw new OperationCanceledException();
101103
}
@@ -108,7 +110,24 @@ public async Task ExecutionStarted()
108110
}
109111
}
110112

111-
await _thread.RegisterWaitForSingleObjectAsync(_notifierExecutionRequested.WaitHandle, _cancellationToken).ConfigureAwait(false);
113+
using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(_cancellationTokenExternal, _onDispose.Token))
114+
{
115+
try
116+
{
117+
await _thread.RegisterWaitForSingleObjectAsync(_notifierExecutionRequested.WaitHandle, linkedCts.Token).ConfigureAwait(false);
118+
}
119+
catch (OperationCanceledException)
120+
{
121+
if (_cancellationTokenExternal.IsCancellationRequested)
122+
{
123+
_cancellationTokenExternal.ThrowIfCancellationRequested();
124+
}
125+
else
126+
{
127+
throw new ObjectDisposedException(nameof(FiberTaskWaiter));
128+
}
129+
}
130+
}
112131

113132
lock (_lockObj)
114133
{
@@ -132,6 +151,8 @@ public void Dispose()
132151
_executionRequested = false;
133152
_inExecuting = false;
134153
_unsubscriber.Dispose();
154+
_onDispose.Cancel();
155+
_onDispose.Dispose();
135156
_notifierExecutionRequested.Dispose();
136157
_notifierExecutionFinished.Dispose();
137158
}

0 commit comments

Comments
 (0)