2020-05-25 19:33:54 +09:00
|
|
|
|
using Cysharp.Threading.Tasks.Internal;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Concurrent;
|
2020-05-09 15:33:46 +09:00
|
|
|
|
using System.Runtime.CompilerServices;
|
|
|
|
|
|
using System.Threading;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Cysharp.Threading.Tasks
|
|
|
|
|
|
{
|
|
|
|
|
|
public partial struct UniTask
|
|
|
|
|
|
{
|
|
|
|
|
|
public static UniTask.YieldAwaitable Yield()
|
|
|
|
|
|
{
|
|
|
|
|
|
return default;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public readonly struct YieldAwaitable
|
|
|
|
|
|
{
|
|
|
|
|
|
public Awaiter GetAwaiter()
|
|
|
|
|
|
{
|
|
|
|
|
|
return default;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public readonly struct Awaiter : ICriticalNotifyCompletion
|
|
|
|
|
|
{
|
|
|
|
|
|
static readonly SendOrPostCallback SendOrPostCallbackDelegate = Continuation;
|
|
|
|
|
|
static readonly WaitCallback WaitCallbackDelegate = Continuation;
|
|
|
|
|
|
|
|
|
|
|
|
public bool IsCompleted => false;
|
|
|
|
|
|
|
|
|
|
|
|
public void GetResult() { }
|
|
|
|
|
|
|
|
|
|
|
|
public void OnCompleted(Action continuation)
|
|
|
|
|
|
{
|
|
|
|
|
|
UnsafeOnCompleted(continuation);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void UnsafeOnCompleted(Action continuation)
|
|
|
|
|
|
{
|
|
|
|
|
|
var syncContext = SynchronizationContext.Current;
|
|
|
|
|
|
if (syncContext != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
syncContext.Post(SendOrPostCallbackDelegate, continuation);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2020-05-25 19:33:54 +09:00
|
|
|
|
#if NETCOREAPP3_1
|
|
|
|
|
|
ThreadPool.UnsafeQueueUserWorkItem(ThreadPoolWorkItem.Create(continuation), false);
|
|
|
|
|
|
#else
|
2020-05-09 15:33:46 +09:00
|
|
|
|
ThreadPool.UnsafeQueueUserWorkItem(WaitCallbackDelegate, continuation);
|
2020-05-25 19:33:54 +09:00
|
|
|
|
#endif
|
2020-05-09 15:33:46 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void Continuation(object state)
|
|
|
|
|
|
{
|
|
|
|
|
|
((Action)state).Invoke();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-05-25 19:33:54 +09:00
|
|
|
|
|
|
|
|
|
|
#if NETCOREAPP3_1
|
|
|
|
|
|
|
2020-05-29 03:43:18 +09:00
|
|
|
|
sealed class ThreadPoolWorkItem : IThreadPoolWorkItem, ITaskPoolNode<ThreadPoolWorkItem>
|
2020-05-25 19:33:54 +09:00
|
|
|
|
{
|
2020-05-29 03:43:18 +09:00
|
|
|
|
static TaskPool<ThreadPoolWorkItem> pool;
|
2020-08-28 18:03:22 +09:00
|
|
|
|
ThreadPoolWorkItem nextNode;
|
|
|
|
|
|
public ref ThreadPoolWorkItem NextNode => ref nextNode;
|
2020-05-29 03:43:18 +09:00
|
|
|
|
|
|
|
|
|
|
static ThreadPoolWorkItem()
|
|
|
|
|
|
{
|
2020-05-29 03:58:22 +09:00
|
|
|
|
TaskPool.RegisterSizeGetter(typeof(ThreadPoolWorkItem), () => pool.Size);
|
2020-05-29 03:43:18 +09:00
|
|
|
|
}
|
2020-05-25 19:33:54 +09:00
|
|
|
|
|
|
|
|
|
|
Action continuation;
|
|
|
|
|
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
|
public static ThreadPoolWorkItem Create(Action continuation)
|
|
|
|
|
|
{
|
2020-05-29 03:43:18 +09:00
|
|
|
|
if (!pool.TryPop(out var item))
|
2020-05-25 19:33:54 +09:00
|
|
|
|
{
|
|
|
|
|
|
item = new ThreadPoolWorkItem();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
item.continuation = continuation;
|
|
|
|
|
|
return item;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
|
public void Execute()
|
|
|
|
|
|
{
|
|
|
|
|
|
var call = continuation;
|
|
|
|
|
|
continuation = null;
|
2020-05-29 03:43:18 +09:00
|
|
|
|
if (call != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
pool.TryPush(this);
|
|
|
|
|
|
call.Invoke();
|
|
|
|
|
|
}
|
2020-05-25 19:33:54 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
2020-05-09 15:33:46 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|