/// <summary>
        ///
        /// </summary>
        /// <param name="segmentId"></param>
        /// <param name="sourceAddress"></param>
        /// <param name="destinationAddress"></param>
        /// <param name="readLength"></param>
        /// <param name="callback"></param>
        /// <param name="asyncResult"></param>
        public override unsafe void ReadAsync(int segmentId, ulong sourceAddress,
                                              IntPtr destinationAddress,
                                              uint readLength,
                                              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)((ulong)sourceAddress & 0xFFFFFFFF));
            ovNative->OffsetHigh = unchecked ((int)(((ulong)sourceAddress >> 32) & 0xFFFFFFFF));

            bool result = Native32.ReadFile(logHandle,
                                            destinationAddress,
                                            readLength,
                                            out uint bytesRead,
                                            ovNative);

            if (!result)
            {
                int error = Marshal.GetLastWin32Error();
                if (error != Native32.ERROR_IO_PENDING)
                {
                    Overlapped.Unpack(ovNative);
                    Overlapped.Free(ovNative);
                    throw new Exception("Error reading from log file: " + error);
                }
            }
        }
Example #2
0
        /// <summary>
        /// Async read
        /// </summary>
        /// <param name="segmentId"></param>
        /// <param name="sourceAddress"></param>
        /// <param name="destinationAddress"></param>
        /// <param name="readLength"></param>
        /// <param name="callback"></param>
        /// <param name="context"></param>
        public override void ReadAsync(int segmentId, ulong sourceAddress,
                                       IntPtr destinationAddress,
                                       uint readLength,
                                       DeviceIOCompletionCallback callback,
                                       object context)
        {
            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)((ulong)sourceAddress & 0xFFFFFFFF));
            ovNative->OffsetHigh = unchecked ((int)(((ulong)sourceAddress >> 32) & 0xFFFFFFFF));

            try
            {
                var logHandle = GetOrAddHandle(segmentId);

                Interlocked.Increment(ref numPending);

                bool _result = Native32.ReadFile(logHandle,
                                                 destinationAddress,
                                                 readLength,
                                                 out uint bytesRead,
                                                 ovNative);

                if (!_result)
                {
                    int error = Marshal.GetLastWin32Error();
                    if (error != Native32.ERROR_IO_PENDING)
                    {
                        throw new IOException("Error reading from 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 ReadAsync(int segmentId, ulong sourceAddress,
                                     IntPtr destinationAddress,
                                     uint readLength,
                                     IAsyncResult asyncResult)
        {
            var logHandle = GetOrAddHandle(segmentId);

            Overlapped ov = new Overlapped
            {
                AsyncResult = asyncResult,
                OffsetLow   = unchecked ((int)(sourceAddress & 0xFFFFFFFF)),
                OffsetHigh  = unchecked ((int)((sourceAddress >> 32) & 0xFFFFFFFF))
            };

            NativeOverlapped *ovNative = ov.UnsafePack(null, IntPtr.Zero);

            /* Invoking the Native method ReadFile provided by Kernel32.dll
             * library. Returns false, if request failed or accepted for async
             * operation. Returns true, if success synchronously.
             */
            uint bytesRead = default(uint);
            bool result    = Native32.ReadFile(logHandle,
                                               destinationAddress,
                                               readLength,
                                               out bytesRead,
                                               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 reading from log file: " + error);
                }
            }
            else
            {
                //executed synchronously, so process callback
                //callback(0, bytesRead, ovNative);
            }
        }
        public unsafe void ReadAsync(int segmentId, ulong sourceAddress,
                                     IntPtr destinationAddress,
                                     uint readLength,
                                     IOCompletionCallback callback,
                                     IAsyncResult asyncResult)
        {
            var logHandle = GetOrAddHandle(segmentId);

            //Debug.WriteLine("sourceAddress: {0}, destinationAddress: {1}, readLength: {2}"
            //    , sourceAddress, (ulong)destinationAddress, readLength);

            if (readLength != 512)
            {
            }
            Overlapped        ov       = new Overlapped(0, 0, IntPtr.Zero, asyncResult);
            NativeOverlapped *ovNative = ov.UnsafePack(callback, IntPtr.Zero);

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

            uint bytesRead = default(uint);
            bool result    = Native32.ReadFile(logHandle,
                                               destinationAddress,
                                               readLength,
                                               out bytesRead,
                                               ovNative);

            if (!result)
            {
                int error = Marshal.GetLastWin32Error();
                if (error != Native32.ERROR_IO_PENDING)
                {
                    Overlapped.Unpack(ovNative);
                    Overlapped.Free(ovNative);

                    // NOTE: alignedDestinationAddress needs to be freed by whoever catches the exception
                    throw new Exception("Error reading from log file: " + error);
                }
            }
            else
            {
                // On synchronous completion, issue callback directly
                callback(0, bytesRead, ovNative);
            }
        }