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); }
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(); } }
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(); } }
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; }
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(); }
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(); }
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; }