예제 #1
0
 private static extern int WSAIoctl(
     [In] IntPtr socket,
     [In] uint dwIoControlCode,
     [In] ref Guid lpvInBuffer,
     [In] uint cbInBuffer,
     [In, Out] ref RioExtensionFunctionTable lpvOutBuffer,
     [In] int cbOutBuffer,
     [Out] out uint lpcbBytesReturned,
     [In] IntPtr lpOverlapped,
     [In] IntPtr lpCompletionRoutine
     );
예제 #2
0
        public unsafe static RegisteredIO Initalize(IntPtr socket)
        {
            UInt32 dwBytes = 0;
            RioExtensionFunctionTable rio = new RioExtensionFunctionTable();
            Guid rioFunctionsTableId      = new Guid("8509e081-96dd-4005-b165-9e2ee8c79e3f");


            int True = -1;

            int result = setsockopt(socket, IPPROTO_TCP, TcpNodelay, (char *)&True, 4);

            if (result != 0)
            {
                var error = WSAGetLastError();
                WSACleanup();
                throw new Exception($"ERROR: setsockopt TCP_NODELAY returned {error}");
            }

            result = WSAIoctlGeneral(socket, SioLoopbackFastPath,
                                     &True, 4, null, 0,
                                     out dwBytes, IntPtr.Zero, IntPtr.Zero);

            if (result != 0)
            {
                var error = WSAGetLastError();
                WSACleanup();
                throw new Exception($"ERROR: WSAIoctl SIO_LOOPBACK_FAST_PATH returned {error}");
            }

            result = WSAIoctl(socket, SioGetMultipleExtensionFunctionPointer,
                              ref rioFunctionsTableId, 16, ref rio,
                              sizeof(RioExtensionFunctionTable),
                              out dwBytes, IntPtr.Zero, IntPtr.Zero);

            if (result != 0)
            {
                var error = WSAGetLastError();
                WSACleanup();
                throw new Exception($"ERROR: RIOInitalize returned {error}");
            }

            var rioFunctions = new RegisteredIO();

            rioFunctions.RioRegisterBuffer = Marshal.GetDelegateForFunctionPointer <RioRegisterBuffer>(rio.RIORegisterBuffer);

            rioFunctions.RioCreateCompletionQueue = Marshal.GetDelegateForFunctionPointer <RioCreateCompletionQueue>(rio.RIOCreateCompletionQueue);

            rioFunctions.RioCreateRequestQueue = Marshal.GetDelegateForFunctionPointer <RioCreateRequestQueue>(rio.RIOCreateRequestQueue);

            rioFunctions.Notify            = Marshal.GetDelegateForFunctionPointer <RioNotify>(rio.RIONotify);
            rioFunctions.DequeueCompletion = Marshal.GetDelegateForFunctionPointer <RioDequeueCompletion>(rio.RIODequeueCompletion);

            rioFunctions.RioReceive = 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);
        }