internal void HandleDataDiskFullException(DiskFullException exception) { if (_options.ManualFlushing) { return; } _endOfDiskSpace = new EndOfDiskSpaceEvent(exception.DriveInfo, ExceptionDispatchInfo.Capture(exception)); }
public void HandleDataDiskFullException(DiskFullException exception) { if (_options.ManualFlushing) { return; } _cancellationTokenSource.Cancel(); _endOfDiskSpace = new EndOfDiskSpaceEvent(exception.DriveInfo); }
public Transaction NewTransaction(TransactionFlags flags, TimeSpan?timeout = null) { bool txLockTaken = false; try { if (flags == (TransactionFlags.ReadWrite)) { var wait = timeout ?? (Debugger.IsAttached ? TimeSpan.FromMinutes(30) : TimeSpan.FromSeconds(30)); if (_txWriter.Wait(wait) == false) { throw new TimeoutException("Waited for " + wait + " for transaction write lock, but could not get it"); } txLockTaken = true; if (_endOfDiskSpace != null) { if (_endOfDiskSpace.CanContinueWriting) { var flushingTask = _flushingTask; Debug.Assert(flushingTask != null && (flushingTask.Status == TaskStatus.Canceled || flushingTask.Status == TaskStatus.RanToCompletion)); _cancellationTokenSource = new CancellationTokenSource(); _flushingTask = FlushWritesToDataFileAsync(); _endOfDiskSpace = null; } } } Transaction tx; _txCommit.EnterReadLock(); try { long txId = flags == TransactionFlags.ReadWrite ? _transactionsCounter + 1 : _transactionsCounter; tx = new Transaction(this, txId, flags, _freeSpaceHandling); if (IsDebugRecording) { RecordTransactionState(tx, DebugActionType.TransactionStart); tx.RecordTransactionState = RecordTransactionState; } } finally { _txCommit.ExitReadLock(); } _activeTransactions.Add(tx); var state = _dataPager.TransactionBegan(); tx.AddPagerState(state); if (flags == TransactionFlags.ReadWrite) { tx.AfterCommit = TransactionAfterCommit; } return(tx); } catch (Exception) { if (txLockTaken) { _txWriter.Release(); } throw; } }
internal LowLevelTransaction NewLowLevelTransaction(TransactionPersistentContext transactionPersistentContext, TransactionFlags flags, ByteStringContext context = null, TimeSpan?timeout = null) { _cancellationTokenSource.Token.ThrowIfCancellationRequested(); bool txLockTaken = false; bool flushInProgressReadLockTaken = false; try { IncrementUsageOnNewTransaction(); if (flags == TransactionFlags.ReadWrite) { var wait = timeout ?? (Debugger.IsAttached ? TimeSpan.FromMinutes(30) : TimeSpan.FromSeconds(30)); if (FlushInProgressLock.IsWriteLockHeld == false) { flushInProgressReadLockTaken = FlushInProgressLock.TryEnterReadLock(wait); } txLockTaken = _transactionWriter.Wait(wait); if (txLockTaken == false || (flushInProgressReadLockTaken == false && FlushInProgressLock.IsWriteLockHeld == false)) { GlobalFlushingBehavior.GlobalFlusher.Value.MaybeFlushEnvironment(this); ThrowOnTimeoutWaitingForWriteTxLock(wait); } _cancellationTokenSource.Token.ThrowIfCancellationRequested(); _currentTransactionHolder = NativeMemory.ThreadAllocations.Value; WriteTransactionStarted(); if (_endOfDiskSpace != null) { _endOfDiskSpace.AssertCanContinueWriting(); _endOfDiskSpace = null; Task.Run(IdleFlushTimer); GlobalFlushingBehavior.GlobalFlusher.Value.MaybeFlushEnvironment(this); } } LowLevelTransaction tx; _txCommit.EnterReadLock(); try { _cancellationTokenSource.Token.ThrowIfCancellationRequested(); if (_currentTransactionHolder == null) { _currentTransactionHolder = NativeMemory.ThreadAllocations.Value; } long txId = flags == TransactionFlags.ReadWrite ? NextWriteTransactionId : CurrentReadTransactionId; tx = new LowLevelTransaction(this, txId, transactionPersistentContext, flags, _freeSpaceHandling, context) { FlushInProgressLockTaken = flushInProgressReadLockTaken, CurrentTransactionHolder = _currentTransactionHolder }; ActiveTransactions.Add(tx); } finally { _txCommit.ExitReadLock(); } var state = _dataPager.PagerState; tx.EnsurePagerStateReference(state); return(tx); } catch (Exception) { try { if (txLockTaken) { _transactionWriter.Release(); } if (flushInProgressReadLockTaken) { FlushInProgressLock.ExitReadLock(); } } finally { DecrementUsageOnTransactionCreationFailure(); } throw; } }
internal LowLevelTransaction NewLowLevelTransaction(TransactionPersistentContext transactionPersistentContext, TransactionFlags flags, ByteStringContext context = null, TimeSpan?timeout = null) { bool txLockTaken = false; bool flushInProgressReadLockTaken = false; try { if (flags == TransactionFlags.ReadWrite) { var wait = timeout ?? (Debugger.IsAttached ? TimeSpan.FromMinutes(30) : TimeSpan.FromSeconds(30)); if (FlushInProgressLock.IsWriteLockHeld == false) { flushInProgressReadLockTaken = FlushInProgressLock.TryEnterReadLock(wait); } if (Monitor.IsEntered(_txWriter)) { ThrowOnRecursiveWriteTransaction(); } Monitor.TryEnter(_txWriter, wait, ref txLockTaken); if (txLockTaken == false || (flushInProgressReadLockTaken == false && FlushInProgressLock.IsWriteLockHeld == false)) { GlobalFlushingBehavior.GlobalFlusher.Value.MaybeFlushEnvironment(this); ThrowOnTimeoutWaitingForWriteTxLock(wait); } _writeTransactionRunning.SetByAsyncCompletion(); if (_endOfDiskSpace != null) { if (_endOfDiskSpace.CanContinueWriting) { CatastrophicFailure = null; _endOfDiskSpace = null; _cancellationTokenSource = new CancellationTokenSource(); Task.Run(IdleFlushTimer); GlobalFlushingBehavior.GlobalFlusher.Value.MaybeFlushEnvironment(this); } } } LowLevelTransaction tx; _txCommit.EnterReadLock(); try { long txId = flags == TransactionFlags.ReadWrite ? _transactionsCounter + 1 : _transactionsCounter; tx = new LowLevelTransaction(this, txId, transactionPersistentContext, flags, _freeSpaceHandling, context) { FlushInProgressLockTaken = flushInProgressReadLockTaken }; ActiveTransactions.Add(tx); } finally { _txCommit.ExitReadLock(); } var state = _dataPager.PagerState; tx.EnsurePagerStateReference(state); return(tx); } catch (Exception) { if (txLockTaken) { Monitor.Exit(_txWriter); } if (flushInProgressReadLockTaken) { FlushInProgressLock.ExitReadLock(); } throw; } }
internal LowLevelTransaction NewLowLevelTransaction(TransactionFlags flags, ByteStringContext context = null, TimeSpan?timeout = null) { bool txLockTaken = false; bool flushInProgressReadLockTaken = false; try { if (flags == TransactionFlags.ReadWrite) { var wait = timeout ?? (Debugger.IsAttached ? TimeSpan.FromMinutes(30) : TimeSpan.FromSeconds(30)); if (FlushInProgressLock.IsWriteLockHeld == false) { flushInProgressReadLockTaken = FlushInProgressLock.TryEnterReadLock(wait); } Monitor.TryEnter(_txWriter, wait, ref txLockTaken); if (txLockTaken == false || (flushInProgressReadLockTaken == false && FlushInProgressLock.IsWriteLockHeld == false)) { GlobalFlusher.Value.MaybeFlushEnvironment(this); throw new TimeoutException("Waited for " + wait + " for transaction write lock, but could not get it"); } if (_endOfDiskSpace != null) { if (_endOfDiskSpace.CanContinueWriting) { _flushingTaskFailure = null; _endOfDiskSpace = null; _cancellationTokenSource = new CancellationTokenSource(); Task.Run(IdleFlushTimer); GlobalFlusher.Value.MaybeFlushEnvironment(this); } } } LowLevelTransaction tx; _txCommit.EnterReadLock(); try { long txId = flags == TransactionFlags.ReadWrite ? _transactionsCounter + 1 : _transactionsCounter; tx = new LowLevelTransaction(this, txId, flags, _freeSpaceHandling, context); } finally { _txCommit.ExitReadLock(); } _activeTransactions.Add(tx); var state = _dataPager.PagerState; tx.EnsurePagerStateReference(state); return(tx); } catch (Exception) { if (txLockTaken) { Monitor.Exit(_txWriter); } if (flushInProgressReadLockTaken) { FlushInProgressLock.ExitReadLock(); } throw; } }