private unsafe void AcceptThreadStart(object state) { try { var socket = _socket; using (socket) { using (EPoll epoll = EPoll.Create()) { int epollFd = epoll.DangerousGetHandle().ToInt32(); const int acceptKey = 0; const int pipeKey = 1; // accept socket epoll.Control(EPollOperation.Add, _socket, EPollEvents.Readable, new EPollData { Int1 = acceptKey, Int2 = acceptKey }); // add pipe epoll.Control(EPollOperation.Add, _pipeEnds.ReadEnd, EPollEvents.Readable, new EPollData { Int1 = pipeKey, Int2 = pipeKey }); const int EventBufferLength = 1; int notPacked = !EPoll.PackedEvents ? 1 : 0; var buffer = stackalloc int[EventBufferLength * (3 + notPacked)]; int * key = &buffer[2]; bool running = true; int nextHandler = 0; var handlers = _handlers; do { int numEvents = EPollInterop.EPollWait(epollFd, buffer, EventBufferLength, timeout: EPoll.TimeoutInfinite).Value; if (numEvents == 1) { if (*key == acceptKey) { var handler = handlers[nextHandler]; nextHandler = (nextHandler + 1) % handlers.Length; socket.TryAcceptAndSendHandleTo(handler); } else { running = false; } } } while (running); } } _stoppedTcs.TrySetResult(null); } catch (Exception e) { _stoppedTcs.SetException(e); } finally { Cleanup(); } }
private unsafe void AcceptThreadStart(object state) { try { var socket = _socket; using (socket) { using (EPoll epoll = EPoll.Create()) { int epollFd = epoll.DangerousGetHandle().ToInt32(); const int acceptKey = 0; const int pipeKey = 1; // accept socket epoll.Control(EPOLL_CTL_ADD, _socket, EPOLLIN, acceptKey); // add pipe epoll.Control(EPOLL_CTL_ADD, _pipeEnds.ReadEnd, EPOLLIN, pipeKey); epoll_event ev; bool running = true; int nextHandler = 0; var handlers = _handlers; do { int numEvents = EPollInterop.EPollWait(epollFd, &ev, 1, timeout: EPoll.TimeoutInfinite).IntValue; if (numEvents == 1) { if (ev.data.fd == acceptKey) { var handler = handlers[nextHandler]; nextHandler = (nextHandler + 1) % handlers.Length; socket.TryAcceptAndSendHandleTo(handler); } else { running = false; } } } while (running); } } _stoppedTcs.TrySetResult(null); } catch (Exception e) { _stoppedTcs.SetException(e); } finally { Cleanup(); } }