/// <summary> /// Tries to initialize the Registered I/O handle. /// </summary> /// <param name="socket">A descriptor that identifies a socket.</param> /// <param name="result">Contains valid object if operation was successful, <c>null</c> otherwise.</param> /// <returns><c>true</c> if operation was successful, <c>false</c> otherwise.</returns> public static unsafe Boolean TryCreate(SOCKET socket, out RIOHandle result) { // get function table id var functionTableId = WinsockInterop.WSAID_MULTIPLE_RIO; // initialize functions table var functionTable = new RIO_EXTENSION_FUNCTION_TABLE(); // get table size var tableSize = (UInt32)sizeof(RIO_EXTENSION_FUNCTION_TABLE); // will contain actual table size UInt32 actualTableSize; // try get registered IO functions table var tryGetTableResult = WinsockInterop.WSAIoctl(socket, WinsockInterop.SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER, &functionTableId, 16, &functionTable, tableSize, out actualTableSize, IntPtr.Zero, IntPtr.Zero); // check if attempt was successful if (tryGetTableResult == WinsockInterop.SOCKET_ERROR) { result = null; // return fail return(false); } // create registered I/O handle result = new RIOHandle(ref functionTable); // return success return(true); }
private static extern int WSAIoctl( [In] IntPtr socket, [In] uint dwIoControlCode, [In] ref Guid lpvInBuffer, [In] uint cbInBuffer, [In, Out] ref RIO_EXTENSION_FUNCTION_TABLE lpvOutBuffer, [In] int cbOutBuffer, [Out] out uint lpcbBytesReturned, [In] IntPtr lpOverlapped, [In] IntPtr lpCompletionRoutine );
/// <summary> /// Initializes a new instance of <see cref="RIOHandle" /> class. /// </summary> /// <param name="table">The reference to the table of the functions pointers.</param> public RIOHandle(ref RIO_EXTENSION_FUNCTION_TABLE table) { registerBuffer = Marshal.GetDelegateForFunctionPointer <RIORegisterBuffer>(table.RIORegisterBuffer); createCompletionQueue = Marshal.GetDelegateForFunctionPointer <RIOCreateCompletionQueue>(table.RIOCreateCompletionQueue); createRequestQueue = Marshal.GetDelegateForFunctionPointer <RIOCreateRequestQueue>(table.RIOCreateRequestQueue); notify = Marshal.GetDelegateForFunctionPointer <RIONotify>(table.RIONotify); dequeueCompletion = Marshal.GetDelegateForFunctionPointer <RIODequeueCompletion>(table.RIODequeueCompletion); receive = Marshal.GetDelegateForFunctionPointer <RIOReceive>(table.RIOReceive); send = Marshal.GetDelegateForFunctionPointer <RIOSend>(table.RIOSend); closeCompletionQueue = Marshal.GetDelegateForFunctionPointer <RIOCloseCompletionQueue>(table.RIOCloseCompletionQueue); deregisterBuffer = Marshal.GetDelegateForFunctionPointer <RIODeregisterBuffer>(table.RIODeregisterBuffer); resizeCompletionQueue = Marshal.GetDelegateForFunctionPointer <RIOResizeCompletionQueue>(table.RIOResizeCompletionQueue); resizeRequestQueue = Marshal.GetDelegateForFunctionPointer <RIOResizeRequestQueue>(table.RIOResizeRequestQueue); }
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 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; } }