public RIOTcpServer(ushort port, byte address1, byte address2, byte address3, byte address4) { var version = new RIOTcpServer.Version(2, 2); WSAData data; SocketError result = RIOImports.WSAStartup((short)version.Raw, out data); if (result != SocketError.Success) { var error = RIOImports.WSAGetLastError(); throw new Exception(String.Format("ERROR: WSAStartup returned {0}", error)); } _socket = RIOImports.WSASocket(ADDRESS_FAMILIES.AF_INET, SOCKET_TYPE.SOCK_STREAM, PROTOCOL.IPPROTO_TCP, IntPtr.Zero, 0, SOCKET_FLAGS.REGISTERED_IO); 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 RIOBufferPool(RIO rio) { _rio = rio; _allocatedBuffers = new ConcurrentQueue <AllocatedBuffer>(); _availableSegments = new ConcurrentQueue <int>(); _underlyingBuffer = new byte[BufferLength]; }
public RIOBufferPool(RIO rio) { _rio = rio; _allocatedBuffers = new ConcurrentQueue<AllocatedBuffer>(); _availableSegments = new ConcurrentQueue<int>(); _underlyingBuffer = new byte[BufferLength]; }
private bool disposedValue = false; // To detect redundant calls protected virtual void Dispose(bool disposing) { if (!disposedValue) { AllocatedBuffer buffer; while (_allocatedBuffers.TryDequeue(out buffer)) { _rio.DeregisterBuffer(buffer.BufferId); buffer.PinnedBuffer.Free(); } if (disposing) { _segments = null; _underlyingBuffer = null; _rio = null; _availableSegments = null; _allocatedBuffers = null; } disposedValue = true; } }
internal TcpConnection(IntPtr socket, long connectionId, WorkBundle wb, RIO rio) { _socket = socket; _connectionId = connectionId; _rio = rio; _wb = wb; _requestQueue = _rio.CreateRequestQueue(_socket, MaxPendingReceives, 1, MaxPendingSends, 1, wb.completionQueue, wb.completionQueue, connectionId); if (_requestQueue == IntPtr.Zero) { var error = RIOImports.WSAGetLastError(); RIOImports.WSACleanup(); throw new Exception(String.Format("ERROR: CreateRequestQueue returned {0}", error)); } _receiveTasks = new ReceiveTask[MaxPendingReceives]; _receiveRequestBuffers = new ArraySegment <byte> [MaxPendingReceives]; for (var i = 0; i < _receiveTasks.Length; i++) { _receiveTasks[i] = new ReceiveTask(this, wb.bufferPool.GetBuffer()); } _sendSegments = new PooledSegment[MaxPendingSends]; for (var i = 0; i < _sendSegments.Length; i++) { _sendSegments[i] = wb.bufferPool.GetBuffer(); } wb.connections.TryAdd(connectionId, this); for (var i = 0; i < _receiveTasks.Length; i++) { PostReceive(i); } }
internal TcpConnection(IntPtr socket, long connectionId, WorkBundle wb, RIO rio) { _socket = socket; _connectionId = connectionId; _rio = rio; _wb = wb; _requestQueue = _rio.CreateRequestQueue(_socket, MaxPendingReceives, 1, MaxPendingSends, 1, wb.completionQueue, wb.completionQueue, connectionId); if (_requestQueue == IntPtr.Zero) { var error = RIOImports.WSAGetLastError(); RIOImports.WSACleanup(); throw new Exception(String.Format("ERROR: CreateRequestQueue returned {0}", error)); } _receiveTasks = new ReceiveTask[MaxPendingReceives]; _receiveRequestBuffers = new ArraySegment<byte>[MaxPendingReceives]; for (var i = 0; i < _receiveTasks.Length; i++) { _receiveTasks[i] = new ReceiveTask(this, wb.bufferPool.GetBuffer()); } _sendSegments = new PooledSegment[MaxPendingSends]; for (var i = 0; i < _sendSegments.Length; i++) { _sendSegments[i] = wb.bufferPool.GetBuffer(); } wb.connections.TryAdd(connectionId, this); for (var i = 0; i < _receiveTasks.Length; i++) { PostReceive(i); } }
public unsafe static RIO Initalize(IntPtr socket) { UInt32 dwBytes = 0; RIO_EXTENSION_FUNCTION_TABLE rio = new RIO_EXTENSION_FUNCTION_TABLE(); Guid RioFunctionsTableId = new Guid("8509e081-96dd-4005-b165-9e2ee8c79e3f"); int True = -1; int result = setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char *)&True, 4); if (result != 0) { var error = RIOImports.WSAGetLastError(); RIOImports.WSACleanup(); throw new Exception(String.Format("ERROR: setsockopt TCP_NODELAY returned {0}", error)); } result = WSAIoctlGeneral(socket, SIO_LOOPBACK_FAST_PATH, &True, 4, null, 0, out dwBytes, IntPtr.Zero, IntPtr.Zero); if (result != 0) { var error = RIOImports.WSAGetLastError(); RIOImports.WSACleanup(); throw new Exception(String.Format("ERROR: WSAIoctl SIO_LOOPBACK_FAST_PATH returned {0}", error)); } result = WSAIoctl(socket, SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER, ref RioFunctionsTableId, 16, ref rio, sizeof(RIO_EXTENSION_FUNCTION_TABLE), out dwBytes, IntPtr.Zero, IntPtr.Zero); if (result != 0) { var error = RIOImports.WSAGetLastError(); RIOImports.WSACleanup(); throw new Exception(String.Format("ERROR: RIOInitalize returned {0}", error)); } else { RIO rioFunctions = new RIO(); rioFunctions.RegisterBuffer = Marshal.GetDelegateForFunctionPointer <RIORegisterBuffer>(rio.RIORegisterBuffer); rioFunctions.CreateCompletionQueue = Marshal.GetDelegateForFunctionPointer <RIOCreateCompletionQueue>(rio.RIOCreateCompletionQueue); rioFunctions.CreateRequestQueue = Marshal.GetDelegateForFunctionPointer <RIOCreateRequestQueue>(rio.RIOCreateRequestQueue); rioFunctions.Notify = Marshal.GetDelegateForFunctionPointer <RIONotify>(rio.RIONotify); rioFunctions.DequeueCompletion = Marshal.GetDelegateForFunctionPointer <RIODequeueCompletion>(rio.RIODequeueCompletion); rioFunctions.Receive = Marshal.GetDelegateForFunctionPointer <RIOReceive>(rio.RIOReceive); rioFunctions.Send = Marshal.GetDelegateForFunctionPointer <RIOSend>(rio.RIOSend); rioFunctions.CloseCompletionQueue = Marshal.GetDelegateForFunctionPointer <RIOCloseCompletionQueue>(rio.RIOCloseCompletionQueue); rioFunctions.DeregisterBuffer = Marshal.GetDelegateForFunctionPointer <RIODeregisterBuffer>(rio.RIODeregisterBuffer); rioFunctions.ResizeCompletionQueue = Marshal.GetDelegateForFunctionPointer <RIOResizeCompletionQueue>(rio.RIOResizeCompletionQueue); rioFunctions.ResizeRequestQueue = Marshal.GetDelegateForFunctionPointer <RIOResizeRequestQueue>(rio.RIOResizeRequestQueue); return(rioFunctions); } }
public unsafe RIOThreadPool(RIO rio, IntPtr socket, CancellationToken token) { _socket = socket; _rio = rio; _token = token; _maxThreads = Environment.ProcessorCount; _workers = new WorkBundle[_maxThreads]; for (var i = 0; i < _workers.Length; i++) { var worker = new WorkBundle() { id = i, bufferPool = new RIOBufferPool(_rio) }; worker.completionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, IntPtr.Zero, 0, 0); if (worker.completionPort == IntPtr.Zero) { var error = GetLastError(); RIOImports.WSACleanup(); throw new Exception(String.Format("ERROR: CreateIoCompletionPort returned {0}", error)); } var completionMethod = new RIO_NOTIFICATION_COMPLETION() { Type = RIO_NOTIFICATION_COMPLETION_TYPE.IOCP_COMPLETION, Iocp = new RIO_NOTIFICATION_COMPLETION_IOCP() { IocpHandle = worker.completionPort, QueueCorrelation = (ulong)i, Overlapped = (NativeOverlapped*)(-1)// nativeOverlapped } }; worker.completionQueue = _rio.CreateCompletionQueue(MaxOutsandingCompletions, completionMethod); if (worker.completionQueue == IntPtr.Zero) { var error = RIOImports.WSAGetLastError(); RIOImports.WSACleanup(); throw new Exception(String.Format("ERROR: CreateCompletionQueue returned {0}", error)); } worker.connections = new ConcurrentDictionary<long, TcpConnection>(); worker.thread = new Thread(GetThreadStart(i)); worker.thread.IsBackground = true; _workers[i] = worker; } // gc //GC.Collect(2, GCCollectionMode.Forced, true, true); //GC.WaitForPendingFinalizers(); //GC.Collect(2, GCCollectionMode.Forced, true, true); GC.Collect(2, GCCollectionMode.Forced, true); GC.WaitForPendingFinalizers(); GC.Collect(2, GCCollectionMode.Forced, true); for (var i = 0; i < _workers.Length; i++) { // pin buffers _workers[i].bufferPool.Initalize(); } for (var i = 0; i < _workers.Length; i++) { _workers[i].thread.Start(); } }
public unsafe RIOThreadPool(RIO rio, IntPtr socket, CancellationToken token) { _socket = socket; _rio = rio; _token = token; _maxThreads = Environment.ProcessorCount; _workers = new WorkBundle[_maxThreads]; for (var i = 0; i < _workers.Length; i++) { var worker = new WorkBundle() { id = i, bufferPool = new RIOBufferPool(_rio) }; worker.completionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, IntPtr.Zero, 0, 0); if (worker.completionPort == IntPtr.Zero) { var error = GetLastError(); RIOImports.WSACleanup(); throw new Exception(String.Format("ERROR: CreateIoCompletionPort returned {0}", error)); } var completionMethod = new RIO_NOTIFICATION_COMPLETION() { Type = RIO_NOTIFICATION_COMPLETION_TYPE.IOCP_COMPLETION, Iocp = new RIO_NOTIFICATION_COMPLETION_IOCP() { IocpHandle = worker.completionPort, QueueCorrelation = (ulong)i, Overlapped = (NativeOverlapped *)(-1)// nativeOverlapped } }; worker.completionQueue = _rio.CreateCompletionQueue(MaxOutsandingCompletions, completionMethod); if (worker.completionQueue == IntPtr.Zero) { var error = RIOImports.WSAGetLastError(); RIOImports.WSACleanup(); throw new Exception(String.Format("ERROR: CreateCompletionQueue returned {0}", error)); } worker.connections = new ConcurrentDictionary <long, TcpConnection>(); worker.thread = new Thread(GetThreadStart(i)); worker.thread.IsBackground = true; _workers[i] = worker; } // gc //GC.Collect(2, GCCollectionMode.Forced, true, true); //GC.WaitForPendingFinalizers(); //GC.Collect(2, GCCollectionMode.Forced, true, true); GC.Collect(2, GCCollectionMode.Forced, true); GC.WaitForPendingFinalizers(); GC.Collect(2, GCCollectionMode.Forced, true); for (var i = 0; i < _workers.Length; i++) { // pin buffers _workers[i].bufferPool.Initalize(); } for (var i = 0; i < _workers.Length; i++) { _workers[i].thread.Start(); } }
public unsafe static RIO Initalize(IntPtr socket) { UInt32 dwBytes = 0; RIO_EXTENSION_FUNCTION_TABLE rio = new RIO_EXTENSION_FUNCTION_TABLE(); Guid RioFunctionsTableId = new Guid("8509e081-96dd-4005-b165-9e2ee8c79e3f"); int True = -1; int result = setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char*)&True, 4); if (result != 0) { var error = RIOImports.WSAGetLastError(); RIOImports.WSACleanup(); throw new Exception(String.Format("ERROR: setsockopt TCP_NODELAY returned {0}", error)); } result = WSAIoctlGeneral(socket, SIO_LOOPBACK_FAST_PATH, &True, 4, null, 0, out dwBytes, IntPtr.Zero, IntPtr.Zero); if (result != 0) { var error = RIOImports.WSAGetLastError(); RIOImports.WSACleanup(); throw new Exception(String.Format("ERROR: WSAIoctl SIO_LOOPBACK_FAST_PATH returned {0}", error)); } result = WSAIoctl(socket, SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER, ref RioFunctionsTableId, 16, ref rio, sizeof(RIO_EXTENSION_FUNCTION_TABLE), out dwBytes, IntPtr.Zero, IntPtr.Zero); if (result != 0) { var error = RIOImports.WSAGetLastError(); RIOImports.WSACleanup(); throw new Exception(String.Format("ERROR: RIOInitalize returned {0}", error)); } else { RIO rioFunctions = new RIO(); rioFunctions.RegisterBuffer = Marshal.GetDelegateForFunctionPointer<RIORegisterBuffer>(rio.RIORegisterBuffer); rioFunctions.CreateCompletionQueue = Marshal.GetDelegateForFunctionPointer<RIOCreateCompletionQueue>(rio.RIOCreateCompletionQueue); rioFunctions.CreateRequestQueue = Marshal.GetDelegateForFunctionPointer<RIOCreateRequestQueue>(rio.RIOCreateRequestQueue); rioFunctions.Notify = Marshal.GetDelegateForFunctionPointer<RIONotify>(rio.RIONotify); rioFunctions.DequeueCompletion = Marshal.GetDelegateForFunctionPointer<RIODequeueCompletion>(rio.RIODequeueCompletion); rioFunctions.Receive = Marshal.GetDelegateForFunctionPointer<RIOReceive>(rio.RIOReceive); rioFunctions.Send = Marshal.GetDelegateForFunctionPointer<RIOSend>(rio.RIOSend); rioFunctions.CloseCompletionQueue = Marshal.GetDelegateForFunctionPointer<RIOCloseCompletionQueue>(rio.RIOCloseCompletionQueue); rioFunctions.DeregisterBuffer = Marshal.GetDelegateForFunctionPointer<RIODeregisterBuffer>(rio.RIODeregisterBuffer); rioFunctions.ResizeCompletionQueue = Marshal.GetDelegateForFunctionPointer<RIOResizeCompletionQueue>(rio.RIOResizeCompletionQueue); rioFunctions.ResizeRequestQueue = Marshal.GetDelegateForFunctionPointer<RIOResizeRequestQueue>(rio.RIOResizeRequestQueue); return rioFunctions; } }