public ReceiveTask(TcpConnection connection, PooledSegment segment) { _segment = segment; _connection = connection; }
private unsafe void Process(int id) { RIO_RESULT * results = stackalloc RIO_RESULT[maxResults]; uint bytes, key; NativeOverlapped *overlapped; var worker = _workers[id]; var completionPort = worker.completionPort; var cq = worker.completionQueue; PooledSegment cachedOKBuffer = worker.bufferPool.GetBuffer(); Buffer.BlockCopy(_okResponseBytes, 0, cachedOKBuffer.Buffer, cachedOKBuffer.Offset, _okResponseBytes.Length); cachedOKBuffer.RioBuffer.Length = (uint)_okResponseBytes.Length; worker.cachedOK = cachedOKBuffer.RioBuffer; PooledSegment cachedBusyBuffer = worker.bufferPool.GetBuffer(); Buffer.BlockCopy(_busyResponseBytes, 0, cachedBusyBuffer.Buffer, cachedBusyBuffer.Offset, _busyResponseBytes.Length); cachedBusyBuffer.RioBuffer.Length = (uint)_busyResponseBytes.Length; worker.cachedBusy = cachedBusyBuffer.RioBuffer; uint count; int ret; RIO_RESULT result; while (!_token.IsCancellationRequested) { _rio.Notify(cq); var sucess = GetQueuedCompletionStatus(completionPort, out bytes, out key, out overlapped, -1); if (sucess) { count = _rio.DequeueCompletion(cq, (IntPtr)results, maxResults); ret = _rio.Notify(cq); for (var i = 0; i < count; i++) { result = results[i]; if (result.RequestCorrelation == RIO.CachedValue) { // cached send response, don't release buffer } else if (result.RequestCorrelation < 0) { // first send 2 buffers are cached responses // so should next have a 0 for a send //worker.bufferPool.ReleaseBuffer((int)-result.RequestCorrelation); } else { // receive TcpConnection connection; if (worker.connections.TryGetValue(result.ConnectionCorrelation, out connection)) { connection.CompleteReceive(result.RequestCorrelation, result.BytesTransferred); } } } } else { var error = GetLastError(); if (error != 258) { throw new Exception(String.Format("ERROR: GetQueuedCompletionStatusEx returned {0}", error)); } } } cachedOKBuffer.Dispose(); cachedBusyBuffer.Dispose(); }