public void PushBufferDestroys() { var buffer = new BufferPool (128) { AutoSizeLimit = true, AutoSizeFactor = 1 }; buffer.AddConnection(); SocketAsyncEventArgs e; buffer.TryGetBuffer (out e); buffer.RemoveConnection(); buffer.PushBuffer (e); Assert.That (() => e.SetBuffer (0, 128), Throws.TypeOf<ObjectDisposedException>()); }
public void TryGetBufferBlocksAndExisting() { var buffer = new BufferPool (128, 1); SocketAsyncEventArgs e; buffer.TryGetBuffer (out e); DateTime now = DateTime.Now; SocketAsyncEventArgs second = null; var test = new AsyncTest (args => { Assert.That (DateTime.Now - now, Is.GreaterThan (TimeSpan.FromSeconds (1))); Assert.That (second, Is.SameAs (e)); }); Task.Run (() => { Assert.IsTrue (buffer.TryGetBuffer (out second)); }).ContinueWith (t => { test.PassHandler (null, EventArgs.Empty); }); Task.Delay (1000).ContinueWith (t => { buffer.PushBuffer (e); }); test.Assert (2000); }
private void CleanupSend(SocketAsyncEventArgs e) { e.Completed -= OnSendCompleted; BufferPool.PushBuffer(e); }
public void PushNull() { var buffer = new BufferPool (128); Assert.That (() => buffer.PushBuffer (null), Throws.TypeOf<ArgumentNullException>()); }
protected Task <bool> SendCore(Message message, bool dontSetId, bool responseRequested, int timeout, out Task <Message> responseTask) { if (message == null) { throw new ArgumentNullException("message"); } responseTask = null; Socket sock = this.socket; MessageSerializer mserialzier = this.serializer; TaskCompletionSource <bool> tcs = new TaskCompletionSource <bool> (message); if (sock == null || mserialzier == null || (!IsConnected && !IsConnecting)) { tcs.TrySetResult(false); if (responseRequested) { var responseTcs = new TaskCompletionSource <Message>(); responseTcs.SetCanceled(); responseTask = responseTcs.Task; } return(tcs.Task); } if (message.Header == null) { message.Header = new MessageHeader(); } if (!dontSetId) { SetMessageId(message); if (responseRequested) { responseTask = Responses.SendFor(message, tcs.Task, timeout); } } IPEndPoint endPoint = IPEndPoint; if (endPoint == null) { tcs.SetResult(false); return(tcs.Task); } SocketAsyncEventArgs e; BufferPool.TryGetBuffer(out e); int length; byte[] buffer = mserialzier.GetBytes(message, out length, e.Buffer); if (!(message is PartialMessage) && length > 490) { byte count = (byte)Math.Ceiling((length / 490f)); int i = 0; int remaining = length; do { int payloadLen = Math.Min(490, remaining); var partial = new PartialMessage { OriginalMessageId = (ushort)message.Header.MessageId, Count = count, Header = new MessageHeader() }; partial.SetPayload(buffer, i, payloadLen); if (i == 0) // We have to fill the gap the original id uses for reliability { partial.Header.MessageId = message.Header.MessageId; } else { SetMessageId(partial); } lock (this.pendingAck) this.pendingAck.Add(partial.Header.MessageId, new Tuple <DateTime, Message> (DateTime.UtcNow, partial)); mserialzier.GetBytes(partial, out length, e.Buffer); e.SetBuffer(0, length); e.RemoteEndPoint = endPoint; remaining -= payloadLen; i += payloadLen; if (remaining == 0) { e.Completed += OnSendCompleted; e.UserToken = tcs; } else { e.Completed += OnPartialSendCompleted; } try { this.lastReliableSendActivity = Stopwatch.GetTimestamp(); if (!sock.SendToAsync(e)) { if (remaining == 0) { OnSendCompleted(this, e); } else { OnPartialSendCompleted(this, e); } } } catch (ObjectDisposedException) { BufferPool.PushBuffer(e); if (remaining == 0) { CleanupSend(e); } else { CleanupPartialSend(e); } tcs.TrySetResult(false); } if (remaining > 0) { BufferPool.TryGetBuffer(out e); } } while (remaining > 0); } else { e.SetBuffer(0, length); e.RemoteEndPoint = endPoint; e.Completed += OnSendCompleted; e.UserToken = tcs; if (message.PreferReliable || message.MustBeReliable) { this.lastReliableSendActivity = Stopwatch.GetTimestamp(); lock (this.pendingAck) this.pendingAck.Add(message.Header.MessageId, new Tuple <DateTime, Message> (DateTime.UtcNow, message)); } try { if (!sock.SendToAsync(e)) { OnSendCompleted(this, e); } } catch (ObjectDisposedException) { CleanupSend(e); tcs.TrySetResult(false); } } return(tcs.Task); }