예제 #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sourceAddress"></param>
        /// <param name="segmentId"></param>
        /// <param name="destinationAddress"></param>
        /// <param name="numBytesToWrite"></param>
        /// <param name="callback"></param>
        /// <param name="asyncResult"></param>
        public override unsafe void WriteAsync(IntPtr sourceAddress,
                                               int segmentId,
                                               ulong destinationAddress,
                                               uint numBytesToWrite,
                                               IOCompletionCallback callback,
                                               IAsyncResult asyncResult)
        {
            var logHandle = GetOrAddHandle(segmentId);

            Overlapped        ov       = new Overlapped(0, 0, IntPtr.Zero, asyncResult);
            NativeOverlapped *ovNative = ov.UnsafePack(callback, IntPtr.Zero);

            ovNative->OffsetLow  = unchecked ((int)(destinationAddress & 0xFFFFFFFF));
            ovNative->OffsetHigh = unchecked ((int)((destinationAddress >> 32) & 0xFFFFFFFF));

            bool result = Native32.WriteFile(logHandle,
                                             sourceAddress,
                                             numBytesToWrite,
                                             out uint bytesWritten,
                                             ovNative);

            if (!result)
            {
                int error = Marshal.GetLastWin32Error();
                if (error != Native32.ERROR_IO_PENDING)
                {
                    Overlapped.Unpack(ovNative);
                    Overlapped.Free(ovNative);
                    throw new Exception("Error writing to log file: " + error);
                }
            }
        }
예제 #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sourceAddress"></param>
        /// <param name="segmentId"></param>
        /// <param name="destinationAddress"></param>
        /// <param name="numBytesToWrite"></param>
        /// <param name="callback"></param>
        /// <param name="context"></param>
        public override unsafe void WriteAsync(IntPtr sourceAddress,
                                               int segmentId,
                                               ulong destinationAddress,
                                               uint numBytesToWrite,
                                               DeviceIOCompletionCallback callback,
                                               object context)
        {
            HandleCapacity(segmentId);

            if (!results.TryDequeue(out SimpleAsyncResult result))
            {
                result                  = new SimpleAsyncResult();
                result.overlapped       = new Overlapped(0, 0, IntPtr.Zero, result);
                result.nativeOverlapped = result.overlapped.UnsafePack(_callback, IntPtr.Zero);
            }

            result.context  = context;
            result.callback = callback;
            var ovNative = result.nativeOverlapped;

            ovNative->OffsetLow  = unchecked ((int)(destinationAddress & 0xFFFFFFFF));
            ovNative->OffsetHigh = unchecked ((int)((destinationAddress >> 32) & 0xFFFFFFFF));

            try
            {
                var logHandle = GetOrAddHandle(segmentId);

                Interlocked.Increment(ref numPending);

                bool _result = Native32.WriteFile(logHandle,
                                                  sourceAddress,
                                                  numBytesToWrite,
                                                  out uint bytesWritten,
                                                  ovNative);

                if (!_result)
                {
                    int error = Marshal.GetLastWin32Error();
                    if (error != Native32.ERROR_IO_PENDING)
                    {
                        throw new IOException("Error writing to log file", error);
                    }
                }
            }
            catch (IOException e)
            {
                Interlocked.Decrement(ref numPending);
                callback((uint)(e.HResult & 0x0000FFFF), 0, context);
                results.Enqueue(result);
            }
            catch
            {
                Interlocked.Decrement(ref numPending);
                callback(uint.MaxValue, 0, context);
                results.Enqueue(result);
            }
        }
        public unsafe void WriteAsync(IntPtr sourceAddress,
                                      int segmentId,
                                      ulong destinationAddress,
                                      uint numBytesToWrite,
                                      IOCompletionCallback callback,
                                      IAsyncResult asyncResult)
        {
            var logHandle = GetOrAddHandle(segmentId);

            Overlapped        ov       = new Overlapped(0, 0, IntPtr.Zero, asyncResult);
            NativeOverlapped *ovNative = ov.UnsafePack(callback, IntPtr.Zero);

            ovNative->OffsetLow  = unchecked ((int)(destinationAddress & 0xFFFFFFFF));
            ovNative->OffsetHigh = unchecked ((int)((destinationAddress >> 32) & 0xFFFFFFFF));


            /* Invoking the Native method WriteFile provided by Kernel32.dll
             * library. Returns false, if request failed or accepted for async
             * operation. Returns true, if success synchronously.
             */
            uint bytesWritten = default(uint);
            bool result       = Native32.WriteFile(logHandle,
                                                   sourceAddress,
                                                   numBytesToWrite,
                                                   out bytesWritten,
                                                   ovNative);

            if (!result)
            {
                int error = Marshal.GetLastWin32Error();

                /* Just handle the case when it is not ERROR_IO_PENDING
                 * If ERROR_IO_PENDING, then it is accepted for async execution
                 */
                if (error != Native32.ERROR_IO_PENDING)
                {
                    Overlapped.Unpack(ovNative);
                    Overlapped.Free(ovNative);
                    throw new Exception("Error writing to log file: " + error);
                }
            }
            else
            {
                //executed synchronously, so process callback
                callback(0, bytesWritten, ovNative);
            }
        }