public bool HandleSocketEvents(int numEvents) { bool enqueuedEvent = false; foreach (var socketEvent in new ReadOnlySpan <Interop.Sys.SocketEvent>(Buffer, numEvents)) { if (_handleToContextMap.TryGetValue(socketEvent.Data, out SocketAsyncContextWrapper contextWrapper)) { SocketAsyncContext context = contextWrapper.Context; if (context.PreferInlineCompletions) { context.HandleEventsInline(socketEvent.Events); } else { Interop.Sys.SocketEvents events = context.HandleSyncEventsSpeculatively(socketEvent.Events); if (events != Interop.Sys.SocketEvents.None) { _eventQueue.Enqueue(new SocketIOEvent(context, events)); enqueuedEvent = true; } } } } return(enqueuedEvent); }
// // Allocates a new {SocketAsyncEngine, handle} pair. // private static void AllocateToken(SocketAsyncContext context, out SocketAsyncEngine engine, out IntPtr handle) { lock (s_lock) { if (s_currentEngine == null) { s_currentEngine = new SocketAsyncEngine(); } engine = s_currentEngine; handle = s_currentEngine.AllocateHandle(context); } }
private void EventLoop() { try { bool shutdown = false; while (!shutdown) { int numEvents = EventBufferCount; Interop.Error err = Interop.Sys.WaitForSocketEvents(_port, _buffer, &numEvents); if (err != Interop.Error.SUCCESS) { throw new InternalException(); } // The native shim is responsible for ensuring this condition. Debug.Assert(numEvents > 0, $"Unexpected numEvents: {numEvents}"); for (int i = 0; i < numEvents; i++) { IntPtr handle = _buffer[i].Data; if (handle == ShutdownHandle) { shutdown = true; } else { SocketAsyncContext context = GetContextFromHandle(handle); if (context != null) { context.HandleEvents(_buffer[i].Events); } } } } FreeNativeResources(); } catch (Exception e) { Environment.FailFast("Exception thrown from SocketAsyncEngine event loop: " + e.ToString(), e); } }
private IntPtr AllocateHandle(SocketAsyncContext context) { Debug.Assert(Monitor.IsEntered(s_lock), "Expected s_lock to be held"); Debug.Assert(!IsFull, "Expected !IsFull"); IntPtr handle = _nextHandle; _handleToContextMap.Add(handle, context); _nextHandle = IntPtr.Add(_nextHandle, 1); _outstandingHandles = IntPtr.Add(_outstandingHandles, 1); if (IsFull) { // We'll need to create a new event port for the next handle. s_currentEngine = null; } Debug.Assert(handle != ShutdownHandle, $"Expected handle != ShutdownHandle: {handle}"); return(handle); }
public Token(SocketAsyncContext context) { AllocateToken(context, out _engine, out _handle); }
public SocketIOEvent(SocketAsyncContext context, Interop.Sys.SocketEvents events) { Context = context; Events = events; }
public SocketAsyncContextWrapper(SocketAsyncContext context) => Context = context;