protected bool IncompleteWrite(bool scheduleAsync, SocketChannelAsyncOperation <TChannel, TUnsafe> operation) { // Did not write completely. if (scheduleAsync) { SetState(StateFlags.WriteScheduled); bool pending; using (ExecutionContext.IsFlowSuppressed() ? default(AsyncFlowControl?) : ExecutionContext.SuppressFlow()) { pending = Socket.SendAsync(operation); } if (!pending) { Unsafe.FinishWrite(operation); } return(pending); } else { // Schedule flush again later so other tasks can be picked up input the meantime EventLoop.Execute(FlushAction, this); return(true); } }
//protected override IChannelUnsafe NewUnsafe() => new SocketByteChannelUnsafe(this); ## 苦竹 屏蔽 ## protected override void ScheduleSocketRead() { var operation = ReadOperation; bool pending; #if NETCOREAPP || NETSTANDARD pending = Socket.ReceiveAsync(operation); #else if (ExecutionContext.IsFlowSuppressed()) { pending = Socket.ReceiveAsync(operation); } else { using (ExecutionContext.SuppressFlow()) { pending = Socket.ReceiveAsync(operation); } } #endif if (!pending) { // todo: potential allocation / non-static field? EventLoop.Execute(ReadCompletedSyncCallback, Unsafe, operation); } }
/// <summary> /// Schedules the send buffer to begin draining /// </summary> protected void Schedule() { //only schedule if we're idle if (Interlocked.Exchange(ref IsIdle, SendBufferProcessingStatus.Busy) == SendBufferProcessingStatus.Idle) { EventLoop.Execute(Run); } }
protected override void ScheduleSocketRead() { var operation = ReadOperation; var pending = Socket.ReceiveAsync(operation); if (!pending) { // todo: potential allocation / non-static field? EventLoop.Execute(ReadCompletedSyncCallback, Unsafe, operation); } }
protected override void DoBeginRead() { if (_readInProgress) { return; } var pipeline = Pipeline; var inboundBuffer = _inboundBuffer; if (!inboundBuffer.Any()) { _readInProgress = true; return; } var stackDepth = _stackDepth.Value; if (stackDepth < MAX_READER_STACK_DEPTH) { _stackDepth.Value = stackDepth + 1; try { while (true) { if (inboundBuffer.Count == 0) { break; } var received = inboundBuffer.Dequeue(); pipeline.FireChannelRead(received); } pipeline.FireChannelReadComplete(); } finally { _stackDepth.Value = stackDepth; } } else { try { EventLoop.Execute(_readTask); } catch (Exception) { ReleaseInboundBuffers(); throw; } } }
public LocalChannel Serve(LocalChannel peer) { var child = new LocalChannel(this, peer); if (EventLoop.InEventLoop) { Serve0(child); } else { EventLoop.Execute(ServeAction, this, child); } return(child); }
public LocalChannel Serve(LocalChannel peer) { LocalChannel child = NewLocalChannel(peer); if (EventLoop.InEventLoop) { Serve0(child); } else { EventLoop.Execute(() => Serve0(child)); } return(child); }
protected void Run() { if (WasDisposed || !IsOpen()) { return; } //Set the deadline timer for this run var deadlineTimer = Deadline.Now + Timeout; //we are about to process all enqueued messages HasUnsentMessages = false; //we should process x messages in this run var left = Throughput; NetworkData message; while (SendQueue.TryTake(out message)) { SendInternal(message.Buffer, 0, message.Length, message.RemoteHost); left--; if (WasDisposed) { return; } //if the deadline has expired, stop and break if (deadlineTimer.IsOverdue || left == 0) { break; //we're done for this run } } //there are still unsent messages that need to be processed if (SendQueue.Count > 0) { HasUnsentMessages = true; } if (HasUnsentMessages) { EventLoop.Execute(Run); } else { Interlocked.Exchange(ref IsIdle, SendBufferProcessingStatus.Idle); } }
protected override void ScheduleSocketRead() { var operation = ReadOperation; bool pending; using (ExecutionContext.IsFlowSuppressed() ? default(AsyncFlowControl?) : ExecutionContext.SuppressFlow()) { pending = Socket.ReceiveAsync(operation); } if (!pending) { // todo: potential allocation / non-static field? EventLoop.Execute(ReadCompletedSyncCallback, Unsafe, operation); } }
private void FireChannelWritabilityChanged(bool invokeLater) { var pipeline = _pipeline; if (invokeLater) { var task = _fireChannelWritabilityChangedTask; if (task is null) { _fireChannelWritabilityChangedTask = task = InvokeFireChannelWritabilityChangedAction; } EventLoop.Execute(task, pipeline); } else { _ = pipeline.FireChannelWritabilityChanged(); } }
protected override void DoBeginRead() { if (SharedConstants.False < (uint)Volatile.Read(ref v_readInProgress)) { return; } if (_inboundBuffer.IsEmpty) { _ = Interlocked.Exchange(ref v_readInProgress, SharedConstants.True); return; } InternalThreadLocalMap threadLocals = InternalThreadLocalMap.Get(); int stackDepth = threadLocals.LocalChannelReaderStackDepth; if (stackDepth < MAX_READER_STACK_DEPTH) { threadLocals.LocalChannelReaderStackDepth = stackDepth + 1; try { ReadInbound(); } finally { threadLocals.LocalChannelReaderStackDepth = stackDepth; } } else { try { EventLoop.Execute(InternalReadAction, this); } catch (Exception ex) { Logger.Warn("Closing Local channels {}-{} because exception occurred!", this, Volatile.Read(ref v_peer), ex); _ = CloseAsync(); _ = Volatile.Read(ref v_peer).CloseAsync(); throw; } } }
protected void IncompleteWrite(bool scheduleAsync, IByteBuf buffer) { // Did not write completely. if (scheduleAsync) { var operation = PrepareWriteOperation(buffer); SetState(StateFlags.WriteScheduled); var pending = Socket.SendAsync(operation); if (!pending) { ((ISocketChannelUnsafe)Unsafe).FinishWrite(operation); } } else { // Schedule flush again later so other tasks can be picked up input the meantime EventLoop.Execute(FlushAction, this); } }
protected bool IncompleteWrite(bool scheduleAsync, SocketChannelAsyncOperation <TChannel, TUnsafe> operation) { // Did not write completely. if (scheduleAsync) { SetState(StateFlags.WriteScheduled); bool pending; #if NETCOREAPP || NETSTANDARD pending = Socket.SendAsync(operation); #else if (ExecutionContext.IsFlowSuppressed()) { pending = Socket.SendAsync(operation); } else { using (ExecutionContext.SuppressFlow()) { pending = Socket.SendAsync(operation); } } #endif if (!pending) { Unsafe.FinishWrite(operation); // ## 苦竹 修改 ## ((ISocketChannelUnsafe)this.Unsafe).FinishWrite(operation); } return(pending); } else { // Schedule flush again later so other tasks can be picked up input the meantime EventLoop.Execute(FlushAction, this); return(true); } }