public static SafeRioCompletionQueueHandle CreateCompletionQueue(uint queueSize, SafeWaitHandle waitHandle) { Debug.Assert(queueSize > 0); Debug.Assert(waitHandle != null); var rnc = new RIO_NOTIFICATION_COMPLETION { Type = RIO_EVENT_COMPLETION, EventHandle = waitHandle.DangerousGetHandle(), NotifyReset = true, Padding = IntPtr.Zero }; SafeRioCompletionQueueHandle handle = s_rioCreateCompletionQueue(queueSize, ref rnc); if (handle.IsInvalid) { throw new SocketException(); } handle.SetDependencies(waitHandle); return(handle); }
public RIO_CQ CreateCompletionQueue([In] DWORD QueueSize, [In] RIO_NOTIFICATION_COMPLETION NotificationCompletion) => createCompletionQueue(QueueSize, NotificationCompletion);
/// <summary> /// Tries to create a new instance of the <see cref="IocpWorker" />. /// </summary> /// <param name="rioHandle">The object that provides work with Winsock registered I/O extensions.</param> /// <param name="processorIndex">The index of the processor.</param> /// <param name="segmentLength">The length of the segment.</param> /// <param name="segmentsCount">The count of the segments.</param> /// <returns> /// An instance of <see cref="TryResult{T}" /> which encapsulates result of the operation. /// <see cref="TryResult{T}.Success" /> contains <c>true</c> if operation was successful, <c>false</c> otherwise. /// <see cref="TryResult{T}.Result" /> contains valid object if operation was successful, <c>null</c> otherwise. /// </returns> public static unsafe TryResult <IocpWorker> TryCreate(RIOHandle rioHandle, Int32 processorIndex, UInt32 segmentLength, UInt32 segmentsCount) { #region 0 try create completion port var completionPort = KernelInterop.CreateIoCompletionPort(KernelInterop.INVALID_HANDLE_VALUE, IntPtr.Zero, UIntPtr.Zero, 0); // check if operation has succeed if (completionPort == IntPtr.Zero) { // get error code var kernelErrorCode = (KernelErrorCode)KernelInterop.GetLastError(); // return fail result TryResult <IocpWorker> .CreateFail(kernelErrorCode); } #endregion #region 1 try create completion queue // compose completion method structure var completionMethod = new RIO_NOTIFICATION_COMPLETION { // set type to IOCP Type = RIO_NOTIFICATION_COMPLETION_TYPE.RIO_IOCP_COMPLETION, union = { // set IOCP parameters Iocp = new RIO_NOTIFICATION_COMPLETION.UNION.IOCP { // set completion port IocpHandle = completionPort, // set completion key CompletionKey = (UInt64)processorIndex, Overlapped = (NativeOverlapped *)-1 } } }; // try create completion queue var completionQueue = rioHandle.CreateCompletionQueue(maxOutsandingCompletions, completionMethod); if (completionQueue == WinsockInterop.RIO_INVALID_CQ) { // get error code var winsockErrorCode = (WinsockErrorCode)WinsockInterop.WSAGetLastError(); // return fail result TryResult <IocpWorker> .CreateFail(winsockErrorCode); } #endregion #region 2 try create buffer pool var tryCreateBufferPool = RIOBufferPool.TryCreate(rioHandle, segmentLength, segmentsCount); if (tryCreateBufferPool.Success == false) { // return result return(TryResult <IocpWorker> .CreateFail(tryCreateBufferPool.KernelErrorCode, tryCreateBufferPool.WinsockErrorCode)); } #endregion // success var result = new IocpWorker(rioHandle, processorIndex, completionPort, completionQueue, tryCreateBufferPool.Result); // return success result return(TryResult <IocpWorker> .CreateSuccess(result)); }