void InvalidateMarshalContext() { lock (this.store.SyncRoot) { if (this.marshalContext != null) { this.marshalContext.Close(); this.marshalContext = null; } } }
void EnsureMarshalContext() { // NOTE: Simple synchronization here may cause problems. I // am counting on the unfairness of the lock object to // make this fast enough. // lock (this.store.SyncRoot) { if ((this.marshalContext != null) && (!this.marshalContext.IsInvalid)) { return; } try { this.marshalContext = UnsafeNativeMethods.CreateLogMarshallingArea( this.store.Handle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, this.bufferSize, this.writeBufferCount, DefaultReadBufferCount); } catch (InvalidOperationException) { if (this.store.Extents.Count == 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( Error.InvalidOperation(SR.InvalidOperation_MustHaveExtents)); } else { throw; } } } }
protected override void FreeReservation(long size) { if (size < 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentOutOfRange("size")); } lock (this.recordSequence.LogStore.SyncRoot) { SafeMarshalContext context = this.recordSequence.InternalMarshalContext; if (context == null || context.IsInvalid) { return; } // Reservation coming from collection, add record header // size. // size += LogLogRecordHeader.Size; long aligned; UnsafeNativeMethods.AlignReservedLogSingle( context, size, out aligned); // Adjustment must be negative, otherwise it's considered // a "set". (Yuck.) // aligned = -aligned; UnsafeNativeMethods.FreeReservedLog( context, 1, ref aligned); } }
public static void AlignReservedLogSingle(SafeMarshalContext pvMarshal, long reservation, out long pcbAlignReservation) { if (!_AlignReservedLogSingle(pvMarshal, 1, ref reservation, out pcbAlignReservation)) { uint errorCode = (uint)Marshal.GetLastWin32Error(); switch (errorCode) { case Error.ERROR_INVALID_HANDLE: case Error.ERROR_INVALID_PARAMETER: case Error.ERROR_IO_DEVICE: case Error.ERROR_LOG_RESERVATION_INVALID: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ExceptionForKnownCode(errorCode)); default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ExceptionForUnknownCode(errorCode)); } } }
public static void FreeReservedLog(SafeMarshalContext pvMarshal, uint cReservedRecords, ref long pcbAdjustment) { if (!_FreeReservedLog(pvMarshal, cReservedRecords, ref pcbAdjustment)) { uint errorCode = (uint)Marshal.GetLastWin32Error(); switch (errorCode) { case Error.ERROR_NO_SYSTEM_RESOURCES: case Error.ERROR_LOG_FULL: case Error.ERROR_INVALID_HANDLE: case Error.ERROR_ACCESS_DENIED: case Error.ERROR_INVALID_PARAMETER: case Error.ERROR_IO_DEVICE: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ExceptionForKnownCode(errorCode)); default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ExceptionForUnknownCode(errorCode)); } } }
public static void FlushLogToLsnSync( SafeMarshalContext pvMarshalContext, ref ulong plsnFlush, out ulong plsnLastFlushed) { if (!_FlushLogToLsnSync(pvMarshalContext, ref plsnFlush, out plsnLastFlushed, null)) { uint errorCode = (uint)Marshal.GetLastWin32Error(); if (errorCode == Error.ERROR_IO_PENDING) { // The CLFS API was called with a NULL overlapped, so the operation should not be asynchronous. // This means that CLFS has a bug, so it is not safe to continue processing. DiagnosticUtility.FailFast("Unexpected IO in progress (FlushToLsnSync)"); } switch (errorCode) { case Error.ERROR_INVALID_HANDLE: case Error.ERROR_ACCESS_DENIED: case Error.ERROR_INVALID_PARAMETER: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ExceptionForKnownCode(errorCode)); default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ExceptionForUnknownCode(errorCode)); } } }
public static uint FlushLogToLsnAsync( SafeMarshalContext pvMarshalContext, ref ulong plsnFlush, IntPtr plsnLastFlushed, NativeOverlapped* overlapped) { uint errorCode = Error.ERROR_SUCCESS; if (!_FlushLogToLsnAsync(pvMarshalContext, ref plsnFlush, plsnLastFlushed, overlapped)) { errorCode = (uint)Marshal.GetLastWin32Error(); } return errorCode; }
public static void AdvanceLogBaseSync( SafeMarshalContext pvMarshal, [In] ref ulong plsnBase, int fFlags) { if (!_AdvanceLogBase(pvMarshal, ref plsnBase, fFlags, null)) { uint errorCode = (uint)Marshal.GetLastWin32Error(); switch (errorCode) { case Error.ERROR_NO_SYSTEM_RESOURCES: case Error.ERROR_LOG_FULL: case Error.ERROR_INVALID_HANDLE: case Error.ERROR_ACCESS_DENIED: case Error.ERROR_IO_DEVICE: case Error.ERROR_INVALID_PARAMETER: case Error.ERROR_LOG_TAIL_INVALID: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ExceptionForKnownCode(errorCode)); default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ExceptionForUnknownCode(errorCode)); } } }
extern static bool _CreateLogMarshallingArea( SafeFileHandle hLog, IntPtr pfnAllocBuffer, IntPtr pfnFreeBuffer, IntPtr pvBlockAllocContext, int cbMarshallingBlock, int cMaxWriteBlocks, int cMaxReadBlocks, out SafeMarshalContext ppvMarshal);
extern static bool _WriteLogRestartArea( SafeMarshalContext pvMarshal, byte* pvRestartBuffer, int cbRestartBuffer, [In] ref ulong plsnBase, int fFlags, IntPtr pcbWritten, // int* IntPtr plsnRestart, // ulong* NativeOverlapped* pOverlapped);
public static uint ReserveAndAppendLog( SafeMarshalContext pvMarshal, CLFS_WRITE_ENTRY[] rgWriteEntries, int cWriteEntries, [In] ref ulong plsnUndoNext, [In] ref ulong plsnPrevious, int cReserveRecords, long[] rgcbReservation, int fFlags, IntPtr plsn, NativeOverlapped* pOverlapped) { uint errorCode = Error.ERROR_SUCCESS; if (!_ReserveAndAppendLog(pvMarshal, rgWriteEntries, cWriteEntries, ref plsnUndoNext, ref plsnPrevious, cReserveRecords, rgcbReservation, fFlags, plsn, pOverlapped)) { errorCode = (uint)Marshal.GetLastWin32Error(); } return errorCode; }
extern static bool _ReadLogRecord( SafeMarshalContext pvMarshal, [In] ref ulong plsnFirst, CLFS_CONTEXT_MODE ecxMode, out byte* ppvReadBuffer, out int pcbReadBuffer, out byte peRecordType, out ulong plsnUndoNext, out ulong plsnPrevious, out SafeReadContext ppvReadContext, NativeOverlapped* pOverlapped);
extern static bool _ReserveAndAppendLog( SafeMarshalContext pvMarshal, CLFS_WRITE_ENTRY[] rgWriteEntries, int cWriteEntries, [In] ref ulong plsnUndoNext, [In] ref ulong plsnPrevious, int cReserveRecords, long[] rgcbReservation, int fFlags, IntPtr plsn, NativeOverlapped* pOverlapped);
extern static bool _ReadLogRestartArea( SafeMarshalContext pvMarshal, out byte* ppvRestartBuffer, out int pcbRestartBuffer, out ulong plsn, out SafeReadContext ppvContext, NativeOverlapped* overlapped);
extern static bool _FreeReservedLog( SafeMarshalContext pvMarshal, uint cReservedRecords, [In] ref long pcbAdjustment);
extern static bool _AlignReservedLogSingle( SafeMarshalContext pvMarshal, int cReservedRecords, ref long rgcbReservation, out long pcbAlignReservation);
public static bool ReadLogRestartAreaSync( SafeMarshalContext pvMarshal, out byte* ppvRestartBuffer, out int pcbRestartBuffer, out ulong plsn, out SafeReadContext ppvContext) { if (!_ReadLogRestartArea(pvMarshal, out ppvRestartBuffer, out pcbRestartBuffer, out plsn, out ppvContext, null)) { uint errorCode = (uint)Marshal.GetLastWin32Error(); Utility.CloseInvalidOutSafeHandle(ppvContext); ppvContext = null; if (errorCode == Error.ERROR_IO_PENDING) { // The CLFS API was called with a NULL overlapped, so the operation should not be asynchronous. // This means that CLFS has a bug, so it is not safe to continue processing. DiagnosticUtility.FailFast("Unexpected IO in progress (ReadLogRA)"); } switch (errorCode) { case Error.ERROR_LOG_NO_RESTART: return false; case Error.ERROR_LOG_BLOCK_INCOMPLETE: case Error.ERROR_INVALID_HANDLE: case Error.ERROR_ACCESS_DENIED: case Error.ERROR_INVALID_PARAMETER: case Error.ERROR_IO_DEVICE: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ExceptionForKnownCode(errorCode)); default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ExceptionForUnknownCode(errorCode)); } } return true; }
extern static bool _WriteLogRestartAreaNoBase( SafeMarshalContext pvMarshal, byte* pvRestartBuffer, int cbRestartBuffer, IntPtr mustBeZero, int fFlags, IntPtr pcbWritten, // int* IntPtr plsnRestart, // ulong* NativeOverlapped* pOverlapped);
public static bool ReadLogRecordSync(SafeMarshalContext pvMarshal, [In] ref ulong plsnFirst, CLFS_CONTEXT_MODE ecxMode, out byte* ppvReadBuffer, out int pcbReadBuffer, out byte peRecordType, out ulong plsnUndoNext, out ulong plsnPrevious, out SafeReadContext ppvReadContext) { if (!_ReadLogRecord(pvMarshal, ref plsnFirst, ecxMode, out ppvReadBuffer, out pcbReadBuffer, out peRecordType, out plsnUndoNext, out plsnPrevious, out ppvReadContext, null)) { uint errorCode = (uint)Marshal.GetLastWin32Error(); Utility.CloseInvalidOutSafeHandle(ppvReadContext); ppvReadContext = null; if (errorCode == Error.ERROR_IO_PENDING) { // The CLFS API was called with a NULL overlapped, so the operation should not be asynchronous. // This means that CLFS has a bug, so it is not safe to continue processing. DiagnosticUtility.FailFast("No async in ReadLogRecordSync"); } switch (errorCode) { case Error.ERROR_HANDLE_EOF: return false; case Error.ERROR_NOT_FOUND: case Error.ERROR_LOG_START_OF_LOG: case Error.ERROR_LOG_BLOCK_INVALID: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentInvalid(SR.Argument_InvalidStartSequenceNumber)); case Error.ERROR_LOG_BLOCK_INCOMPLETE: case Error.ERROR_INVALID_HANDLE: case Error.ERROR_ACCESS_DENIED: case Error.ERROR_INVALID_PARAMETER: case Error.ERROR_IO_DEVICE: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ExceptionForKnownCode(errorCode)); default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ExceptionForUnknownCode(errorCode)); } } return true; }
public static void TruncateLogSync(SafeMarshalContext pvMarshal, ref ulong plsnEnd) { if (!_TruncateLog(pvMarshal, ref plsnEnd, null)) { uint errorCode = (uint)Marshal.GetLastWin32Error(); if (errorCode == Error.ERROR_IO_PENDING) { // The CLFS API was called with a NULL overlapped, so the operation should not be asynchronous. // This means that CLFS has a bug, so it is not safe to continue processing. DiagnosticUtility.FailFast("No async in TruncateLogSync"); } switch (errorCode) { case Error.ERROR_LOG_START_OF_LOG: case Error.ERROR_LOG_BLOCK_INVALID: case Error.ERROR_LOG_SECTOR_PARITY_INVALID: case Error.ERROR_HANDLE_EOF: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentInvalid(SR.Argument_InvalidSequenceNumber)); case Error.ERROR_LOG_METADATA_CORRUPT: case Error.ERROR_INVALID_HANDLE: case Error.ERROR_ACCESS_DENIED: case Error.ERROR_INVALID_PARAMETER: case Error.ERROR_LOG_INVALID_RANGE: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ExceptionForKnownCode(errorCode)); default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ExceptionForUnknownCode(errorCode)); } } }
public static uint WriteLogRestartArea(SafeMarshalContext pvMarshal, byte* pvRestartBuffer, int cbRestartBuffer, [In] ref ulong plsnBase, int fFlags, IntPtr pcbWritten, // int* IntPtr plsnRestart, // ulong* NativeOverlapped* pOverlapped) { uint errorCode = Error.ERROR_SUCCESS; if (!_WriteLogRestartArea(pvMarshal, pvRestartBuffer, cbRestartBuffer, ref plsnBase, fFlags, pcbWritten, plsnRestart, pOverlapped)) { errorCode = (uint)Marshal.GetLastWin32Error(); } return errorCode; }
extern static bool _AdvanceLogBase( SafeMarshalContext pvMarshal, [In] ref ulong plsnBase, int fFlags, NativeOverlapped* pOverlapped);
extern static bool _TruncateLog(SafeMarshalContext pvMarshal, [In] ref ulong plsnEnd, NativeOverlapped* lpOverlapped);
extern static bool _FlushLogToLsnAsync( SafeMarshalContext pvMarshalContext, [In] ref ulong plsnFlush, IntPtr plsnLastFlushed, NativeOverlapped* overlapped);