Exemplo n.º 1
0
        public RioTcpServer(ushort port, byte address1, byte address2, byte address3, byte address4)
        {
            var version = new Internal.Winsock.Version(2, 2);
            WindowsSocketsData wsaData;

            System.Net.Sockets.SocketError result = RioImports.WSAStartup((short)version.Raw, out wsaData);
            if (result != System.Net.Sockets.SocketError.Success)
            {
                var error = RioImports.WSAGetLastError();
                throw new Exception(string.Format("ERROR: WSAStartup returned {0}", error));
            }

            _socket = RioImports.WSASocket(AddressFamilies.Internet, SocketType.Stream, Protocol.IpProtocolTcp, IntPtr.Zero, 0, SocketFlags.RegisteredIO);
            if (_socket == IntPtr.Zero)
            {
                var error = RioImports.WSAGetLastError();
                RioImports.WSACleanup();
                throw new Exception(string.Format("ERROR: WSASocket returned {0}", error));
            }

            _rio = RioImports.Initalize(_socket);


            _pool         = new RioThreadPool(_rio, _socket, CancellationToken.None);
            _connectionId = 0;
            Start(port, address1, address2, address3, address4);
        }
Exemplo n.º 2
0
        public unsafe RioThreadPool(RegisteredIO rio, IntPtr socket, CancellationToken token)
        {
            _socket = socket;
            _rio    = rio;
            _token  = token;

            // Count non-HT cores only
            var procCount = CpuInfo.PhysicalCoreCount;

            // RSS only supports up to 16 cores
            _maxThreads = procCount > 16 ? 16 : procCount;

            _rioThreads = new RioThread[_maxThreads];
            for (var i = 0; i < _rioThreads.Length; i++)
            {
                IntPtr completionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, IntPtr.Zero, 0, 0);

                if (completionPort == IntPtr.Zero)
                {
                    var error = GetLastError();
                    RioImports.WSACleanup();
                    throw new Exception($"ERROR: CreateIoCompletionPort returned {error}");
                }

                var completionMethod = new NotificationCompletion
                {
                    Type = NotificationCompletionType.IocpCompletion,
                    Iocp = new NotificationCompletionIocp
                    {
                        IocpHandle       = completionPort,
                        QueueCorrelation = (ulong)i,
                        Overlapped       = (NativeOverlapped *)(-1) // nativeOverlapped
                    }
                };

                IntPtr completionQueue = _rio.RioCreateCompletionQueue(RioTcpServer.MaxOutsandingCompletionsPerThread,
                                                                       completionMethod);

                if (completionQueue == IntPtr.Zero)
                {
                    var error = RioImports.WSAGetLastError();
                    RioImports.WSACleanup();
                    throw new Exception($"ERROR: RioCreateCompletionQueue returned {error}");
                }

                var thread = new RioThread(i, _token, completionPort, completionQueue, rio);
                _rioThreads[i] = thread;
            }

            for (var i = 0; i < _rioThreads.Length; i++)
            {
                var thread = _rioThreads[i];
                thread.Start();
            }
        }
Exemplo n.º 3
0
        public unsafe RioThreadPool(RegisteredIO rio, IntPtr socket, CancellationToken token)
        {
            _socket = socket;
            _rio    = rio;
            _token  = token;

            _maxThreads = Environment.ProcessorCount;

            _rioThreads = new RioThread[_maxThreads];
            for (var i = 0; i < _rioThreads.Length; i++)
            {
                IntPtr completionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, IntPtr.Zero, 0, 0);

                if (completionPort == IntPtr.Zero)
                {
                    var error = GetLastError();
                    RioImports.WSACleanup();
                    throw new Exception(string.Format("ERROR: CreateIoCompletionPort returned {0}", error));
                }

                var completionMethod = new NotificationCompletion()
                {
                    Type = NotificationCompletionType.IocpCompletion,
                    Iocp = new NotificationCompletionIocp()
                    {
                        IocpHandle       = completionPort,
                        QueueCorrelation = (ulong)i,
                        Overlapped       = (NativeOverlapped *)(-1)// nativeOverlapped
                    }
                };

                IntPtr completionQueue = _rio.RioCreateCompletionQueue(RioTcpServer.MaxOutsandingCompletionsPerThread, completionMethod);

                if (completionQueue == IntPtr.Zero)
                {
                    var error = RioImports.WSAGetLastError();
                    RioImports.WSACleanup();
                    throw new Exception(String.Format("ERROR: RioCreateCompletionQueue returned {0}", error));
                }

                var thread = new RioThread(i, _token, completionPort, completionQueue, rio);
                _rioThreads[i] = thread;
            }

            for (var i = 0; i < _rioThreads.Length; i++)
            {
                var thread = _rioThreads[i];
                thread.Start();
            }
        }
Exemplo n.º 4
0
 public RioThread(int id, CancellationToken token, IntPtr completionPort, IntPtr completionQueue, RegisteredIO rio)
 {
     _id         = id;
     _rio        = rio;
     _token      = token;
     _memoryPool = new MemoryPool();
     _memoryPool.RegisterSlabAllocationCallback(OnSlabAllocated);
     _memoryPool.RegisterSlabDeallocationCallback(OnSlabDeallocated);
     _channelFactory      = new ChannelFactory(_memoryPool);
     _connections         = new ConcurrentDictionary <long, RioTcpConnection>();
     _thread              = new Thread(OnThreadStart);
     _thread.Name         = "RIOThread " + id;
     _thread.IsBackground = true;
     _completionPort      = completionPort;
     _completionQueue     = completionQueue;
 }
Exemplo n.º 5
0
        internal RioTcpConnection(IntPtr socket, long connectionId, IntPtr requestQueue, RioThread rioThread, RegisteredIO rio)
        {
            _socket       = socket;
            _connectionId = connectionId;
            _rio          = rio;
            _rioThread    = rioThread;

            _input  = new ResetablePipe(new PipeOptions(rioThread.Pool));
            _output = new ResetablePipe(new PipeOptions(rioThread.Pool));

            _requestQueue = requestQueue;

            rioThread.AddConnection(connectionId, this);

            ProcessReceives();
            _sendTask = ProcessSends();
        }
Exemplo n.º 6
0
        internal RioTcpConnection(IntPtr socket, long connectionId, IntPtr requestQueue, RioThread rioThread, RegisteredIO rio)
        {
            _socket       = socket;
            _connectionId = connectionId;
            _rio          = rio;
            _rioThread    = rioThread;

            _input  = rioThread.PipelineFactory.Create();
            _output = rioThread.PipelineFactory.Create();

            _requestQueue = requestQueue;

            rioThread.AddConnection(connectionId, this);

            ProcessReceives();
            _sendTask = ProcessSends();
        }
Exemplo n.º 7
0
        public RioThread(int id, CancellationToken token, IntPtr completionPort, IntPtr completionQueue, RegisteredIO rio)
        {
            _id    = id;
            _rio   = rio;
            _token = token;

            if (CpuInfo.LogicalProcessorCount > CpuInfo.PhysicalCoreCount)
            {
                _completionThread = new Thread(RunLogicalCompletions)
                {
                    Name         = $"RIO Completion Thread {id:00}",
                    IsBackground = true
                };

                _notifyBatches = new Queue <NotifyBatch>(16);
                _notify        = new object();

                _notifyThread = new Thread(RunNotifies)
                {
                    Name         = $"RIO Notify Thread {id:00}",
                    IsBackground = true
                };
                _processedBatches = new Queue <NotifyBatch>(16);
            }
            else
            {
                _completionThread = new Thread(RunPhysicalCompletions)
                {
                    Name         = $"RIO Completion Thread {id:00}",
                    IsBackground = true
                };
            }

            _completionPort  = completionPort;
            _completionQueue = completionQueue;
        }