mirror of https://github.com/Cysharp/UniTask
Merge pull request #488 from Cysharp/revert-445-fix-wait-async
Revert "Fixed https://github.com/Cysharp/UniTask/issues/444"pull/489/head
commit
c1042b32b7
|
@ -20,6 +20,8 @@ namespace Cysharp.Threading.Tasks
|
||||||
{
|
{
|
||||||
ITriggerHandler<T> head; // head.prev is last
|
ITriggerHandler<T> head; // head.prev is last
|
||||||
ITriggerHandler<T> iteratingHead;
|
ITriggerHandler<T> iteratingHead;
|
||||||
|
|
||||||
|
bool preserveRemoveSelf;
|
||||||
ITriggerHandler<T> iteratingNode;
|
ITriggerHandler<T> iteratingNode;
|
||||||
|
|
||||||
void LogError(Exception ex)
|
void LogError(Exception ex)
|
||||||
|
@ -42,7 +44,6 @@ namespace Cysharp.Threading.Tasks
|
||||||
while (h != null)
|
while (h != null)
|
||||||
{
|
{
|
||||||
iteratingNode = h;
|
iteratingNode = h;
|
||||||
var next = h.Next;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -54,7 +55,18 @@ namespace Cysharp.Threading.Tasks
|
||||||
Remove(h);
|
Remove(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
h = next;
|
if (preserveRemoveSelf)
|
||||||
|
{
|
||||||
|
preserveRemoveSelf = false;
|
||||||
|
iteratingNode = null;
|
||||||
|
var next = h.Next;
|
||||||
|
Remove(h);
|
||||||
|
h = next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
h = h.Next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
iteratingNode = null;
|
iteratingNode = null;
|
||||||
|
@ -85,6 +97,7 @@ namespace Cysharp.Threading.Tasks
|
||||||
LogError(ex);
|
LogError(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
preserveRemoveSelf = false;
|
||||||
iteratingNode = null;
|
iteratingNode = null;
|
||||||
var next = h.Next;
|
var next = h.Next;
|
||||||
Remove(h);
|
Remove(h);
|
||||||
|
@ -119,6 +132,7 @@ namespace Cysharp.Threading.Tasks
|
||||||
LogError(ex);
|
LogError(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
preserveRemoveSelf = false;
|
||||||
iteratingNode = null;
|
iteratingNode = null;
|
||||||
var next = h.Next;
|
var next = h.Next;
|
||||||
Remove(h);
|
Remove(h);
|
||||||
|
@ -153,6 +167,7 @@ namespace Cysharp.Threading.Tasks
|
||||||
LogError(ex);
|
LogError(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
preserveRemoveSelf = false;
|
||||||
iteratingNode = null;
|
iteratingNode = null;
|
||||||
var next = h.Next;
|
var next = h.Next;
|
||||||
Remove(h);
|
Remove(h);
|
||||||
|
@ -226,63 +241,71 @@ namespace Cysharp.Threading.Tasks
|
||||||
{
|
{
|
||||||
if (handler == null) throw new ArgumentNullException(nameof(handler));
|
if (handler == null) throw new ArgumentNullException(nameof(handler));
|
||||||
|
|
||||||
var prev = handler.Prev;
|
if (iteratingNode != null && iteratingNode == handler)
|
||||||
var next = handler.Next;
|
|
||||||
|
|
||||||
if (next != null)
|
|
||||||
{
|
{
|
||||||
next.Prev = prev;
|
// if remove self, reserve remove self after invoke completed.
|
||||||
}
|
preserveRemoveSelf = true;
|
||||||
|
|
||||||
if (handler == head)
|
|
||||||
{
|
|
||||||
head = next;
|
|
||||||
}
|
|
||||||
else if (handler == iteratingHead)
|
|
||||||
{
|
|
||||||
iteratingHead = next;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// when handler is head, prev indicate last so don't use it.
|
var prev = handler.Prev;
|
||||||
if (prev != null)
|
var next = handler.Next;
|
||||||
{
|
|
||||||
prev.Next = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (head != null)
|
if (next != null)
|
||||||
{
|
|
||||||
if (head.Prev == handler)
|
|
||||||
{
|
{
|
||||||
if (prev != head)
|
next.Prev = prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handler == head)
|
||||||
|
{
|
||||||
|
head = next;
|
||||||
|
}
|
||||||
|
else if (handler == iteratingHead)
|
||||||
|
{
|
||||||
|
iteratingHead = next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// when handler is head, prev indicate last so don't use it.
|
||||||
|
if (prev != null)
|
||||||
{
|
{
|
||||||
head.Prev = prev;
|
prev.Next = next;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
head.Prev = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (iteratingHead != null)
|
if (head != null)
|
||||||
{
|
|
||||||
if (iteratingHead.Prev == handler)
|
|
||||||
{
|
{
|
||||||
if (prev != iteratingHead.Prev)
|
if (head.Prev == handler)
|
||||||
{
|
{
|
||||||
iteratingHead.Prev = prev;
|
if (prev != head)
|
||||||
}
|
{
|
||||||
else
|
head.Prev = prev;
|
||||||
{
|
}
|
||||||
iteratingHead.Prev = null;
|
else
|
||||||
|
{
|
||||||
|
head.Prev = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
handler.Prev = null;
|
if (iteratingHead != null)
|
||||||
handler.Next = null;
|
{
|
||||||
|
if (iteratingHead.Prev == handler)
|
||||||
|
{
|
||||||
|
if (prev != iteratingHead.Prev)
|
||||||
|
{
|
||||||
|
iteratingHead.Prev = prev;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iteratingHead.Prev = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handler.Prev = null;
|
||||||
|
handler.Next = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
using Cysharp.Threading.Tasks;
|
|
||||||
using FluentAssertions;
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Threading;
|
|
||||||
using UnityEngine.TestTools;
|
|
||||||
|
|
||||||
namespace Cysharp.Threading.TasksTests
|
|
||||||
{
|
|
||||||
public class AsyncReactivePropertyTest
|
|
||||||
{
|
|
||||||
private int _callCounter;
|
|
||||||
|
|
||||||
[UnityTest]
|
|
||||||
public IEnumerator WaitCancelWait() => UniTask.ToCoroutine(async () =>
|
|
||||||
{
|
|
||||||
// Test case for https://github.com/Cysharp/UniTask/issues/444
|
|
||||||
|
|
||||||
var property = new AsyncReactiveProperty<int>(0);
|
|
||||||
|
|
||||||
var cts1 = new CancellationTokenSource();
|
|
||||||
var cts2 = new CancellationTokenSource();
|
|
||||||
WaitForProperty(property, cts1.Token);
|
|
||||||
WaitForProperty(property, cts2.Token);
|
|
||||||
|
|
||||||
_callCounter = 0;
|
|
||||||
property.Value = 1;
|
|
||||||
_callCounter.Should().Be(2);
|
|
||||||
|
|
||||||
cts2.Cancel();
|
|
||||||
cts2.Dispose();
|
|
||||||
cts1.Cancel();
|
|
||||||
cts1.Dispose();
|
|
||||||
|
|
||||||
var cts3 = new CancellationTokenSource();
|
|
||||||
WaitForProperty(property, cts3.Token);
|
|
||||||
|
|
||||||
_callCounter = 0;
|
|
||||||
property.Value = 2;
|
|
||||||
_callCounter.Should().Be(1);
|
|
||||||
|
|
||||||
cts3.Cancel();
|
|
||||||
cts3.Dispose();
|
|
||||||
await UniTask.CompletedTask;
|
|
||||||
});
|
|
||||||
|
|
||||||
private async void WaitForProperty(AsyncReactiveProperty<int> property, CancellationToken token)
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await property.WaitAsync(token);
|
|
||||||
_callCounter++;
|
|
||||||
}
|
|
||||||
catch (OperationCanceledException)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 27665955eefb4448969b8cc4dd204600
|
|
||||||
timeCreated: 1676129650
|
|
Loading…
Reference in New Issue