public DefaultChannelHandlerContext( DefaultChannelPipeline pipeline, IEventExecutor executor, string name, IChannelHandler handler) : base(pipeline, executor, name, GetSkipPropagationFlags(handler)) { Contract.Requires(handler != null); this.Handler = handler; }
internal void Remove() { IEventExecutor executor = this.Executor; if (executor.InEventLoop) { this.Remove0(); } else { executor.Execute(() => this.Remove0()); } }
private static void SetupServerLoop(IEventExecutor eventExecutor) { if (!_running) { return; } eventExecutor.Execute(() => { eventExecutor.Schedule(() => { SetupServerLoop(eventExecutor); }, TimeSpan.FromMilliseconds(DelayBetweenTicks)); Update(); }); }
internal static void InvokeChannelUnregistered(FABHandlerContext next) { IEventExecutor nextExecutor = next.Executor; if (nextExecutor.InEventLoop) { next.InvokeChannelUnregistered(); } else { nextExecutor.Execute(c => ((FABHandlerContext)c).InvokeChannelUnregistered(), next); } }
internal void Remove() { IEventExecutor executor = Executor; if (executor.InEventLoop) { Remove0(); } else { executor.Execute(s_removeAction, this); } }
public Task ConnectAsync(EndPoint remoteAddress, EndPoint localAddress) { AbstractChannelHandlerContext next = this.FindContextOutbound(); Contract.Requires(remoteAddress != null); // todo: check for cancellation IEventExecutor nextExecutor = next.Executor; return(nextExecutor.InEventLoop ? next.InvokeConnectAsync(remoteAddress, localAddress) : SafeExecuteOutboundAsync(nextExecutor, () => next.InvokeConnectAsync(remoteAddress, localAddress))); }
internal static void InvokeChannelInactive(AbstractChannelHandlerContext next) { IEventExecutor nextExecutor = next.Executor; if (nextExecutor.InEventLoop) { next.InvokeChannelInactive(); } else { nextExecutor.Execute(c => ((AbstractChannelHandlerContext)c).InvokeChannelInactive(), next); } }
internal static void InvokeChannelWritabilityChanged(AbstractChannelHandlerContext next) { IEventExecutor nextExecutor = next.Executor; if (nextExecutor.InEventLoop) { next.InvokeChannelReadComplete(); } else { // todo: consider caching task nextExecutor.Execute(InvokeChannelWritabilityChangedAction, next); } }
internal static void InvokeUserEventTriggered(AbstractChannelHandlerContext next, object evt) { Contract.Requires(evt != null); IEventExecutor nextExecutor = next.Executor; if (nextExecutor.InEventLoop) { next.InvokeUserEventTriggered(evt); } else { nextExecutor.Execute(InvokeUserEventTriggeredAction, next, evt); } }
private static void _NotifyListenerWithStackOverFlowProtection(IEventExecutor eventExecutor, IFuture <V> future, IFutureListener <V> listener) { if (eventExecutor.InEventLoop()) { // @TODO: 增加对调用堆栈深度的保护(避免出现堆栈溢出) try { _NotifyListener(future, listener); } catch { } return; } _SafeExecute(eventExecutor, () => { _NotifyListener(future, listener); }); }
internal static void InvokeChannelReadComplete(FABHandlerContext next) { IEventExecutor nextExecutor = next.Executor; if (nextExecutor.InEventLoop) { next.InvokeChannelReadComplete(); } else { // todo: consider caching task nextExecutor.Execute(InvokeChannelReadCompleteAction, next); } }
static Task SafeExecuteOutboundAsync(IEventExecutor executor, Func <Task> function) { var promise = new TaskCompletionSource(); try { executor.Execute((p, func) => ((Func <Task>)func)().LinkOutcome((TaskCompletionSource)p), promise, function); } catch (Exception cause) { promise.TrySetException(cause); } return(promise.Task); }
public DefaultChannelGroup(string name, IEventExecutor executor, bool stayClosed) { if (name is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.name); } _nonServerChannels = new ConcurrentDictionary <IChannelId, IChannel>(ChannelIdComparer.Default); _serverChannels = new ConcurrentDictionary <IChannelId, IChannel>(ChannelIdComparer.Default); Name = name; _executor = executor; _stayClosed = stayClosed; }
public Task DisconnectAsync() { if (!this.Channel.Metadata.HasDisconnect) { return(this.CloseAsync()); } // todo: check for cancellation AbstractChannelHandlerContext next = this.FindContextOutbound(); IEventExecutor nextExecutor = next.Executor; return(nextExecutor.InEventLoop ? next.InvokeDisconnectAsync() : SafeExecuteOutboundAsync(nextExecutor, () => next.InvokeDisconnectAsync())); }
public IChannelHandlerContext Flush() { AbstractChannelHandlerContext next = this.FindContextOutbound(); IEventExecutor nextExecutor = next.Executor; if (nextExecutor.InEventLoop) { next.InvokeFlush(); } else { nextExecutor.Execute(InvokeFlushAction, next); } return(this); }
/// <summary> /// Creates a new <see cref="FixedChannelPool"/> instance. /// </summary> /// <param name="bootstrap">The <see cref="Bootstrap"/> that is used for connections.</param> /// <param name="handler"> /// The <see cref="IChannelPoolHandler"/> that will be notified for the different pool actions. /// </param> /// <param name="healthChecker"> /// The <see cref="IChannelHealthChecker"/> that will be used to check if a <see cref="IChannel"/> is still /// healthy when obtained from the <see cref="IChannelPool"/>. /// </param> /// <param name="action"> /// The <see cref="AcquireTimeoutAction"/> to use or <c>null</c> if none should be used. In this case, /// <paramref name="acquireTimeout"/> must also be <c>null</c>. /// </param> /// <param name="acquireTimeout"> /// A <see cref="TimeSpan"/> after which an pending acquire must complete, or the /// <see cref="AcquireTimeoutAction"/> takes place. /// </param> /// <param name="maxConnections"> /// The number of maximal active connections. Once this is reached, new attempts to acquire an /// <see cref="IChannel"/> will be delayed until a connection is returned to the pool again. /// </param> /// <param name="maxPendingAcquires"> /// The maximum number of pending acquires. Once this is exceeded, acquire attempts will be failed. /// </param> /// <param name="releaseHealthCheck">If <c>true</c>, will check channel health before offering it back.</param> /// <param name="lastRecentUsed"> /// If <c>true</c>, <see cref="IChannel"/> selection will be LIFO. If <c>false</c>, it will be FIFO. /// </param> public FixedChannelPool(Bootstrap bootstrap, IChannelPoolHandler handler, IChannelHealthChecker healthChecker, AcquireTimeoutAction action, TimeSpan acquireTimeout, int maxConnections, int maxPendingAcquires, bool releaseHealthCheck, bool lastRecentUsed) : base(bootstrap, handler, healthChecker, releaseHealthCheck, lastRecentUsed) { if ((uint)(maxConnections - 1) > SharedConstants.TooBigOrNegative) { ThrowHelper.ThrowArgumentException_MaxConnections(maxConnections); } if ((uint)(maxPendingAcquires - 1) > SharedConstants.TooBigOrNegative) { ThrowHelper.ThrowArgumentException_MaxPendingAcquires(maxPendingAcquires); } _acquireTimeout = acquireTimeout; if (action == AcquireTimeoutAction.None && acquireTimeout == Timeout.InfiniteTimeSpan) { _timeoutTask = null; } else if (action == AcquireTimeoutAction.None && acquireTimeout != Timeout.InfiniteTimeSpan) { ThrowHelper.ThrowArgumentException_Action(); } else if (action != AcquireTimeoutAction.None && acquireTimeout < TimeSpan.Zero) { ThrowHelper.ThrowArgumentException_AcquireTimeoutMillis(acquireTimeout); } else { switch (action) { case AcquireTimeoutAction.Fail: _timeoutTask = new TimeoutTask(this, OnTimeoutFail); break; case AcquireTimeoutAction.New: _timeoutTask = new TimeoutTask(this, OnTimeoutNew); break; default: ThrowHelper.ThrowArgumentException_Action(); break; } } _executor = bootstrap.Group().GetNext(); _maxConnections = maxConnections; _maxPendingAcquires = maxPendingAcquires; _pendingAcquireQueue = PlatformDependent.NewMpscQueue <AcquireTask>(); }
public IChannelHandlerContext Read() { AbstractChannelHandlerContext next = this.FindContextOutbound(); IEventExecutor nextExecutor = next.Executor; if (nextExecutor.InEventLoop) { next.InvokeRead(); } else { // todo: consider caching task nextExecutor.Execute(InvokeReadAction, next); } return(this); }
public Task BindAsync(EndPoint localAddress) { Contract.Requires(localAddress != null); // todo: check for cancellation //if (!validatePromise(ctx, promise, false)) { // // promise cancelled // return; //} AbstractChannelHandlerContext next = this.FindContextOutbound(); IEventExecutor nextExecutor = next.Executor; return(nextExecutor.InEventLoop ? next.InvokeBindAsync(localAddress) : SafeExecuteOutboundAsync(nextExecutor, () => next.InvokeBindAsync(localAddress))); }
internal static void InvokeChannelRead(AbstractChannelHandlerContext next, object msg) { Contract.Requires(msg != null); object m = next.pipeline.Touch(msg, next); IEventExecutor nextExecutor = next.Executor; if (nextExecutor.InEventLoop) { next.InvokeChannelRead(m); } else { nextExecutor.Execute(InvokeChannelReadAction, next, msg); } }
private void _NotifyListeners() { IEventExecutor executor = Executor; if (executor.InEventLoop()) { // @TODO: 增加对调用堆栈深度的保护(避免出现堆栈溢出) try { _NotifyListenersNow(); } catch { } return; } _SafeExecute(executor, () => { _NotifyListenersNow(); }); }
/// <summary> /// Creates a new <see cref="FixedChannelPool"/> instance. /// </summary> /// <param name="bootstrap">The <see cref="Bootstrap"/> that is used for connections.</param> /// <param name="handler"> /// The <see cref="IChannelPoolHandler"/> that will be notified for the different pool actions. /// </param> /// <param name="healthChecker"> /// The <see cref="IChannelHealthChecker"/> that will be used to check if a <see cref="IChannel"/> is still /// healthy when obtained from the <see cref="IChannelPool"/>. /// </param> /// <param name="action"> /// The <see cref="AcquireTimeoutAction"/> to use or <c>null</c> if none should be used. In this case, /// <paramref name="acquireTimeout"/> must also be <c>null</c>. /// </param> /// <param name="acquireTimeout"> /// A <see cref="TimeSpan"/> after which an pending acquire must complete, or the /// <see cref="AcquireTimeoutAction"/> takes place. /// </param> /// <param name="maxConnections"> /// The number of maximal active connections. Once this is reached, new attempts to acquire an /// <see cref="IChannel"/> will be delayed until a connection is returned to the pool again. /// </param> /// <param name="maxPendingAcquires"> /// The maximum number of pending acquires. Once this is exceeded, acquire attempts will be failed. /// </param> /// <param name="releaseHealthCheck">If <c>true</c>, will check channel health before offering it back.</param> /// <param name="lastRecentUsed"> /// If <c>true</c>, <see cref="IChannel"/> selection will be LIFO. If <c>false</c>, it will be FIFO. /// </param> public FixedChannelPool(Bootstrap bootstrap, IChannelPoolHandler handler, IChannelHealthChecker healthChecker, AcquireTimeoutAction action, TimeSpan acquireTimeout, int maxConnections, int maxPendingAcquires, bool releaseHealthCheck, bool lastRecentUsed) : base(bootstrap, handler, healthChecker, releaseHealthCheck, lastRecentUsed) { if (maxConnections < 1) { throw new ArgumentException($"maxConnections: {maxConnections} (expected: >= 1)"); } if (maxPendingAcquires < 1) { throw new ArgumentException($"maxPendingAcquires: {maxPendingAcquires} (expected: >= 1)"); } this.acquireTimeout = acquireTimeout; if (action == AcquireTimeoutAction.None && acquireTimeout == Timeout.InfiniteTimeSpan) { this.timeoutTask = null; } else if (action == AcquireTimeoutAction.None && acquireTimeout != Timeout.InfiniteTimeSpan) { throw new ArgumentException("action"); } else if (action != AcquireTimeoutAction.None && acquireTimeout < TimeSpan.Zero) { throw new ArgumentException($"acquireTimeoutMillis: {acquireTimeout} (expected: >= 1)"); } else { switch (action) { case AcquireTimeoutAction.Fail: this.timeoutTask = new TimeoutTask(this, this.OnTimeoutFail); break; case AcquireTimeoutAction.New: this.timeoutTask = new TimeoutTask(this, this.OnTimeoutNew); break; default: throw new ArgumentException("action"); } } this.executor = bootstrap.Group().GetNext(); this.maxConnections = maxConnections; this.maxPendingAcquires = maxPendingAcquires; }
static void SafeExecuteOutbound(IEventExecutor executor, IRunnable task, TaskCompletionSource promise, object msg) { try { executor.Execute(task); } catch (Exception cause) { try { promise.TrySetException(cause); } finally { ReferenceCountUtil.Release(msg); } } }
internal override void Execute() { IEventExecutor executor = this.Ctx.Executor; if (executor.InEventLoop) { this.Pipeline.CallHandlerAdded0(this.Ctx); } else { try { executor.Execute(this); } catch { Remove0(this.Ctx); this.Ctx.SetRemoved(); } } }
internal override void Execute() { IEventExecutor executor = this.Ctx.Executor; if (executor.InEventLoop) { this.Pipeline.CallHandlerRemoved0(this.Ctx); } else { try { executor.Execute(this); } catch { // remove0(...) was call before so just call AbstractChannelHandlerContext.setRemoved(). this.Ctx.SetRemoved(); } } }
Task WriteAsync(object msg, bool flush) { AbstractChannelHandlerContext next = this.FindContextOutbound(); object m = this.pipeline.Touch(msg, next); IEventExecutor nextExecutor = next.Executor; if (nextExecutor.InEventLoop) { return(flush ? next.InvokeWriteAndFlushAsync(m) : next.InvokeWriteAsync(m)); } else { var promise = new TaskCompletionSource(); AbstractWriteTask task = flush ? WriteAndFlushTask.NewInstance(next, m, promise) : (AbstractWriteTask)WriteTask.NewInstance(next, m, promise); SafeExecuteOutbound(nextExecutor, task, promise, msg); return(promise.Task); } }
internal static void InvokeExceptionCaught(FABHandlerContext next, Exception cause) { Contract.Requires(cause != null); IEventExecutor nextExecutor = next.Executor; if (nextExecutor.InEventLoop) { next.InvokeExceptionCaught(cause); } else { try { nextExecutor.Execute((c, e) => ((FABHandlerContext)c).InvokeExceptionCaught((Exception)e), next, cause); } catch (Exception t) { throw t; } } }
void DestroyUp(AbstractChannelHandlerContext ctx) { Thread currentThread = Thread.CurrentThread; AbstractChannelHandlerContext tailContext = this.tail; while (true) { if (ctx == tailContext) { this.DestroyDown(currentThread, tailContext.Prev); break; } IEventExecutor executor = ctx.Executor; if (!executor.IsInEventLoop(currentThread)) { executor.Unwrap().Execute((self, c) => ((DefaultChannelPipeline)self).DestroyUp((AbstractChannelHandlerContext)c), this, ctx); break; } ctx = ctx.Next; } }
void DestroyUp(FABHandlerContext ctx, bool inEventLoop) { XThread currentThread = XThread.CurrentThread; FABHandlerContext tailContext = this.tail; while (true) { if (ctx == tailContext) { this.DestroyDown(currentThread, tailContext.Prev, inEventLoop); break; } IEventExecutor executor = ctx.Executor; if (!inEventLoop && !executor.IsInEventLoop(currentThread)) { executor.Execute((self, c) => ((FABChannelPipeline)self).DestroyUp((FABHandlerContext)c, true), this, ctx); break; } ctx = ctx.Next; inEventLoop = false; } }
public static bool TryGetCurrentExecutor(out IEventExecutor executor) { executor = currentExecutor; return(executor != null); }
public ExecutorTaskScheduler(IEventExecutor executor) { this.executor = executor; this.executorCallback = this.ExecutorCallback; }
public DefaultChannelHandlerInvoker(IEventExecutor executor) { Contract.Requires(executor != null); this.executor = executor; }
static async Task <Tuple <EmbeddedChannel, SslStream> > SetupStreamAndChannelAsync(bool isClient, IEventExecutor executor, IWriteStrategy writeStrategy, SslProtocols protocol, List <Task> writeTasks) { X509Certificate2 tlsCertificate = TestResourceHelper.GetTestCertificate(); string targetHost = tlsCertificate.GetNameInfo(X509NameType.DnsName, false); TlsHandler tlsHandler = isClient ? new TlsHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) => true), new ClientTlsSettings(targetHost)) : TlsHandler.Server(tlsCertificate); //var ch = new EmbeddedChannel(new LoggingHandler("BEFORE"), tlsHandler, new LoggingHandler("AFTER")); var ch = new EmbeddedChannel(tlsHandler); IByteBuffer readResultBuffer = Unpooled.Buffer(4 * 1024); Func <ArraySegment <byte>, Task <int> > readDataFunc = async output => { if (writeTasks.Count > 0) { await Task.WhenAll(writeTasks).WithTimeout(TestTimeout); writeTasks.Clear(); } if (readResultBuffer.ReadableBytes < output.Count) { await ReadOutboundAsync(async() => ch.ReadOutbound <IByteBuffer>(), output.Count - readResultBuffer.ReadableBytes, readResultBuffer, TestTimeout); } Assert.NotEqual(0, readResultBuffer.ReadableBytes); int read = Math.Min(output.Count, readResultBuffer.ReadableBytes); readResultBuffer.ReadBytes(output.Array, output.Offset, read); return(read); }; var mediationStream = new MediationStream(readDataFunc, input => { Task task = executor.SubmitAsync(() => writeStrategy.WriteToChannelAsync(ch, input)).Unwrap(); writeTasks.Add(task); return(task); }); var driverStream = new SslStream(mediationStream, true, (_1, _2, _3, _4) => true); if (isClient) { await Task.Run(() => driverStream.AuthenticateAsServerAsync(tlsCertificate)).WithTimeout(TimeSpan.FromSeconds(5)); } else { await Task.Run(() => driverStream.AuthenticateAsClientAsync(targetHost, null, protocol, false)).WithTimeout(TimeSpan.FromSeconds(5)); } writeTasks.Clear(); return(Tuple.Create(ch, driverStream)); }
public void SetUp(BenchmarkContext context) { _executor = CreateExecutor(); _executorThroughput = context.GetCounter(EventExecutorThroughputCounterName); }
internal static void SetCurrentExecutor(IEventExecutor executor) => currentExecutor = executor;
public EventExecutorTaskScheduler(IEventExecutor executor) { _executor = executor; }