示例#1
0
        /// <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));
        }
示例#2
0
		/// <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);
		}