OnLogicalLogClose(LogicalLog ToClose, CancellationToken cancellationToken) { await _Lock.WaitUntilSetAsync(cancellationToken).ConfigureAwait(false); try { PhysicalLog handleOwner = null; ReleaseAssert.AssertIfNot(_Logs.TryGetValue(ToClose.OwnerId, out handleOwner), "_Logs index is inconsistent"); if (await handleOwner.OnCloseLogicalLog(ToClose, cancellationToken).ConfigureAwait(false)) { // last handle or logical log closed on the PhysicalLog, removed from this index _Logs.Remove(ToClose.OwnerId); if ((_Handles.Count == 0) && (_Logs.Count == 0)) { var m = _AppDomainPhysLogManager; _AppDomainPhysLogManager = null; await m.CloseAsync(cancellationToken).ConfigureAwait(false); } } } finally { _Lock.Set(); } }
OnCloseLogicalLog(LogicalLog toClose, CancellationToken cancellationToken) { await this._PhysicalLogLock.WaitUntilSetAsync(cancellationToken).ConfigureAwait(false); try { LogicalLogInfo llInfo; if (this._LogicalLogs.TryGetValue(toClose.Id, out llInfo) == false) { ReleaseAssert.Failfast("toClose missing from _LogicalLogs"); } await llInfo.UnderlyingStream.CloseAsync(cancellationToken).ConfigureAwait(false); ReleaseAssert.AssertIfNot(this._LogicalLogs.Remove(toClose.Id), "handle missing from _LogicalLogs"); if ((this._PhysicalLogHandles.Count == 0) && (this._LogicalLogs.Count == 0)) { await this._Container.CloseAsync(cancellationToken).ConfigureAwait(false); this.IsOpen = false; return(true); // Indicate p.log was closed } return(false); } finally { this._PhysicalLogLock.Set(); } }
public LogicalLogInfo(LogicalLog logicalLog, IPhysicalLogStream underlyingStream) { this.LogicalLog = new WeakReference <LogicalLog>(logicalLog); this.UnderlyingStream = underlyingStream; }
OnOpenLogicalLogAsync( Handle owningHandle, Guid logicalLogId, string traceType, CancellationToken cancellationToken) { await this._PhysicalLogLock.WaitUntilSetAsync(cancellationToken).ConfigureAwait(false); try { LogicalLog logicalLog = null; LogicalLogInfo llInfo; if ((this._LogicalLogs.TryGetValue(logicalLogId, out llInfo) == false) || (llInfo.LogicalLog.TryGetTarget(out logicalLog) == false)) { // LLog has not been opened or created - attempt to open it IPhysicalLogStream underlyingStream = null; var retries = 0; const int retryLimit = 3; do { try { underlyingStream = await this._Container.OpenPhysicalLogStreamAsync( logicalLogId, cancellationToken).ConfigureAwait(false); retries = retryLimit; } catch (System.IO.FileLoadException ex) { retries++; if ((ex.HResult != unchecked ((int)0x80070020)) || (retries == retryLimit)) { throw; } } } while (retries < retryLimit); Exception caughtException = null; LogicalLog newLogicalLog = null; try { newLogicalLog = new LogicalLog(this, owningHandle.Id, logicalLogId, underlyingStream, traceType); this._LogicalLogs.Add(logicalLogId, new LogicalLogInfo(newLogicalLog, underlyingStream)); newLogicalLog.IsOpen = true; await newLogicalLog.OnRecoverAsync(cancellationToken).ConfigureAwait(false); } catch (Exception ex) { // Cause clean up failed create caughtException = ex; } if (caughtException != null) { // clean up failed create and forward the causing exception if (newLogicalLog != null) { newLogicalLog.IsOpen = false; this._LogicalLogs.Remove(logicalLogId); } // TODO: Consider adding trace output when secondary exceptions occur try { await underlyingStream.CloseAsync(cancellationToken).ConfigureAwait(false); } catch { } throw caughtException; } return(newLogicalLog); } else { // Already open - fault - only exclusive opens supported throw new UnauthorizedAccessException(); } } finally { this._PhysicalLogLock.Set(); } }
OnCreateLogicalLogAsync( Handle owningHandle, Guid logicalLogId, string optionalLogStreamAlias, string path, FileSecurity optionalSecurityInfo, Int64 maximumSize, UInt32 maximumBlockSize, LogManager.LogCreationFlags creationFlags, string traceType, CancellationToken cancellationToken) { Requires.Argument("path", path).NotNull(); await this._PhysicalLogLock.WaitUntilSetAsync(cancellationToken).ConfigureAwait(false); try { LogicalLog logicalLog = null; LogicalLogInfo llInfo; if ((this._LogicalLogs.TryGetValue(logicalLogId, out llInfo) == false) || (llInfo.LogicalLog.TryGetTarget(out logicalLog) == false)) { // LLog has not been opened or created or has gone away - attempt to create it var underlyingStream = await this._Container.CreatePhysicalLogStreamAsync( logicalLogId, KLogicalLogInformation.GetLogicalLogStreamType(), optionalLogStreamAlias, path, optionalSecurityInfo, maximumSize, maximumBlockSize, creationFlags, cancellationToken).ConfigureAwait(false); Exception caughtException = null; try { var newLogicalLog = new LogicalLog(this, owningHandle.Id, logicalLogId, underlyingStream, traceType); if (logicalLog == null) { this._LogicalLogs.Add(logicalLogId, new LogicalLogInfo(newLogicalLog, underlyingStream)); } else { // The LLog was indexed but had gone away - just update the index with the new LLog llInfo.LogicalLog.SetTarget(newLogicalLog); } newLogicalLog.IsOpen = true; await newLogicalLog.OnCreated(cancellationToken).ConfigureAwait(false); return(newLogicalLog); } catch (Exception ex) { // Cause clean up failed create caughtException = ex; } System.Diagnostics.Debug.Assert(caughtException != null); // clean up failed create and forward the causing exception if (logicalLog != null) { this._LogicalLogs.Remove(logicalLogId); } // TODO: Consider adding trace output when secondary exceptions occur try { await underlyingStream.CloseAsync(cancellationToken).ConfigureAwait(false); } catch { } try { await this._Container.DeletePhysicalLogStreamAsync(logicalLogId, cancellationToken).ConfigureAwait(false); } catch { } throw caughtException; } else { // Already open - fault - only exclusive opens supported throw new UnauthorizedAccessException(); } } finally { this._PhysicalLogLock.Set(); } }