예제 #1
0
        private static unsafe void ReadCompletionCallback(uint errCode, uint numBytes, NativeOverlapped *nativeOverlapped)
        {
            unsafe
            {
                try
                {
                    int workerNums, ioNums;
                    ThreadPool.GetAvailableThreads(out workerNums, out ioNums);
                    Console.WriteLine("from callback thread: available work threads:{0}, io threads:{1}", workerNums, ioNums);

#if MANUAL_BIND_IOCP
                    numBytes = (uint)(nativeOverlapped->InternalHigh);
#endif
                    Overlapped overlapped = Overlapped.Unpack(nativeOverlapped);
                    var        ar         = (AsyncResult)overlapped.AsyncResult;
                    var        buffer     = (byte[])ar.AsyncState;
                    if (errCode == (uint)Win32Api.GetLastErrorEnum.ERROR_HANDLE_EOF)
                    {
                        Console.WriteLine("End of file in callback.");
                    }
                    if (errCode != 0 && numBytes != 0)
                    {
                        Console.WriteLine("Error {0} when reading file.", errCode);
                    }
                    Console.WriteLine("Read {0} bytes.", numBytes);
                    Console.WriteLine(Encoding.UTF8.GetString(buffer, 0, (int)numBytes));
                }
                finally
                {
                    Overlapped.Free(nativeOverlapped);
                }
            }
        }
예제 #2
0
        public static unsafe Task <int> ReadAsync(SafeFileHandle hFile, long fileOffset, byte[] buffer, int bytesToRead)
        {
            if (fileOffset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(fileOffset));
            }

            if (bytesToRead < 0 || bytesToRead > buffer.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(bytesToRead));
            }

            var asyncResult = new AsyncResult();
            var o           = new Overlapped((int)(fileOffset & 0xFFFFFFFF), (int)(fileOffset >> 32), IntPtr.Zero, asyncResult);

            fixed(byte *bufferBase = buffer)
            {
                // https://docs.microsoft.com/en-us/dotnet/api/system.threading.overlapped.pack?view=netframework-4.7#System_Threading_Overlapped_Pack_System_Threading_IOCompletionCallback_System_Object_
                // The buffer or buffers specified in userData must be the same as those passed to the unmanaged operating system function that performs the asynchronous I/O.
                // The runtime pins the buffer or buffers specified in userData for the duration of the I/O operation.
                NativeOverlapped *pOverlapped = o.Pack(CompletionCallback, buffer);
                bool needToFree = true;

                try
                {
                    if (ReadFile(hFile, bufferBase, bytesToRead, IntPtr.Zero, pOverlapped) != 0)
                    {
                        // Completed synchronously.

                        // The number of bytes transferred for the I/ O request.The system sets this member if the request is completed without errors.
                        // https://msdn.microsoft.com/en-us/library/windows/desktop/ms684342(v=vs.85).aspx
                        int bytesRead = (int)pOverlapped->InternalHigh.ToInt64();
                        return(Task.FromResult(bytesRead));
                    }
                    else
                    {
                        int systemErrorCode = Marshal.GetLastWin32Error();
                        if (systemErrorCode == ERROR_IO_PENDING)
                        {
                            needToFree = false;
                        }
                        else
                        {
                            throw new Win32Exception(systemErrorCode, $"ReadFile failed with system error code:{systemErrorCode}");
                        }

                        return(asyncResult.CompletionSource.Value.Task);
                    }
                }
                finally
                {
                    if (needToFree)
                    {
                        Overlapped.Unpack(pOverlapped);
                        Overlapped.Free(pOverlapped);
                    }
                }
            }
        }
예제 #3
0
            unsafe void StartReceive(bool synchronously)
            {
                bool useCompletionPort;

                try
                {
                    this.handle = this.msmqQueue.GetHandleForAsync(out useCompletionPort);
                }
                catch (MsmqException ex)
                {
                    OnCompletion(ex.ErrorCode, synchronously);
                    return;
                }
                if (null != nativeOverlapped)
                {
                    Fx.Assert("---- in StartReceive");
                }

                IntPtr nativePropertiesPointer = this.message.Pin();

                nativeOverlapped = new Overlapped(0, 0, IntPtr.Zero, this).UnsafePack(onPortedCompletion, this.message.GetBuffersForAsync());

                int error;

                try
                {
                    if (useCompletionPort)
                    {
                        error = msmqQueue.ReceiveCoreAsync(this.handle, nativePropertiesPointer, this.timeoutHelper.RemainingTime(),
                                                           this.action, nativeOverlapped, null);
                    }
                    else
                    {
                        if (onNonPortedCompletion == null)
                        {
                            onNonPortedCompletion = new UnsafeNativeMethods.MQReceiveCallback(OnNonPortedCompletion);
                        }
                        error = msmqQueue.ReceiveCoreAsync(this.handle, nativePropertiesPointer, this.timeoutHelper.RemainingTime(),
                                                           this.action, nativeOverlapped, onNonPortedCompletion);
                    }
                }
                catch (ObjectDisposedException ex)
                {
                    // if Close ----s with the async Receive, it is possible that SafeHandle will throw ObjectDisposedException
                    // the behavior should be same as if operation was just cancelled (the channel will return no message)
                    MsmqDiagnostics.ExpectedException(ex);
                    error = UnsafeNativeMethods.MQ_ERROR_OPERATION_CANCELLED;
                }
                if (error != 0)
                {
                    if (error != UnsafeNativeMethods.MQ_INFORMATION_OPERATION_PENDING)
                    {
                        Overlapped.Free(nativeOverlapped);
                        nativeOverlapped = null;
                        GC.SuppressFinalize(this);
                        OnCompletion(error, synchronously);
                    }
                }
            }
 protected override unsafe void Dispose(bool disposing)
 {
     if ((this.m_NativeOverlapped != null) && (!NclUtilities.HasShutdownStarted || disposing))
     {
         Overlapped.Free(this.m_NativeOverlapped);
     }
     base.Dispose(disposing);
 }
예제 #5
0
 private static unsafe void UnpackAndFreeNativeOverlapped(NativeOverlapped *nativeOverlapped)
 {
     if (nativeOverlapped != null)
     {
         Overlapped.Unpack(nativeOverlapped);
         Overlapped.Free(nativeOverlapped);
     }
 }
예제 #6
0
 public void Cleanup()
 {
     if (this.scheduler != null)
     {
         throw Fx.AssertAndThrowFatal("Cleanup called on an overlapped that is in-flight.");
     }
     Overlapped.Free(this.nativeOverlapped);
 }
 protected override unsafe void Cleanup()
 {
     base.Cleanup();
     if (this.m_pOverlapped != null)
     {
         Overlapped.Free(this.m_pOverlapped);
     }
 }
예제 #8
0
 // Will be called from the base class upon InvokeCallback()
 protected override void Cleanup()
 {
     base.Cleanup();
     if (m_pOverlapped != null)
     {
         Overlapped.Free(m_pOverlapped);
     }
 }
예제 #9
0
 internal void ReleaseNativeResource()
 {
     // Free memory & GC handles.
     if (this._overlapped != null)
     {
         Overlapped.Free(_overlapped);
     }
 }
예제 #10
0
        //solucion de https://stackoverflow.com/questions/33389896/c-sharp-wcf-hosted-in-windows-service-goes-idle-after-5-minutes/33396091#33396091
        private static unsafe void QueueDummyIOCPWork()
        {
            Overlapped        ovl  = new Overlapped();
            NativeOverlapped *pOvl = null;

            pOvl = ovl.Pack((a, b, c) => { Overlapped.Unpack(pOvl); Overlapped.Free(pOvl); }, null);
            ThreadPool.UnsafeQueueNativeOverlapped(pOvl);
        }
        private static unsafe void DoOverlappedIO()
        {
            Console.WriteLine("DOOVERLAPPEDIO");
            Overlapped        overlapped = new();
            NativeOverlapped *pOverlap   = overlapped.Pack(null, null);

            Overlapped.Free(pOverlap);
        }
예제 #12
0
 internal unsafe void ReleaseNativeResource()
 {
     if ((IntPtr)this._overlapped == IntPtr.Zero)
     {
         return;
     }
     Overlapped.Free(this._overlapped);
 }
        /// <summary>
        /// The completion callback for when the operation completes. This is
        /// an internal callback that frees the native memory and subsequently
        /// invokes the original caller's completion callback so it can
        /// retrieve the result.
        /// </summary>
        private unsafe void CompletionCallback(
            UInt32 errorCode,
            UInt32 numBytes,
            NativeOverlapped *nativeOverlapped
            )
        {
            // First, free the NativeOverlapped structure and let this
            // IAsyncResult be collectable by the garbage collector
            Overlapped.Free(nativeOverlapped);

            try
            {
                if (errorCode != 0)
                {
                    // Check if an error occurred and record the error if so
                    base.SetAsCompleted(new Win32Exception((Int32)errorCode), false);
                }
                else
                {
                    // No error occurred, so the output buffer must contain the
                    // result!
                    TResult result = (TResult)mOutDeviceBuffer.Target;

                    // The result is going to be an array of bytes, so we need
                    // to resize the array to the exact size so that the Length
                    // property is accurate
                    if ((result != null) && result.GetType().IsArray)
                    {
                        // Only resize if the number of elements initialized in
                        // the array is less than the size of the array itself
                        Type  elementType   = result.GetType().GetElementType();
                        Int64 numElements   = numBytes / Marshal.SizeOf(elementType);
                        Array originalArray = (Array)(object)result;
                        if (numElements < originalArray.Length)
                        {
                            // Create a new array whose size is the number of
                            // initialized elements
                            Array newArray = Array.CreateInstance(elementType,
                                                                  numElements
                                                                  );
                            // Copy the initialized elements from the original
                            // array to the new one
                            Array.Copy(originalArray, newArray, numElements);
                            result = (TResult)(object)newArray;
                        }
                    }

                    // Record the result and call the AsyncCallback method
                    base.SetAsCompleted(result, false);
                }
            }
            finally
            {
                // Make sure that the input and output buffers are unpinned
                mOutDeviceBuffer.Dispose();
                mOutDeviceBuffer = null;  // Allow early GC
            }
        }
예제 #14
0
    // clear out the USB input buffer
    public void FlushReadUSB()
    {
        // note the starting time so we don't wait forever
        DateTime t0 = DateTime.Now;

        // wait until a read would block
        int rptLen = inputReportLength;

        while ((DateTime.Now - t0).TotalMilliseconds < 100)
        {
            // set up a non-blocking read
            IntPtr buf = Marshal.AllocHGlobal(rptLen);
            try
            {
                unsafe
                {
                    // set up the overlapped I/O descriptor
                    Overlapped        o  = new Overlapped(0, 0, evov.SafeWaitHandle.DangerousGetHandle(), null);
                    NativeOverlapped *no = o.Pack(null, null);

                    // start the non-blocking read
                    Marshal.WriteByte(buf, 0);
                    HIDImports.ReadFile(fp, buf, rptLen, IntPtr.Zero, no);

                    // check to see if it's ready immediately
                    bool ready = evov.WaitOne(0);
                    if (ready)
                    {
                        // it's ready - complete the read
                        UInt32 readLen;
                        int    result = HIDImports.GetOverlappedResult(fp, no, out readLen, 0);
                    }
                    else
                    {
                        // Not ready - we'd have to wait to do a read, so the
                        // buffer is empty.  Cancel the read.
                        HIDImports.CancelIo(fp);
                    }

                    // done with the overlapped I/O descriptor
                    Overlapped.Unpack(no);
                    Overlapped.Free(no);

                    // if there was nothing ready to read, we've cleared out buffered
                    // inputs, so we're done
                    if (!ready)
                    {
                        return;
                    }
                }
            }
            finally
            {
                Marshal.FreeHGlobal(buf);
            }
        }
    }
 protected override unsafe void OnReleasePins()
 {
     if (this.m_NativeOverlapped != null)
     {
         System.Threading.NativeOverlapped *nativeOverlapped = this.m_NativeOverlapped;
         this.m_NativeOverlapped = null;
         Overlapped.Free(nativeOverlapped);
     }
 }
예제 #16
0
            public void Cleanup()
            {
                if (this.scheduler != null)
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.Error_CleanupCalledOnAnOverlappedThatsInFlight));
                }

                Overlapped.Free(this.nativeOverlapped);
            }
예제 #17
0
            /// <summary>
            /// Unpacks the unmanaged <see cref="NativeOverlapped"/> structure into
            /// a managed <see cref="WinUsbOverlapped"/> object.
            /// </summary>
            internal unsafe void Unpack()
            {
                Overlapped.Unpack(this.native);
                Overlapped.Free(this.native);
                this.native = null;

                this.cancellationTokenRegistration.Dispose();
                this.BufferHandle.Dispose();
            }
예제 #18
0
            /// <summary>
            /// Unpacks the <see cref="NativeOverlapped"/> structure associated with this <see cref="DeviceIOControlOverlapped{TInput, TOutput}"/>
            /// instance, frees the native memory used and unpins the input and output buffers.
            /// </summary>
            internal unsafe void Unpack()
            {
                Overlapped.Unpack(this.native);
                Overlapped.Free(this.native);
                this.native = null;

                this.InputHandle.Dispose();
                this.OutputHandle.Dispose();
            }
            public void Cleanup()
            {
                if (this.scheduler != null)
                {
                    throw new InvalidOperationException("Cleanup called on an overlapped that is in-flight.");
                }

                Overlapped.Free(this.nativeOverlapped);
            }
예제 #20
0
 private unsafe void AsyncPageReadCallback(uint errorCode, uint numBytes, NativeOverlapped *overlap)
 {
     if (errorCode != 0)
     {
         Trace.TraceError("OverlappedStream GetQueuedCompletionStatus error: {0}", errorCode);
     }
     Interlocked.Decrement(ref numChunksToBeRecovered);
     Overlapped.Free(overlap);
 }
예제 #21
0
 private unsafe void AsyncPageReadCallback(uint errorCode, uint numBytes, NativeOverlapped *overlap)
 {
     if (errorCode != 0)
     {
         Trace.TraceError("OverlappedStream GetQueuedCompletionStatus error: {0}", errorCode);
     }
     mainIndexRecoveryEvent.Signal();
     Overlapped.Free(overlap);
 }
예제 #22
0
 internal void Free()
 {
     if (this.nativeOverlapped != null)
     {
         GC.SuppressFinalize(this);
         Overlapped.Free(this.nativeOverlapped);
         this.nativeOverlapped = null;
     }
 }
예제 #23
0
        protected override unsafe bool ReleaseHandle()
        {
            IntPtr ptr = Interlocked.Exchange(ref this.handle, IntPtr.Zero);

            if ((ptr != IntPtr.Zero) && !NclUtilities.HasShutdownStarted)
            {
                Overlapped.Free((NativeOverlapped *)ptr);
            }
            return(true);
        }
예제 #24
0
 internal void ErrorCleanup()
 {
     if (pOverlapped != null)
     {
         Overlapped.Unpack(pOverlapped);
         Overlapped.Free(pOverlapped);
         pOverlapped = null;
     }
     AsyncWaitHandle.Close();
 }
예제 #25
0
        internal unsafe void ReleaseMemory()
        {
            if (m_overlapped != null)
            {
                Overlapped.Free(m_overlapped);
                m_overlapped = null;
            }

            UnpinBuffer();
        }
예제 #26
0
        public void Dispose()
        {
            if (!m_disposed)
            {
                m_disposed = true;
                FreeBuffer();

                Overlapped.Free(m_nativeOverlapped);
            }
        }
예제 #27
0
 internal unsafe void Callback(uint errorCode, uint numBytes, NativeOverlapped *_overlapped)
 {
     try
     {
         this._event.Set();
     }
     finally
     {
         Overlapped.Free(_overlapped);
     }
 }
예제 #28
0
 protected override unsafe void Cleanup()
 {
     if (this.m_pOverlapped != null)
     {
         this.m_MemoryBlob = null;
         Overlapped.Free(this.m_pOverlapped);
         this.m_pOverlapped = null;
     }
     GC.SuppressFinalize(this);
     base.Cleanup();
 }
예제 #29
0
        private static unsafe void CleanupCallback(object state, bool timedOut)
        {
            OverlappedContext context = state as OverlappedContext;

            if (!timedOut)
            {
                context.pinnedTarget = null;
                context.rootedHolder.EventHolder.Close();
                Overlapped.Free(context.nativeOverlapped);
            }
        }
 private static unsafe void OnPortedCompletion(uint error, uint numBytes, NativeOverlapped *nativeOverlapped)
 {
     MsmqQueue.TryReceiveAsyncResult asyncResult = (MsmqQueue.TryReceiveAsyncResult)Overlapped.Unpack(nativeOverlapped).AsyncResult;
     if (error != 0)
     {
         error = (uint)UnsafeNativeMethods.MQGetOverlappedResult(nativeOverlapped);
     }
     Overlapped.Free(nativeOverlapped);
     asyncResult.nativeOverlapped = null;
     GC.SuppressFinalize(asyncResult);
     asyncResult.OnCompletion((int)error, false);
 }