parent
990e6fe188
commit
90220feb41
3 changed files with 73 additions and 59 deletions
|
|
@ -33,12 +33,20 @@ namespace Server.Network
|
|||
|
||||
public class Pipe<T>
|
||||
{
|
||||
public readonly struct Result
|
||||
{
|
||||
public bool Closed { get; }
|
||||
|
||||
public Result(bool closed) => Closed = closed;
|
||||
}
|
||||
|
||||
public class PipeWriter<T>
|
||||
{
|
||||
private readonly Pipe<T> _pipe;
|
||||
|
||||
public PipeWriter(Pipe<T> pipe) => _pipe = pipe;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool GetAvailable(ArraySegment<T>[] segments)
|
||||
{
|
||||
var read = _pipe._readIdx;
|
||||
|
|
@ -63,6 +71,7 @@ namespace Server.Network
|
|||
return !_pipe._closed;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool GetAvailable(out CircularBuffer<T> buffer)
|
||||
{
|
||||
var read = _pipe._readIdx;
|
||||
|
|
@ -183,7 +192,7 @@ namespace Server.Network
|
|||
}
|
||||
}
|
||||
|
||||
public class PipeReader<T> : IPipeTask<PipeReader<T>>
|
||||
public class PipeReader<T> : IPipeTask<Result>
|
||||
{
|
||||
private readonly Pipe<T> _pipe;
|
||||
|
||||
|
|
@ -203,6 +212,20 @@ namespace Server.Network
|
|||
return write + _pipe.Size - read;
|
||||
}
|
||||
|
||||
private ArraySegment<T>[] _segments;
|
||||
|
||||
public IPipeTask<Result> Read(ArraySegment<T>[] segments)
|
||||
{
|
||||
if (_pipe._awaitBeginning)
|
||||
{
|
||||
throw new Exception("Double await on reader");
|
||||
}
|
||||
|
||||
_segments = segments;
|
||||
return this;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool TryRead(out CircularBuffer<T> buffer)
|
||||
{
|
||||
var read = _pipe._readIdx;
|
||||
|
|
@ -226,7 +249,8 @@ namespace Server.Network
|
|||
return !_pipe._closed;
|
||||
}
|
||||
|
||||
public bool TryRead(ArraySegment<T>[] segments)
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void TryRead(ArraySegment<T>[] segments)
|
||||
{
|
||||
var read = _pipe._readIdx;
|
||||
var write = _pipe._writeIdx;
|
||||
|
|
@ -241,8 +265,6 @@ namespace Server.Network
|
|||
segments[0] = _pipe.Size - read == 0 ? ArraySegment<T>.Empty : new ArraySegment<T>(_pipe._buffer, (int)read, (int)(_pipe.Size - read));
|
||||
segments[1] = write == 0 ? ArraySegment<T>.Empty : new ArraySegment<T>(_pipe._buffer, 0, (int)write);
|
||||
}
|
||||
|
||||
return !_pipe._closed;
|
||||
}
|
||||
|
||||
public void Advance(uint count)
|
||||
|
|
@ -288,7 +310,7 @@ namespace Server.Network
|
|||
|
||||
// The following makes it possible to await the reader. Do not use any of this directly.
|
||||
|
||||
public IPipeTask<PipeReader<T>> GetAwaiter() => this;
|
||||
public IPipeTask<Result> GetAwaiter() => this;
|
||||
|
||||
public bool IsCompleted
|
||||
{
|
||||
|
|
@ -304,7 +326,22 @@ namespace Server.Network
|
|||
}
|
||||
}
|
||||
|
||||
public PipeReader<T> GetResult() => this;
|
||||
public Result GetResult()
|
||||
{
|
||||
if (_pipe._closed)
|
||||
{
|
||||
_segments = null;
|
||||
return new Result(true);
|
||||
}
|
||||
|
||||
if (_segments != null)
|
||||
{
|
||||
TryRead(_segments);
|
||||
_segments = null;
|
||||
}
|
||||
|
||||
return new Result(false);
|
||||
}
|
||||
|
||||
public void OnCompleted(Action continuation) => _pipe._readerContinuation = continuation;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue