Beispiel #1
0
        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();
                }
            }