private unsafe void Complete(RioRequestResult *results, uint count, RioTcpConnection[] connectionsToSignal) { for (var i = 0; i < count; i++) { var result = results[i]; RioTcpConnection connection; bool found; lock (_connections) { found = _connections.TryGetValue(result.ConnectionCorrelation, out connection); } if (found) { if (result.RequestCorrelation >= 0) { connection.ReceiveBeginComplete(result.BytesTransferred); connectionsToSignal[i] = connection; } else { connection.SendComplete(result.RequestCorrelation); connectionsToSignal[i] = null; } } else { connectionsToSignal[i] = null; } } }
private void ProcessPhysicalCompletions() { RioRequestResult *results = stackalloc RioRequestResult[maxResults]; var connectionsToSignal = new RioTcpConnection[maxResults]; _rio.Notify(ReceiveCompletionQueue); while (!_token.IsCancellationRequested) { NativeOverlapped *overlapped; uint bytes, key; var success = GetQueuedCompletionStatus(CompletionPort, out bytes, out key, out overlapped, -1); if (success) { var activatedNotify = false; while (true) { var count = _rio.DequeueCompletion(ReceiveCompletionQueue, (IntPtr)results, maxResults); if (count == 0) { if (!activatedNotify) { activatedNotify = true; _rio.Notify(ReceiveCompletionQueue); continue; } break; } Complete(results, count, connectionsToSignal); Notify(connectionsToSignal, count); if (!activatedNotify) { activatedNotify = true; _rio.Notify(ReceiveCompletionQueue); } } } else { var error = GetLastError(); if (error != 258) { throw new Exception($"ERROR: GetQueuedCompletionStatusEx returned {error}"); } } } }
private static void OnThreadStart(object state) { const int maxResults = 1024; var thread = ((RioThread)state); var rio = thread._rio; var token = thread._token; RioRequestResult *results = stackalloc RioRequestResult[maxResults]; uint bytes, key; NativeOverlapped *overlapped; var completionPort = thread.CompletionPort; var completionQueue = thread.ReceiveCompletionQueue; uint count; while (!token.IsCancellationRequested) { rio.Notify(completionQueue); var success = GetQueuedCompletionStatus(completionPort, out bytes, out key, out overlapped, -1); if (success) { while ((count = rio.DequeueCompletion(completionQueue, (IntPtr)results, maxResults)) > 0) { for (var i = 0; i < count; i++) { var result = results[i]; RioTcpConnection connection; if (thread._connections.TryGetValue(result.ConnectionCorrelation, out connection)) { connection.Complete(result.RequestCorrelation, result.BytesTransferred); } } } } else { var error = GetLastError(); if (error != 258) { throw new Exception(string.Format("ERROR: GetQueuedCompletionStatusEx returned {0}", error)); } } } }
private void ProcessLogicalCompletions() { RioRequestResult *results = stackalloc RioRequestResult[maxResults]; _rio.Notify(ReceiveCompletionQueue); while (!_token.IsCancellationRequested) { NativeOverlapped *overlapped; uint bytes, key; var success = GetQueuedCompletionStatus(CompletionPort, out bytes, out key, out overlapped, -1); if (success) { var activatedNotify = false; while (true) { var count = _rio.DequeueCompletion(ReceiveCompletionQueue, (IntPtr)results, maxResults); if (count == 0) { if (!activatedNotify) { activatedNotify = true; _rio.Notify(ReceiveCompletionQueue); continue; } break; } var gotBatch = false; var batch = default(NotifyBatch); lock (_processedBatches) { if (_processedBatches.Count > 0) { batch = _processedBatches.Dequeue(); batch.Count = count; gotBatch = true; } } if (!gotBatch) { batch = new NotifyBatch() { ConnectionsToSignal = new RioTcpConnection[maxResults], Count = count }; } var connectionsToSignal = batch.ConnectionsToSignal; Complete(results, count, connectionsToSignal); lock (_notify) { _notifyBatches.Enqueue(batch); Monitor.Pulse(_notify); } if (!activatedNotify) { activatedNotify = true; _rio.Notify(ReceiveCompletionQueue); } } } else { var error = GetLastError(); if (error != 258) { throw new Exception($"ERROR: GetQueuedCompletionStatusEx returned {error}"); } } } }