Exemplo n.º 1
0
        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;
                }
            }
        }
Exemplo n.º 2
0
        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}");
                    }
                }
            }
        }
Exemplo n.º 3
0
        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));
                    }
                }
            }
        }
Exemplo n.º 4
0
        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}");
                    }
                }
            }
        }