/// <summary> /// IOCompletion callback for page flush /// </summary> /// <param name="errorCode"></param> /// <param name="numBytes"></param> /// <param name="overlap"></param> private void AsyncFlushPageToDeviceCallback(uint errorCode, uint numBytes, NativeOverlapped *overlap) { if (errorCode != 0) { Trace.TraceError("OverlappedStream GetQueuedCompletionStatus error: {0}", errorCode); } PageAsyncFlushResult <Empty> result = (PageAsyncFlushResult <Empty>)Overlapped.Unpack(overlap).AsyncResult; if (Interlocked.Decrement(ref result.count) == 0) { result.Free(); } Overlapped.Free(overlap); }
/// <summary> /// IOCompletion callback for page flush /// </summary> /// <param name="errorCode"></param> /// <param name="numBytes"></param> /// <param name="overlap"></param> private void AsyncFlushPageCallback(uint errorCode, uint numBytes, NativeOverlapped *overlap) { if (errorCode != 0) { Trace.TraceError("OverlappedStream GetQueuedCompletionStatus error: {0}", errorCode); } // Set the page status to flushed PageAsyncFlushResult <Empty> result = (PageAsyncFlushResult <Empty>)Overlapped.Unpack(overlap).AsyncResult; if (Interlocked.Decrement(ref result.count) == 0) { PageStatusIndicator[result.page % BufferSize].LastFlushedUntilAddress = result.untilAddress; if (!result.partial) { while (true) { var oldStatus = PageStatusIndicator[result.page % BufferSize].PageFlushCloseStatus; if (oldStatus.PageCloseStatus == CloseStatus.Closed) { ClearPage((int)(result.page % BufferSize), result.page == 0); } var newStatus = oldStatus; newStatus.PageFlushStatus = FlushStatus.Flushed; if (oldStatus.value == Interlocked.CompareExchange(ref PageStatusIndicator[result.page % BufferSize].PageFlushCloseStatus.value, newStatus.value, oldStatus.value)) { break; } } } ShiftFlushedUntilAddress(); result.Free(); } Overlapped.Free(overlap); }