parent
990e6fe188
commit
90220feb41
3 changed files with 73 additions and 59 deletions
|
|
@ -25,22 +25,21 @@ namespace Server.Tests.Network
|
|||
|
||||
DelayedExecute(() =>
|
||||
{
|
||||
// Write some data into the pipe
|
||||
; // Write some data into the pipe
|
||||
writer.GetAvailable(out var buffer);
|
||||
Assert.True(buffer.Length == 99);
|
||||
|
||||
buffer.CopyFrom(new byte[] { 1 });
|
||||
buffer.CopyFrom(new byte[] { 2 });
|
||||
buffer.CopyFrom(new byte[] { 3 });
|
||||
buffer[0] = 0x1;
|
||||
buffer[1] = 0x2;
|
||||
buffer[2] = 0x3;
|
||||
|
||||
writer.Advance(3);
|
||||
writer.Flush();
|
||||
});
|
||||
|
||||
var segments = new ArraySegment<byte>[2];
|
||||
(await reader).TryRead(segments);
|
||||
await reader.Read(segments);
|
||||
|
||||
Assert.True(segments[0].Count == 3);
|
||||
Assert.Equal(3, segments[0].Count);
|
||||
}
|
||||
|
||||
private bool _signal;
|
||||
|
|
@ -139,32 +138,31 @@ namespace Server.Tests.Network
|
|||
|
||||
writer.GetAvailable(out var buffer);
|
||||
|
||||
Assert.True(buffer.Length == 9);
|
||||
Assert.True(reader.GetAvailable() == 0);
|
||||
Assert.Equal(9, buffer.Length);
|
||||
Assert.Equal(0u, reader.GetAvailable());
|
||||
reader.TryRead(out buffer);
|
||||
Assert.True(buffer.Length == 0);
|
||||
Assert.Equal(0, buffer.Length);
|
||||
|
||||
writer.Advance(7);
|
||||
writer.GetAvailable(out buffer);
|
||||
Assert.True(buffer.Length == 2);
|
||||
Assert.True(reader.GetAvailable() == 7);
|
||||
Assert.Equal(2, buffer.Length);
|
||||
Assert.Equal(7u, reader.GetAvailable());
|
||||
reader.TryRead(out buffer);
|
||||
Assert.True(buffer.Length == 7);
|
||||
Assert.Equal(7, buffer.Length);
|
||||
|
||||
reader.Advance(4);
|
||||
writer.GetAvailable(out buffer);
|
||||
Assert.True(buffer.Length == 6);
|
||||
Assert.True(reader.GetAvailable() == 3);
|
||||
Assert.Equal(6, buffer.Length);
|
||||
Assert.Equal(3u, reader.GetAvailable());
|
||||
reader.TryRead(out buffer);
|
||||
Assert.True(buffer.Length == 3);
|
||||
Assert.Equal(3, buffer.Length);
|
||||
|
||||
writer.Advance(3);
|
||||
writer.GetAvailable(out buffer);
|
||||
Assert.True(buffer.Length == 3);
|
||||
Assert.True(reader.GetAvailable() == 6);
|
||||
Assert.Equal(3, buffer.Length);
|
||||
Assert.Equal(6u, reader.GetAvailable());
|
||||
reader.TryRead(out buffer);
|
||||
Assert.True(buffer.Length == 6);
|
||||
|
||||
Assert.Equal(6, buffer.Length);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -201,7 +199,7 @@ namespace Server.Tests.Network
|
|||
writer.Advance(9);
|
||||
writer.Flush();
|
||||
|
||||
Assert.True(reader.GetAvailable() == 9);
|
||||
Assert.Equal(9u, reader.GetAvailable());
|
||||
|
||||
reader.TryRead(out buffer);
|
||||
|
||||
|
|
@ -209,18 +207,18 @@ namespace Server.Tests.Network
|
|||
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
Assert.True(first[i] == i);
|
||||
Assert.Equal(i, first[i]);
|
||||
}
|
||||
|
||||
reader.Advance(4);
|
||||
reader.TryRead(out buffer);
|
||||
first = buffer.GetSpan(0);
|
||||
Assert.True(buffer.Length == 5);
|
||||
Assert.True(first[0] == 4);
|
||||
Assert.True(first[1] == 5);
|
||||
Assert.True(first[2] == 6);
|
||||
Assert.True(first[3] == 7);
|
||||
Assert.True(first[4] == 8);
|
||||
Assert.Equal(5, buffer.Length);
|
||||
Assert.Equal(4, first[0]);
|
||||
Assert.Equal(5, first[1]);
|
||||
Assert.Equal(6, first[2]);
|
||||
Assert.Equal(7, first[3]);
|
||||
Assert.Equal(8, first[4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ using System.Net.Sockets;
|
|||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using Server.Accounting;
|
||||
using Server.Exceptions;
|
||||
using Server.Gumps;
|
||||
using Server.HuePickers;
|
||||
using Server.Items;
|
||||
|
|
@ -55,7 +54,6 @@ namespace Server.Network
|
|||
private byte[] _sendBuffer;
|
||||
private long m_NextCheckActivity;
|
||||
private volatile bool m_Running;
|
||||
private readonly Thread _sendThread;
|
||||
private volatile EncodePacket _packetDecoder;
|
||||
private volatile EncodePacket _packetEncoder;
|
||||
|
||||
|
|
@ -77,7 +75,7 @@ namespace Server.Network
|
|||
Timer.DelayCall(checkAliveDuration, checkAliveDuration, CheckAllAlive);
|
||||
}
|
||||
|
||||
public NetState(Socket connection, Thread sendThread = null)
|
||||
public NetState(Socket connection)
|
||||
{
|
||||
m_Running = false;
|
||||
Connection = connection;
|
||||
|
|
@ -91,7 +89,6 @@ namespace Server.Network
|
|||
_sendBuffer = new byte[SendPipeSize];
|
||||
SendPipe = new Pipe<byte>(_sendBuffer);
|
||||
m_NextCheckActivity = Core.TickCount + 30000;
|
||||
_sendThread = sendThread ?? Core.Thread;
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -372,8 +369,6 @@ namespace Server.Network
|
|||
NetworkState.Resume(ref m_NetworkState);
|
||||
}
|
||||
|
||||
public bool GetAvailableSendPipe(out CircularBuffer<byte> buffer) => SendPipe.Writer.GetAvailable(out buffer);
|
||||
|
||||
public virtual void Send(ref CircularBuffer<byte> buffer, int length)
|
||||
{
|
||||
if (Connection == null || BlockAllPackets || buffer.Length == 0)
|
||||
|
|
@ -381,14 +376,6 @@ namespace Server.Network
|
|||
return;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
var currentThread = Thread.CurrentThread;
|
||||
if (currentThread != _sendThread)
|
||||
{
|
||||
throw new InvalidThreadException("Attempted to send packet outside send thread!");
|
||||
}
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
_packetEncoder?.Invoke(ref buffer, ref length);
|
||||
|
|
@ -412,15 +399,6 @@ namespace Server.Network
|
|||
return;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
var currentThread = Thread.CurrentThread;
|
||||
|
||||
if (currentThread != _sendThread)
|
||||
{
|
||||
throw new InvalidThreadException("Attempted to send packet outside send thread!");
|
||||
}
|
||||
#endif
|
||||
|
||||
var writer = SendPipe.Writer;
|
||||
|
||||
try
|
||||
|
|
@ -429,7 +407,7 @@ namespace Server.Network
|
|||
|
||||
if (buffer.Length > 0 && length > 0)
|
||||
{
|
||||
if (!GetAvailableSendPipe(out var pipeBuffer))
|
||||
if (!SendPipe.Writer.GetAvailable(out var pipeBuffer))
|
||||
{
|
||||
p.OnSend();
|
||||
return;
|
||||
|
|
@ -489,7 +467,8 @@ namespace Server.Network
|
|||
{
|
||||
while (m_Running)
|
||||
{
|
||||
if (!(await reader).TryRead(segments))
|
||||
var result = await reader.Read(segments);
|
||||
if (result.Closed)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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