public void TestRemoveAndWriteAllReentrantWrite() { EmbeddedChannel channel = new EmbeddedChannel(new ChannelOutboundHandlerAdapter0(), new ChannelHandlerAdapter()); PendingWriteQueue queue = new PendingWriteQueue(channel.Pipeline.LastContext()); IPromise promise = channel.NewPromise(); IPromise promise3 = channel.NewPromise(); promise.Task.ContinueWith(t => queue.Add(3L, promise3), TaskContinuationOptions.ExecuteSynchronously); queue.Add(1L, promise); IPromise promise2 = channel.NewPromise(); queue.Add(2L, promise2); queue.RemoveAndWriteAllAsync(); Assert.True(promise.IsCompleted); Assert.True(promise.IsSuccess); Assert.True(promise2.IsCompleted); Assert.True(promise2.IsSuccess); Assert.True(promise3.IsCompleted); Assert.True(promise3.IsSuccess); Assert.True(channel.Finish()); Assert.Equal(1L, channel.ReadOutbound <long>()); Assert.Equal(2L, channel.ReadOutbound <long>()); Assert.Equal(3L, channel.ReadOutbound <long>()); }
private void FailPendingWrites(Exception cause) { if (_pendingWrites != null) { _pendingWrites.RemoveAndFailAll(cause); _pendingWrites = null; } }
private void WritePendingWrites() { if (_pendingWrites != null) { _pendingWrites.RemoveAndWriteAllAsync(); _pendingWrites = null; } }
private static void AssertQueueEmpty(PendingWriteQueue queue) { Assert.True(queue.IsEmpty); Assert.Equal(0, queue.Size); Assert.Equal(0, queue.Bytes); Assert.Null(queue.Current); Assert.Null(queue.RemoveAndWriteAsync()); Assert.Null(queue.RemoveAndWriteAllAsync()); }
private async Task AddPendingWrite(IChannelHandlerContext ctx, object msg) { var pendingWrites = _pendingWrites; if (pendingWrites == null) { _pendingWrites = pendingWrites = new PendingWriteQueue(ctx); } await pendingWrites.Add(msg); }
public override void HandlerAdded(IChannelHandlerContext context) { base.HandlerAdded(context); this.capturedContext = context; this.pendingUnencryptedWrites = new PendingWriteQueue(context); if (context.Channel.Active && !this.isServer) { // todo: support delayed initialization on an existing/active channel if in client mode this.EnsureAuthenticated(); } }
public void TestRemoveAndFailAllReentrantWrite() { List <int> failOrder = new List <int>(); EmbeddedChannel channel = NewChannel(); PendingWriteQueue queue = new PendingWriteQueue(channel.Pipeline.FirstContext()); IPromise promise = channel.NewPromise(); IPromise promise3 = channel.NewPromise(); promise3.Task.ContinueWith(t => { lock (s_lock) { failOrder.Add(3); } }, TaskContinuationOptions.ExecuteSynchronously); promise.Task.ContinueWith(t => { lock (s_lock) { failOrder.Add(1); } queue.Add(3L, promise3); }, TaskContinuationOptions.ExecuteSynchronously); queue.Add(1L, promise); IPromise promise2 = channel.NewPromise(); promise2.Task.ContinueWith(t => { lock (s_lock) { failOrder.Add(2); } }, TaskContinuationOptions.ExecuteSynchronously); queue.Add(2L, promise2); queue.RemoveAndFailAll(new Exception()); Assert.True(promise.IsCompleted); Assert.False(promise.IsSuccess); Assert.True(promise2.IsCompleted); Assert.False(promise2.IsSuccess); Assert.True(promise3.IsCompleted); Assert.False(promise3.IsSuccess); Assert.False(channel.Finish()); Assert.Equal(1, failOrder[0]); Assert.Equal(2, failOrder[1]); Assert.Equal(3, failOrder[2]); }
public void TestRemoveAndWriteAllWithVoidPromise() { EmbeddedChannel channel = new EmbeddedChannel(new ChannelOutboundHandlerAdapter0(), new ChannelHandlerAdapter()); PendingWriteQueue queue = new PendingWriteQueue(channel.Pipeline.LastContext()); IPromise promise = channel.NewPromise(); queue.Add(1L, promise); queue.Add(2L, channel.VoidPromise()); queue.RemoveAndWriteAllAsync(); Assert.True(channel.Finish()); Assert.True(promise.IsCompleted); Assert.True(promise.IsSuccess); Assert.Equal(1L, channel.ReadOutbound <long>()); Assert.Equal(2L, channel.ReadOutbound <long>()); }
public void ShouldFireChannelWritabilityChangedAfterRemoval() { AtomicReference <IChannelHandlerContext> ctxRef = new AtomicReference <IChannelHandlerContext>(); AtomicReference <PendingWriteQueue> queueRef = new AtomicReference <PendingWriteQueue>(); IByteBuffer msg = Unpooled.CopiedBuffer("test", Encoding.ASCII); EmbeddedChannel channel = new EmbeddedChannel(new ChannelInboundHandlerAdapter0(ctxRef, queueRef)); channel.Configuration.WriteBufferLowWaterMark = 1; channel.Configuration.WriteBufferHighWaterMark = 3; PendingWriteQueue queue = queueRef.Value; // Trigger channelWritabilityChanged() by adding a message that's larger than the high watermark. queue.Add(msg, channel.NewPromise()); channel.Finish(); Assert.Equal(0, msg.ReferenceCount); }
public void TestCloseChannelOnCreation() { EmbeddedChannel channel = NewChannel(); IChannelHandlerContext context = channel.Pipeline.FirstContext(); try { channel.CloseAsync().GetAwaiter().GetResult(); } catch { } PendingWriteQueue queue = new PendingWriteQueue(context); var ex = new InvalidOperationException(); IPromise promise = channel.NewPromise(); queue.Add(1L, promise); queue.RemoveAndFailAll(ex); Assert.Same(ex, promise.Task.Exception.InnerException); }
public void TestRemoveAndFailAllReentrantFailAll() { EmbeddedChannel channel = NewChannel(); PendingWriteQueue queue = new PendingWriteQueue(channel.Pipeline.FirstContext()); IPromise promise = channel.NewPromise(); promise.Task.ContinueWith(t => queue.RemoveAndFailAll(new InvalidOperationException()), TaskContinuationOptions.ExecuteSynchronously); queue.Add(1L, promise); IPromise promise2 = channel.NewPromise(); queue.Add(2L, promise2); queue.RemoveAndFailAll(new Exception()); Assert.True(promise.IsCompleted); Assert.False(promise.IsSuccess); Assert.True(promise2.IsCompleted); Assert.False(promise2.IsSuccess); Assert.False(channel.Finish()); }
public override void ChannelWritabilityChanged(IChannelHandlerContext context) { PendingWriteQueue queue = _queueRef.Value; IByteBuffer msg = (IByteBuffer)queue.Current; if (msg is null) { return; } Assert.Equal(1, msg.ReferenceCount); // This call will trigger another channelWritabilityChanged() event because the number of // pending bytes will go below the low watermark. // // If PendingWriteQueue.remove() did not remove the current entry before triggering // channelWritabilityChanged() event, we will end up with attempting to remove the same // element twice, resulting in the double release. queue.Remove(); Assert.Equal(0, msg.ReferenceCount); }
public void TestRemoveAndWriteAllReentrance() { EmbeddedChannel channel = NewChannel(); PendingWriteQueue queue = new PendingWriteQueue(channel.Pipeline.FirstContext()); IPromise promise = channel.NewPromise(); promise.Task.ContinueWith(t => queue.RemoveAndWriteAllAsync(), TaskContinuationOptions.ExecuteSynchronously); queue.Add(1L, promise); IPromise promise2 = channel.NewPromise(); queue.Add(2L, promise2); queue.RemoveAndWriteAllAsync(); channel.Flush(); Assert.True(promise.IsSuccess); Assert.True(promise2.IsSuccess); Assert.True(channel.Finish()); Assert.Equal(1L, channel.ReadOutbound <long>()); Assert.Equal(2L, channel.ReadOutbound <long>()); Assert.Null(channel.ReadOutbound()); Assert.Null(channel.ReadOutbound()); }
public override void HandlerAdded(IChannelHandlerContext context) { _queue = new PendingWriteQueue(context); }