Skip to content

Commit

Permalink
fix WhenAll,WhenAny 0-length
Browse files Browse the repository at this point in the history
  • Loading branch information
neuecc committed May 7, 2020
1 parent 66fa203 commit be539fd
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 7 deletions.
12 changes: 10 additions & 2 deletions src/UniTask.NetCoreSandbox/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,16 @@ static async Task Main(string[] args)

static async UniTask<int> outer()
{
var v = await DoAsync();
return v;
//await Task.WhenAll();

//var foo = await Task.WhenAny(Array.Empty<Task<int>>());


await UniTask.WhenAny(new UniTask[0]);

return 10;
//var v = await DoAsync();
//return v;
}


Expand Down
12 changes: 11 additions & 1 deletion src/UniTask/Assets/Plugins/UniTask/Internal/ArrayPoolUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,21 @@ static void EnsureCapacityCore<T>(ref T[] array, int index, ArrayPool<T> pool)
}
}

public static RentArray<T> CopyToRentArray<T>(IEnumerable<T> source)
public static RentArray<T> Materialize<T>(IEnumerable<T> source)
{
if (source is T[] array)
{
return new RentArray<T>(array, array.Length, null);
}

var defaultCount = 32;
if (source is ICollection<T> coll)
{
if (coll.Count == 0)
{
return new RentArray<T>(Array.Empty<T>(), 0, null);
}

defaultCount = coll.Count;
var pool = ArrayPool<T>.Shared;
var buffer = pool.Rent(defaultCount);
Expand Down
28 changes: 26 additions & 2 deletions src/UniTask/Assets/Plugins/UniTask/UniTask.WhenAll.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@ public partial struct UniTask
{
public static UniTask<T[]> WhenAll<T>(params UniTask<T>[] tasks)
{
if (tasks.Length == 0)
{
return UniTask.FromResult(Array.Empty<T>());
}

return new UniTask<T[]>(new WhenAllPromise<T>(tasks, tasks.Length), 0);
}

public static UniTask<T[]> WhenAll<T>(IEnumerable<UniTask<T>> tasks)
{
using (var span = ArrayPoolUtil.CopyToRentArray(tasks))
using (var span = ArrayPoolUtil.Materialize(tasks))
{
var promise = new WhenAllPromise<T>(span.Array, span.Length); // consumed array in constructor.
return new UniTask<T[]>(promise, 0);
Expand All @@ -25,12 +30,17 @@ public static UniTask<T[]> WhenAll<T>(IEnumerable<UniTask<T>> tasks)

public static UniTask WhenAll(params UniTask[] tasks)
{
if (tasks.Length == 0)
{
return UniTask.CompletedTask;
}

return new UniTask(new WhenAllPromise(tasks, tasks.Length), 0);
}

public static UniTask WhenAll(IEnumerable<UniTask> tasks)
{
using (var span = ArrayPoolUtil.CopyToRentArray(tasks))
using (var span = ArrayPoolUtil.Materialize(tasks))
{
var promise = new WhenAllPromise(span.Array, span.Length); // consumed array in constructor.
return new UniTask(promise, 0);
Expand All @@ -48,6 +58,14 @@ public WhenAllPromise(UniTask<T>[] tasks, int tasksLength)
TaskTracker.TrackActiveTask(this, 3);

this.completeCount = 0;

if (tasksLength == 0)
{
this.result = Array.Empty<T>();
core.TrySetResult(result);
return;
}

this.result = new T[tasksLength];

for (int i = 0; i < tasksLength; i++)
Expand Down Expand Up @@ -144,6 +162,12 @@ public WhenAllPromise(UniTask[] tasks, int tasksLength)
this.tasksLength = tasksLength;
this.completeCount = 0;

if (tasksLength == 0)
{
core.TrySetResult(AsyncUnit.Default);
return;
}

for (int i = 0; i < tasksLength; i++)
{
UniTask.Awaiter awaiter;
Expand Down
14 changes: 12 additions & 2 deletions src/UniTask/Assets/Plugins/UniTask/UniTask.WhenAny.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public partial struct UniTask

public static UniTask<(int winArgumentIndex, T result)> WhenAny<T>(IEnumerable<UniTask<T>> tasks)
{
using (var span = ArrayPoolUtil.CopyToRentArray(tasks))
using (var span = ArrayPoolUtil.Materialize(tasks))
{
return new UniTask<(int, T)>(new WhenAnyPromise<T>(span.Array, span.Length), 0);
}
Expand All @@ -36,7 +36,7 @@ public static UniTask<int> WhenAny(params UniTask[] tasks)
/// <summary>Return value is winArgumentIndex</summary>
public static UniTask<int> WhenAny(IEnumerable<UniTask> tasks)
{
using (var span = ArrayPoolUtil.CopyToRentArray(tasks))
using (var span = ArrayPoolUtil.Materialize(tasks))
{
return new UniTask<int>(new WhenAnyPromise(span.Array, span.Length), 0);
}
Expand Down Expand Up @@ -186,6 +186,11 @@ sealed class WhenAnyPromise<T> : IUniTaskSource<(int, T)>

public WhenAnyPromise(UniTask<T>[] tasks, int tasksLength)
{
if (tasksLength == 0)
{
throw new ArgumentException("The tasks argument contains no tasks.");
}

TaskTracker.TrackActiveTask(this, 3);

for (int i = 0; i < tasksLength; i++)
Expand Down Expand Up @@ -277,6 +282,11 @@ sealed class WhenAnyPromise : IUniTaskSource<int>

public WhenAnyPromise(UniTask[] tasks, int tasksLength)
{
if (tasksLength == 0)
{
throw new ArgumentException("The tasks argument contains no tasks.");
}

TaskTracker.TrackActiveTask(this, 3);

for (int i = 0; i < tasksLength; i++)
Expand Down

0 comments on commit be539fd

Please sign in to comment.