Skip to content

Commit 651abe4

Browse files
committed
Disallow LogicLooper.Dispose on the loop thread.
1 parent 7a8476f commit 651abe4

2 files changed

Lines changed: 40 additions & 2 deletions

File tree

src/LogicLooper/LogicLooper.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Cysharp.Threading.Internal;
1+
using Cysharp.Threading.Internal;
22

33
// ReSharper disable StringLiteralTypo
44
// ReSharper disable IdentifierTypo
@@ -187,6 +187,11 @@ public async Task RegisterActionAsync<TState>(LogicLooperAsyncActionWithStateDel
187187
/// <param name="shutdownDelay"></param>
188188
public async Task ShutdownAsync(TimeSpan shutdownDelay)
189189
{
190+
if (_runLoopThread == Thread.CurrentThread)
191+
{
192+
throw new InvalidOperationException("Cannot dispose the looper from the run loop thread. ShutdownAsync or Dispose must be called outside the loop.");
193+
}
194+
190195
if (Interlocked.CompareExchange(ref _isShuttingDown, 1, 0) == 0)
191196
{
192197
_ctsAction.Cancel();

test/LogicLooper.Test/LogicLooperTest.cs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Cysharp.Threading;
1+
using Cysharp.Threading;
22
using Cysharp.Threading.Internal;
33

44
namespace LogicLooper.Test;
@@ -384,4 +384,37 @@ public async Task TargetFrameRateOverride_2()
384384

385385
Assert.Equal(1, overriddenFrameCount);
386386
}
387+
388+
[Fact]
389+
public async Task Dispose_DisallowOnLoopThread()
390+
{
391+
using var looper = new Cysharp.Threading.LogicLooper(30);
392+
Exception? ex = default;
393+
394+
await looper.RegisterActionAsync((in LogicLooperActionContext ctx) =>
395+
{
396+
ex = Record.Exception(() => looper.Dispose());
397+
return false;
398+
});
399+
400+
Assert.NotNull(ex);
401+
Assert.IsType<InvalidOperationException>(ex);
402+
}
403+
404+
[Fact]
405+
public async Task Dispose_OutsideTheLoop()
406+
{
407+
using var looper = new Cysharp.Threading.LogicLooper(30);
408+
Exception? ex = default;
409+
410+
var t = looper.RegisterActionAsync((in LogicLooperActionContext ctx) =>
411+
{
412+
return true;
413+
});
414+
415+
await Task.Delay(100);
416+
417+
looper.Dispose();
418+
}
419+
387420
}

0 commit comments

Comments
 (0)