Пример #1
0
        /// <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);
        }
Пример #2
0
 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
     );
Пример #3
0
        /// <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);
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
        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;
            }
        }