// This is called on the libuv event loop private void OnWriteCompleted(Queue<ArraySegment<byte>> writtenBuffers, UvWriteReq req, int status, Exception error) { KestrelTrace.Log.ConnectionWriteCallback(0, status); lock (_lockObj) { _lastWriteError = error; if (_nextWriteContext != null) { ScheduleWrite(); } else { _writesPending--; } foreach (var writeBuffer in writtenBuffers) { // _numBytesPreCompleted can temporarily go negative in the event there are // completed writes that we haven't triggered callbacks for yet. _numBytesPreCompleted -= writeBuffer.Count; } // bytesLeftToBuffer can be greater than _maxBytesPreCompleted // This allows large writes to complete once they've actually finished. var bytesLeftToBuffer = _maxBytesPreCompleted - _numBytesPreCompleted; while (_callbacksPending.Count > 0 && _callbacksPending.Peek().BytesToWrite <= bytesLeftToBuffer) { var callbackContext = _callbacksPending.Dequeue(); _numBytesPreCompleted += callbackContext.BytesToWrite; TriggerCallback(callbackContext); } // Now that the while loop has completed the following invariants should hold true: Trace.Assert(_numBytesPreCompleted >= 0); Trace.Assert(_numBytesPreCompleted <= _maxBytesPreCompleted); } req.Dispose(); }
public void ServerPipeDispatchConnections() { var pipeName = @"\\.\pipe\ServerPipeDispatchConnections" + Guid.NewGuid().ToString("n"); var loop = new UvLoopHandle(); loop.Init(_uv); var serverConnectionPipe = default(UvPipeHandle); var serverConnectionPipeAcceptedEvent = new ManualResetEvent(false); var serverConnectionTcpDisposedEvent = new ManualResetEvent(false); var serverListenPipe = new UvPipeHandle(); serverListenPipe.Init(loop, false); serverListenPipe.Bind(pipeName); serverListenPipe.Listen(128, (_1, status, error, _2) => { serverConnectionPipe = new UvPipeHandle(); serverConnectionPipe.Init(loop, true); try { serverListenPipe.Accept(serverConnectionPipe); serverConnectionPipeAcceptedEvent.Set(); } catch (Exception ex) { Console.WriteLine(ex); serverConnectionPipe.Dispose(); serverConnectionPipe = null; } }, null); var serverListenTcp = new UvTcpHandle(); serverListenTcp.Init(loop); serverListenTcp.Bind(new IPEndPoint(0, 54321)); serverListenTcp.Listen(128, (_1, status, error, _2) => { var serverConnectionTcp = new UvTcpHandle(); serverConnectionTcp.Init(loop); serverListenTcp.Accept(serverConnectionTcp); serverConnectionPipeAcceptedEvent.WaitOne(); var writeRequest = new UvWriteReq(); writeRequest.Init(loop); writeRequest.Write2( serverConnectionPipe, new ArraySegment<ArraySegment<byte>>(new ArraySegment<byte>[] { new ArraySegment<byte>(new byte[] { 1, 2, 3, 4 }) }), serverConnectionTcp, (_3, status2, error2, _4) => { writeRequest.Dispose(); serverConnectionTcp.Dispose(); serverConnectionTcpDisposedEvent.Set(); serverConnectionPipe.Dispose(); serverListenPipe.Dispose(); serverListenTcp.Dispose(); }, null); }, null); var worker = new Thread(() => { var loop2 = new UvLoopHandle(); var clientConnectionPipe = new UvPipeHandle(); var connect = new UvConnectRequest(); loop2.Init(_uv); clientConnectionPipe.Init(loop2, true); connect.Init(loop2); connect.Connect(clientConnectionPipe, pipeName, (_1, status, error, _2) => { connect.Dispose(); var buf = loop2.Libuv.buf_init(Marshal.AllocHGlobal(64), 64); serverConnectionTcpDisposedEvent.WaitOne(); clientConnectionPipe.ReadStart( (_3, cb, _4) => buf, (_3, status2, error2, _4) => { if (status2 == 0) { clientConnectionPipe.Dispose(); return; } var clientConnectionTcp = new UvTcpHandle(); clientConnectionTcp.Init(loop2); clientConnectionPipe.Accept(clientConnectionTcp); var buf2 = loop2.Libuv.buf_init(Marshal.AllocHGlobal(64), 64); clientConnectionTcp.ReadStart( (_5, cb, _6) => buf2, (_5, status3, error3, _6) => { if (status3 == 0) { clientConnectionTcp.Dispose(); } }, null); }, null); }, null); loop2.Run(); loop2.Dispose(); }); var worker2 = new Thread(() => { try { serverConnectionPipeAcceptedEvent.WaitOne(); var socket = new Socket(SocketType.Stream, ProtocolType.IP); socket.Connect(IPAddress.Loopback, 54321); socket.Send(new byte[] { 6, 7, 8, 9 }); socket.Shutdown(SocketShutdown.Send); var cb = socket.Receive(new byte[64]); socket.Dispose(); } catch(Exception ex) { Console.WriteLine(ex); } }); worker.Start(); worker2.Start(); loop.Run(); loop.Dispose(); worker.Join(); worker2.Join(); }
public void ServerPipeListenForConnections() { var loop = new UvLoopHandle(_logger); var serverListenPipe = new UvPipeHandle(_logger); loop.Init(_uv); serverListenPipe.Init(loop, false); serverListenPipe.Bind(@"\\.\pipe\ServerPipeListenForConnections"); serverListenPipe.Listen(128, (_1, status, error, _2) => { var serverConnectionPipe = new UvPipeHandle(_logger); serverConnectionPipe.Init(loop, true); try { serverListenPipe.Accept(serverConnectionPipe); } catch (Exception) { serverConnectionPipe.Dispose(); return; } var writeRequest = new UvWriteReq(new KestrelTrace(new TestKestrelTrace())); writeRequest.Init(loop); var block = MemoryPoolBlock2.Create( new ArraySegment<byte>(new byte[] { 1, 2, 3, 4 }), dataPtr: IntPtr.Zero, pool: null, slab: null); var start = new MemoryPoolIterator2(block, 0); var end = new MemoryPoolIterator2(block, block.Data.Count); writeRequest.Write( serverConnectionPipe, start, end, 1, (_3, status2, error2, _4) => { writeRequest.Dispose(); serverConnectionPipe.Dispose(); serverListenPipe.Dispose(); block.Unpin(); }, null); }, null); var worker = new Thread(() => { var loop2 = new UvLoopHandle(_logger); var clientConnectionPipe = new UvPipeHandle(_logger); var connect = new UvConnectRequest(new KestrelTrace(new TestKestrelTrace())); loop2.Init(_uv); clientConnectionPipe.Init(loop2, true); connect.Init(loop2); connect.Connect(clientConnectionPipe, @"\\.\pipe\ServerPipeListenForConnections", (_1, status, error, _2) => { var buf = loop2.Libuv.buf_init(Marshal.AllocHGlobal(8192), 8192); connect.Dispose(); clientConnectionPipe.ReadStart( (_3, cb, _4) => buf, (_3, status2, _4) => { if (status2 == 0) { clientConnectionPipe.Dispose(); } }, null); }, null); loop2.Run(); loop2.Dispose(); }); worker.Start(); loop.Run(); loop.Dispose(); worker.Join(); }
public void ServerPipeListenForConnections() { var loop = new UvLoopHandle(); var serverListenPipe = new UvPipeHandle(); loop.Init(_uv); serverListenPipe.Init(loop, false); serverListenPipe.Bind(@"\\.\pipe\ServerPipeListenForConnections"); serverListenPipe.Listen(128, (_1, status, error, _2) => { var serverConnectionPipe = new UvPipeHandle(); serverConnectionPipe.Init(loop, true); try { serverListenPipe.Accept(serverConnectionPipe); } catch (Exception) { serverConnectionPipe.Dispose(); return; } var writeRequest = new UvWriteReq(); writeRequest.Init(loop); writeRequest.Write( serverConnectionPipe, new ArraySegment<ArraySegment<byte>>(new ArraySegment<byte>[] { new ArraySegment<byte>(new byte[] { 1, 2, 3, 4 }) }), (_3, status2, error2, _4) => { writeRequest.Dispose(); serverConnectionPipe.Dispose(); serverListenPipe.Dispose(); }, null); }, null); var worker = new Thread(() => { var loop2 = new UvLoopHandle(); var clientConnectionPipe = new UvPipeHandle(); var connect = new UvConnectRequest(); loop2.Init(_uv); clientConnectionPipe.Init(loop2, true); connect.Init(loop2); connect.Connect(clientConnectionPipe, @"\\.\pipe\ServerPipeListenForConnections", (_1, status, error, _2) => { var buf = loop2.Libuv.buf_init(Marshal.AllocHGlobal(8192), 8192); connect.Dispose(); clientConnectionPipe.ReadStart( (_3, cb, _4) => buf, (_3, status2, error2, _4) => { if (status2 == 0) { clientConnectionPipe.Dispose(); } }, null); }, null); loop2.Run(); loop2.Dispose(); }); worker.Start(); loop.Run(); loop.Dispose(); worker.Join(); }
private void PoolWriteReq(UvWriteReq writeReq) { if (Self._writeReqPool.Count < MaxPooledWriteReqs) { Self._writeReqPool.Enqueue(writeReq); } else { writeReq.Dispose(); } }