示例#1
0
		/// <summary>
		/// Tries to create a new instance of the <see cref="RIOBufferPool" />.
		/// </summary>
		/// <param name="rioHandle">The object that provides work with Winsock registered I/O extensions.</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>
		/// <remarks>
		/// The multiplication of <paramref name="segmentLength" /> and <paramref name="segmentsCount" /> must produce value that is aligned to Memory Allocation Granularity.
		/// </remarks>
		public static unsafe TryResult<RIOBufferPool> TryCreate(RIOHandle rioHandle, UInt32 segmentLength, UInt32 segmentsCount)
		{
			// calculate size of the memory buffer to allocate
			var bufferLength = segmentLength * segmentsCount;

			void* memoryPointer;

			IntPtr buffer;

			IntPtr bufferId;

			// 1 try allocate memory block
			{
				// try reserve and commit memory block
				memoryPointer = KernelInterop.VirtualAlloc(null, bufferLength, KernelInterop.MEM_COMMIT | KernelInterop.MEM_RESERVE, KernelInterop.PAGE_READWRITE);

				// check if allocation has failed
				if (memoryPointer == null)
				{
					// get kernel error code
					var kernelErrorCode = (KernelErrorCode) KernelInterop.GetLastError();

					// return result
					return TryResult<RIOBufferPool>.CreateFail(kernelErrorCode);
				}

				// set buffer
				buffer = (IntPtr) memoryPointer;
			}

			// 2 try register buffer with Registered I/O extensions
			{
				bufferId = rioHandle.RegisterBuffer(buffer, bufferLength);

				if (bufferId == WinsockInterop.RIO_INVALID_BUFFERID)
				{
					// get winsock error code
					var winsockErrorCode = (WinsockErrorCode) WinsockInterop.WSAGetLastError();

					// free allocated memory
					var freeResult = KernelInterop.VirtualFree(memoryPointer, 0, KernelInterop.MEM_RELEASE);

					// set kernel error code
					if (freeResult)
					{
						// return result
						return TryResult<RIOBufferPool>.CreateFail(winsockErrorCode);
					}

					// get kernel error code
					var kernelErrorCode = (KernelErrorCode) KernelInterop.GetLastError();

					// return result
					return TryResult<RIOBufferPool>.CreateFail(kernelErrorCode, winsockErrorCode);
				}
			}

			// 3 success
			var result = new RIOBufferPool(buffer, bufferLength, bufferId, segmentLength, segmentsCount);

			// return result
			return TryResult<RIOBufferPool>.CreateSuccess(result);
		}
示例#2
0
        /// <summary>
        /// Tries to create a new instance of the <see cref="RIOBufferPool" />.
        /// </summary>
        /// <param name="rioHandle">The object that provides work with Winsock registered I/O extensions.</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>
        /// <remarks>
        /// The multiplication of <paramref name="segmentLength" /> and <paramref name="segmentsCount" /> must produce value that is aligned to Memory Allocation Granularity.
        /// </remarks>
        public static unsafe TryResult <RIOBufferPool> TryCreate(RIOHandle rioHandle, UInt32 segmentLength, UInt32 segmentsCount)
        {
            // calculate size of the memory buffer to allocate
            var bufferLength = segmentLength * segmentsCount;

            void *memoryPointer;

            IntPtr buffer;

            IntPtr bufferId;

            // 1 try allocate memory block
            {
                // try reserve and commit memory block
                memoryPointer = KernelInterop.VirtualAlloc(null, bufferLength, KernelInterop.MEM_COMMIT | KernelInterop.MEM_RESERVE, KernelInterop.PAGE_READWRITE);

                // check if allocation has failed
                if (memoryPointer == null)
                {
                    // get kernel error code
                    var kernelErrorCode = (KernelErrorCode)KernelInterop.GetLastError();

                    // return result
                    return(TryResult <RIOBufferPool> .CreateFail(kernelErrorCode));
                }

                // set buffer
                buffer = (IntPtr)memoryPointer;
            }

            // 2 try register buffer with Registered I/O extensions
            {
                bufferId = rioHandle.RegisterBuffer(buffer, bufferLength);

                if (bufferId == WinsockInterop.RIO_INVALID_BUFFERID)
                {
                    // get winsock error code
                    var winsockErrorCode = (WinsockErrorCode)WinsockInterop.WSAGetLastError();

                    // free allocated memory
                    var freeResult = KernelInterop.VirtualFree(memoryPointer, 0, KernelInterop.MEM_RELEASE);

                    // set kernel error code
                    if (freeResult)
                    {
                        // return result
                        return(TryResult <RIOBufferPool> .CreateFail(winsockErrorCode));
                    }

                    // get kernel error code
                    var kernelErrorCode = (KernelErrorCode)KernelInterop.GetLastError();

                    // return result
                    return(TryResult <RIOBufferPool> .CreateFail(kernelErrorCode, winsockErrorCode));
                }
            }

            // 3 success
            var result = new RIOBufferPool(buffer, bufferLength, bufferId, segmentLength, segmentsCount);

            // return result
            return(TryResult <RIOBufferPool> .CreateSuccess(result));
        }