wabbajack/Wabbajack.Common.CSP/AChannel.cs

84 lines
2.8 KiB
C#
Raw Normal View History

2019-11-09 06:37:05 +00:00
using System;
using System.IO;
using System.Threading;
2019-11-09 06:37:05 +00:00
using System.Threading.Tasks;
namespace Wabbajack.Common.CSP
{
public abstract class AChannel<TIn, TOut> : IChannel<TIn, TOut>
{
public abstract bool IsClosed { get; }
public abstract void Close();
public abstract (AsyncResult, bool) Put(TIn val, Handler<Action<bool>> handler);
public abstract (AsyncResult, TOut) Take(Handler<Action<bool, TOut>> handler);
2019-11-09 06:37:05 +00:00
private Task<(bool, TOut)> _take_cancelled_task;
private Task<(bool, TOut)> TakeCancelledTask
{
get
{
if (_take_cancelled_task == null)
_take_cancelled_task = Task.FromCanceled<(bool, TOut)>(CancellationToken.None);
return _take_cancelled_task;
}
}
private Task<bool> _put_cancelled_task;
private Task<bool> PutCancelledTask
2019-11-09 06:37:05 +00:00
{
get
{
if (_put_cancelled_task == null)
_put_cancelled_task = Task.FromCanceled<bool>(CancellationToken.None);
return _put_cancelled_task;
}
2019-11-09 06:37:05 +00:00
}
public ValueTask<(bool, TOut)> Take(bool onCaller)
2019-11-09 06:37:05 +00:00
{
var handler = new TakeTaskHandler<TOut>();
var (resultType, val) = Take(handler);
switch (resultType)
{
case AsyncResult.Closed:
return new ValueTask<(bool, TOut)>((false, default));
case AsyncResult.Completed:
return new ValueTask<(bool, TOut)>((true, val));
case AsyncResult.Enqueued:
return new ValueTask<(bool, TOut)>(handler.TaskCompletionSource.Task);
case AsyncResult.Canceled:
return new ValueTask<(bool, TOut)>(TakeCancelledTask);
default:
// Should never happen
throw new InvalidDataException();
}
}
public ValueTask<bool> Put(TIn val, bool onCaller)
{
var handler = new PutTaskHandler<bool>();
var (resultType, putResult) = Put(val, handler);
switch (resultType)
{
case AsyncResult.Completed:
return new ValueTask<bool>(putResult);
case AsyncResult.Canceled:
return new ValueTask<bool>(PutCancelledTask);
case AsyncResult.Closed:
return new ValueTask<bool>(false);
case AsyncResult.Enqueued:
return new ValueTask<bool>(handler.TaskCompletionSource.Task);
default:
// Should never happen
throw new InvalidDataException();
}
2019-11-09 06:37:05 +00:00
}
}
}