コード例 #1
0
        /// <summary>   Creates texture and pass to plugin. </summary>
        /// <param name="height">   The height. </param>
        /// <param name="width">    The width. </param>
        public void CreateTextureAndPassToPlugin(int height, int width)
        {
            // Create a texture
            tex = new Texture2D(height, width, TextureFormat.RGBAFloat, false, true);

            // Use bilinear, point caused issues with striations in the depth image
            // bilinear also causes issues but they are handled in the DepthMapOcclusion.shader
            tex.filterMode = FilterMode.Bilinear;

            // Call Apply() so it's actually uploaded to the GPU
            tex.Apply();

            // Pass texture pointer to the plugin
            KernelInterop.SetTextureFromUnity(tex.GetNativeTexturePtr(), height, width);
        }
コード例 #2
0
        /// <summary>
        /// Tries to release all allocated resources.
        /// </summary>
        /// <param name="rioHandle">The object that provides work with Winsock registered I/O extensions.</param>
        /// <param name="kernelErrorCode">Contains <c>0</c> if operation was successful, error code otherwise.</param>
        /// <returns><c>true</c> if operation was successful, <c>false</c> otherwise.</returns>
        public unsafe Boolean TryRelease(RIOHandle rioHandle, out UInt32 kernelErrorCode)
        {
            // 0 deregister buffer with Registered I/O extension
            {
                rioHandle.DeregisterBuffer(bufferId);
            }

            // 1 try free memory
            {
                var freeResult = KernelInterop.VirtualFree((void *)buffer, 0, KernelInterop.MEM_RELEASE);

                if (freeResult == false)
                {
                    kernelErrorCode = KernelInterop.GetLastError();

                    return(false);
                }
            }

            // 2 success
            kernelErrorCode = 0;

            return(true);
        }
コード例 #3
0
ファイル: IocpWorker.cs プロジェクト: stas-sultanov/SXN.Net
        /// <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));
        }
コード例 #4
0
ファイル: IocpWorker.cs プロジェクト: stas-sultanov/SXN.Net
        private unsafe void Process()
        {
            const Int32 maxResults = 1024;

            RIORESULT *results = stackalloc RIORESULT[maxResults];

            /*
             * RIOPooledSegment cachedBadBuffer = worker.bufferPool.GetBuffer();
             * Buffer.BlockCopy(_badResponseBytes, 0, cachedBadBuffer.Buffer, cachedBadBuffer.Offset, _badResponseBytes.Length);
             * cachedBadBuffer.RioBuffer.Length = (uint)_badResponseBytes.Length;
             * worker.cachedBad = cachedBadBuffer.RioBuffer;
             *
             * RIOPooledSegment cachedBusyBuffer = worker.bufferPool.GetBuffer();
             * Buffer.BlockCopy(_busyResponseBytes, 0, cachedBusyBuffer.Buffer, cachedBusyBuffer.Offset, _busyResponseBytes.Length);
             * cachedBusyBuffer.RioBuffer.Length = (uint)_busyResponseBytes.Length;
             * worker.cachedBusy = cachedBusyBuffer.RioBuffer;
             */

            //while (!cancellationToken.IsCancellationRequested)
            while (true)
            {
                // try register method to use for notification behavior with the I/O completion queue
                var notifyResult = (WinsockErrorCode)RioHandle.Notify(CompletionQueue);

                if (notifyResult != WinsockErrorCode.None)
                {
                    // TODO: fail
                }

                // try dequeue the I/O completion packet from the specified I/O completion port
                UInt32 bytesCount;

                UIntPtr completionKey;

                NativeOverlapped *overlapped;

                var getQueuedCompletionStatusResult = KernelInterop.GetQueuedCompletionStatus(CompletionPort, out bytesCount, out completionKey, out overlapped, UInt32.MaxValue);

                if (getQueuedCompletionStatusResult == false)
                {
                    // TODO: fail
                }

                // try remove entries from the I/O completion queue
                var resultsCount = RioHandle.DequeueCompletion(CompletionQueue, (IntPtr)results, maxResults);

                /*
                 * if (resultsCount == RIOHandle.RIO_CORRUPT_CQ.)
                 * {
                 *      // TODO: fail
                 * }
                 */

                var activatedCompletionPort = false;

                while (resultsCount > 0)
                {
                    for (var resultIndex = 0; resultIndex < resultsCount; resultIndex++)
                    {
                        // get RIORESULT
                        var result = results[resultIndex];

                        // TODO : wtf ???
                        // if (result.RequestContext >= 0)

                        TcpConnection connection;

                        if (Connections.TryGetValue(result.SocketContext.ToUInt64(), out connection))
                        {
                            //connection.CompleteReceive(result.RequestContext, result.BytesTransferred);
                        }
                    }

                    if (!activatedCompletionPort)
                    {
                        notifyResult = (WinsockErrorCode)RioHandle.Notify(CompletionQueue);

                        if (notifyResult != WinsockErrorCode.None)
                        {
                            // TODO: fail
                        }

                        activatedCompletionPort = true;
                    }
                }
            }

            /*
             *                              else
             *      {
             *              var error = GetLastError();
             *              if (error != 258)
             *              {
             *                      throw new Exception(string.Format("ERROR: GetQueuedCompletionStatusEx returned {0}", error));
             *              }
             * }
             *
             * cachedBadBuffer.Dispose();
             * cachedBusyBuffer.Dispose();
             */
        }
コード例 #5
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));
        }