Esempio n. 1
0
        internal override void DecrementOutstandingNotifications(bool voteYes)
        {
            bool flag = false;
            IPhase0EnlistmentShim shim = null;

            lock (this)
            {
                if (DiagnosticTrace.Verbose)
                {
                    string methodName = "OletxPhase0VolatileEnlistmentContainer.DecrementOutstandingNotifications, outstandingNotifications = " + this.outstandingNotifications.ToString(CultureInfo.CurrentCulture) + ", incompleteDependentClones = " + this.incompleteDependentClones.ToString(CultureInfo.CurrentCulture);
                    MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), methodName);
                }
                base.outstandingNotifications--;
                base.collectedVoteYes = base.collectedVoteYes && voteYes;
                if ((base.outstandingNotifications == 0) && (base.incompleteDependentClones == 0))
                {
                    if ((base.phase == 0) && !base.alreadyVoted)
                    {
                        flag = true;
                        base.alreadyVoted = true;
                        shim = this.phase0EnlistmentShim;
                    }
                    base.realOletxTransaction.DecrementUndecidedEnlistments();
                }
            }
            try
            {
                if (flag && (shim != null))
                {
                    shim.Phase0Done(base.collectedVoteYes && !base.realOletxTransaction.Doomed);
                }
            }
            catch (COMException exception)
            {
                if ((System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN == exception.ErrorCode) || (System.Transactions.Oletx.NativeMethods.XACT_E_TMNOTAVAILABLE == exception.ErrorCode))
                {
                    if (DiagnosticTrace.Verbose)
                    {
                        ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
                    }
                }
                else
                {
                    if (System.Transactions.Oletx.NativeMethods.XACT_E_PROTOCOL != exception.ErrorCode)
                    {
                        throw;
                    }
                    this.phase0EnlistmentShim = null;
                    if (DiagnosticTrace.Verbose)
                    {
                        ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
                    }
                }
            }
            if (DiagnosticTrace.Verbose)
            {
                string str = "OletxPhase0VolatileEnlistmentContainer.DecrementOutstandingNotifications";
                MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), str);
            }
        }
 internal OletxEnlistment(bool canDoSinglePhase, IEnlistmentNotificationInternal enlistmentNotification, Guid transactionGuid, EnlistmentOptions enlistmentOptions, OletxResourceManager oletxResourceManager, OletxTransaction oletxTransaction) : base(oletxResourceManager, oletxTransaction)
 {
     this.transactionGuid         = Guid.Empty;
     this.phase1Handle            = IntPtr.Zero;
     this.enlistmentShim          = null;
     this.phase0Shim              = null;
     this.canDoSinglePhase        = canDoSinglePhase;
     this.iEnlistmentNotification = enlistmentNotification;
     this.state                     = OletxEnlistmentState.Active;
     this.transactionGuid           = transactionGuid;
     this.proxyPrepareInfoByteArray = null;
     if (DiagnosticTrace.Information)
     {
         EnlistmentTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentType.Durable, enlistmentOptions);
     }
     base.AddToEnlistmentTable();
 }
Esempio n. 3
0
        internal OletxPhase0VolatileEnlistmentContainer(
            RealOletxTransaction realOletxTransaction
            )
        {
            Debug.Assert( null != realOletxTransaction, "Argument is null" );

            // This will be set later, after the caller creates the enlistment with the proxy.
            this.phase0EnlistmentShim = null;

            this.realOletxTransaction = realOletxTransaction;
            this.phase = -1;
            this.aborting = false;
            this.tmWentDown = false;
            this.outstandingNotifications = 0;
            this.incompleteDependentClones = 0;
            this.alreadyVoted = false;
            // If anybody votes false, this will get set to false.
            this.collectedVoteYes = true;
            this.enlistmentList = new ArrayList();

            // This is a new undecided enlistment on the transaction.  Do this last since it has side affects.
            realOletxTransaction.IncrementUndecidedEnlistments();
        }
Esempio n. 4
0
        internal OletxEnlistment(
            bool canDoSinglePhase,
            IEnlistmentNotificationInternal enlistmentNotification,
            Guid transactionGuid,
            EnlistmentOptions enlistmentOptions,
            OletxResourceManager oletxResourceManager,
            OletxTransaction oletxTransaction
            ) : base( oletxResourceManager, oletxTransaction )
        {
            Guid myGuid = Guid.Empty;

            // This will get set later by the creator of this object after it
            // has enlisted with the proxy.
            this.enlistmentShim = null;
            this.phase0Shim = null;

            this.canDoSinglePhase = canDoSinglePhase;
            this.iEnlistmentNotification = enlistmentNotification;
            this.state = OletxEnlistmentState.Active;
            this.transactionGuid = transactionGuid;

            this.proxyPrepareInfoByteArray = null;

            if ( DiagnosticTrace.Information )
            {
                EnlistmentTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    this.InternalTraceIdentifier,
                    EnlistmentType.Durable,
                    enlistmentOptions
                    );
            }

            // Always do this last incase anything earlier fails.
            AddToEnlistmentTable();
        }
Esempio n. 5
0
        internal OletxEnlistment(
            IEnlistmentNotificationInternal enlistmentNotification,
            OletxTransactionStatus xactStatus,
            byte[] prepareInfoByteArray,
            OletxResourceManager oletxResourceManager
            ) : base( oletxResourceManager, null )
        {
            Guid myGuid = Guid.Empty;

            // This will get set later by the creator of this object after it
            // has enlisted with the proxy.
            this.enlistmentShim = null;
            this.phase0Shim = null;

            this.canDoSinglePhase = false;
            this.iEnlistmentNotification = enlistmentNotification;
            this.state = OletxEnlistmentState.Active;

            // Do this before we do any tracing because it will affect the trace identifiers that we generate.
            Debug.Assert( ( null != prepareInfoByteArray ),  
                "OletxEnlistment.ctor - null oletxTransaction without a prepareInfoByteArray" );

            int prepareInfoLength = prepareInfoByteArray.Length;
            this.proxyPrepareInfoByteArray = new byte[prepareInfoLength];
            Array.Copy(prepareInfoByteArray, proxyPrepareInfoByteArray, prepareInfoLength);

            byte[] txGuidByteArray = new byte[16];
            Array.Copy(proxyPrepareInfoByteArray, txGuidByteArray, 16);

            this.transactionGuid = new Guid( txGuidByteArray );
            this.transactionGuidString = this.transactionGuid.ToString();
            
            // If this is being created as part of a Reenlist and we already know the
            // outcome, then tell the application.
            switch (xactStatus)
            {
                case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_ABORTED:
                {
                    this.state = OletxEnlistmentState.Aborting;
                    if ( DiagnosticTrace.Verbose )
                    {
                        EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            this.InternalTraceIdentifier,
                            NotificationCall.Rollback
                            );
                    }

                    iEnlistmentNotification.Rollback( this );
                    break;
                }

                case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_COMMITTED:
                {
                    this.state = OletxEnlistmentState.Committing;
                    // We are going to send the notification to the RM.  We need to put the
                    // enlistment on the reenlistPendingList.  We lock the reenlistList because
                    // we have decided that is the lock that protects both lists.  The entry will
                    // be taken off the reenlistPendingList when the enlistment has
                    // EnlistmentDone called on it.  The enlistment will call
                    // RemoveFromReenlistPending.
                    lock ( oletxResourceManager.reenlistList )
                    {
                        oletxResourceManager.reenlistPendingList.Add( this );
                    }

                    if ( DiagnosticTrace.Verbose )
                    {
                        EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            this.InternalTraceIdentifier,
                            NotificationCall.Commit
                            );
                    }

                    iEnlistmentNotification.Commit( this );
                    break;
                }

                case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED:
                {
                    this.state = OletxEnlistmentState.Prepared;
                    lock ( oletxResourceManager.reenlistList )
                    {
                        oletxResourceManager.reenlistList.Add( this );
                        oletxResourceManager.StartReenlistThread();
                    }
                    break;
                }

                default:
                {
                    if ( DiagnosticTrace.Critical )
                    {
                        InternalErrorTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            SR.GetString( SR.OletxEnlistmentUnexpectedTransactionStatus )
                            );
                    }

                    throw TransactionException.Create( SR.GetString( SR.TraceSourceOletx ), SR.GetString( SR.OletxEnlistmentUnexpectedTransactionStatus ), null );
                }
            }

            if ( DiagnosticTrace.Information )
            {
                EnlistmentTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    this.InternalTraceIdentifier,
                    EnlistmentType.Durable,
                    EnlistmentOptions.None
                    );
            }

            // Always do this last in case anything prior to this fails.
            AddToEnlistmentTable();
        }
Esempio n. 6
0
        internal override void DecrementOutstandingNotifications( bool voteYes )
        {
            bool respondToProxy = false;
            IPhase0EnlistmentShim localPhase0Shim = null;

            lock ( this )
            {
                if ( DiagnosticTrace.Verbose )
                {
                    string description = "OletxPhase0VolatileEnlistmentContainer.DecrementOutstandingNotifications, outstandingNotifications = " +
                        this.outstandingNotifications.ToString( CultureInfo.CurrentCulture ) +
                        ", incompleteDependentClones = " +
                        this.incompleteDependentClones.ToString( CultureInfo.CurrentCulture );
                    MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                        description
                        );
                }
                outstandingNotifications--;
                Debug.Assert( 0 <= outstandingNotifications, "OletxPhase0VolatileEnlistmentContainer.DecrementOutstandingNotifications - outstandingNotifications < 0" );
                
                this.collectedVoteYes = this.collectedVoteYes && voteYes;
                if ( ( 0 == this.outstandingNotifications ) && ( 0 == this.incompleteDependentClones ) )
                {
                    if ( ( 0 == this.phase ) && ( !this.alreadyVoted ) )
                    {
                        respondToProxy = true;
                        this.alreadyVoted = true;
                        localPhase0Shim = this.phase0EnlistmentShim;
                    }
                    this.realOletxTransaction.DecrementUndecidedEnlistments();
                }
            }

            try
            {
                if ( respondToProxy )
                {
                    if ( null != localPhase0Shim )
                    {
                        localPhase0Shim.Phase0Done( ( this.collectedVoteYes ) && ( !this.realOletxTransaction.Doomed ) );
                    }
                }
            }
            catch ( COMException ex )
            {
                if ( ( NativeMethods.XACT_E_CONNECTION_DOWN == ex.ErrorCode ) ||
                    ( NativeMethods.XACT_E_TMNOTAVAILABLE == ex.ErrorCode )
                    )
                {
                    if ( DiagnosticTrace.Verbose )
                    {
                        ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            ex );
                    }
                }
                // In the case of Phase0, there is a bug in the proxy that causes an XACT_E_PROTOCOL
                // error if the TM goes down while the enlistment is still active.  The Phase0Request is
                // sent out with abortHint false, but the state of the proxy object is not changed, causing
                // Phase0Done request to fail with XACT_E_PROTOCOL.
                // For Prepared, we want to make sure the proxy aborts the transaction.  We don't need
                // to drive the abort to the application here because the Phase1 enlistment will do that.
                // In other words, treat this as if the proxy said Phase0Request( abortingHint = true ).
                else if ( NativeMethods.XACT_E_PROTOCOL == ex.ErrorCode )
                {
                    this.phase0EnlistmentShim = null;
                    if ( DiagnosticTrace.Verbose )
                    {
                        ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            ex );
                    }
                }
                else
                {
                    throw;
                }
            }

            if ( DiagnosticTrace.Verbose )
            {
                string description = "OletxPhase0VolatileEnlistmentContainer.DecrementOutstandingNotifications";
                MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    description
                    );
            }
        }
        public void Prepared()
        {
            int                   num1              = System.Transactions.Oletx.NativeMethods.S_OK;
            IEnlistmentShim       enlistmentShim    = null;
            IPhase0EnlistmentShim shim              = null;
            bool                  fabricateRollback = false;

            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxPreparingEnlistment.Prepared");
                EnlistmentCallbackPositiveTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentCallback.Prepared);
            }
            lock (this)
            {
                if (OletxEnlistmentState.Preparing == this.state)
                {
                    enlistmentShim = this.EnlistmentShim;
                }
                else
                {
                    if (OletxEnlistmentState.Phase0Preparing != this.state)
                    {
                        throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null);
                    }
                    shim = this.Phase0EnlistmentShim;
                    if (base.oletxTransaction.realOletxTransaction.Doomed || this.fabricateRollback)
                    {
                        this.fabricateRollback = true;
                        fabricateRollback      = this.fabricateRollback;
                    }
                }
                this.state = OletxEnlistmentState.Prepared;
            }
            try
            {
                if (enlistmentShim != null)
                {
                    enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.Prepared);
                }
                else if (shim != null)
                {
                    base.oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments();
                    shim.Phase0Done(!fabricateRollback);
                }
                else
                {
                    fabricateRollback = true;
                }
                if (fabricateRollback)
                {
                    this.AbortRequest();
                }
            }
            catch (COMException exception)
            {
                if ((System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN == exception.ErrorCode) || (System.Transactions.Oletx.NativeMethods.XACT_E_TMNOTAVAILABLE == exception.ErrorCode))
                {
                    if (DiagnosticTrace.Verbose)
                    {
                        ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
                    }
                }
                else
                {
                    if (System.Transactions.Oletx.NativeMethods.XACT_E_PROTOCOL != exception.ErrorCode)
                    {
                        throw;
                    }
                    this.Phase0EnlistmentShim = null;
                    if (DiagnosticTrace.Verbose)
                    {
                        ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
                    }
                }
            }
            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxPreparingEnlistment.Prepared");
            }
        }
        public void EnlistmentDone()
        {
            bool flag;

            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.EnlistmentDone");
                EnlistmentCallbackPositiveTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentCallback.Done);
            }
            IEnlistmentShim       enlistmentShim = null;
            IPhase0EnlistmentShim shim2          = null;
            OletxEnlistmentState  active         = OletxEnlistmentState.Active;
            bool fabricateRollback = false;

            lock (this)
            {
                active = this.state;
                if (this.state == OletxEnlistmentState.Active)
                {
                    shim2 = this.Phase0EnlistmentShim;
                    if (shim2 != null)
                    {
                        base.oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments();
                    }
                    flag = false;
                }
                else if (OletxEnlistmentState.Preparing == this.state)
                {
                    enlistmentShim = this.EnlistmentShim;
                    flag           = true;
                }
                else if (OletxEnlistmentState.Phase0Preparing == this.state)
                {
                    shim2 = this.Phase0EnlistmentShim;
                    base.oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments();
                    if (this.fabricateRollback)
                    {
                        flag = true;
                    }
                    else
                    {
                        flag = false;
                    }
                }
                else
                {
                    if (((OletxEnlistmentState.Committing != this.state) && (OletxEnlistmentState.Aborting != this.state)) && (OletxEnlistmentState.SinglePhaseCommitting != this.state))
                    {
                        throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null);
                    }
                    enlistmentShim = this.EnlistmentShim;
                    flag           = true;
                }
                fabricateRollback = this.fabricateRollback;
                this.state        = OletxEnlistmentState.Done;
            }
            try
            {
                if (enlistmentShim != null)
                {
                    if (OletxEnlistmentState.Preparing == active)
                    {
                        try
                        {
                            enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.ReadOnly);
                            goto Label_01C1;
                        }
                        finally
                        {
                            HandleTable.FreeHandle(this.phase1Handle);
                        }
                    }
                    if (OletxEnlistmentState.Committing != active)
                    {
                        if (OletxEnlistmentState.Aborting != active)
                        {
                            if (OletxEnlistmentState.SinglePhaseCommitting != active)
                            {
                                throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null);
                            }
                            enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.SinglePhase);
                        }
                        else if (!fabricateRollback)
                        {
                            enlistmentShim.AbortRequestDone();
                        }
                    }
                    else
                    {
                        enlistmentShim.CommitRequestDone();
                    }
                }
                else if (shim2 != null)
                {
                    if (active != OletxEnlistmentState.Active)
                    {
                        if (OletxEnlistmentState.Phase0Preparing != active)
                        {
                            throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null);
                        }
                        shim2.Phase0Done(true);
                    }
                    else
                    {
                        shim2.Unenlist();
                    }
                }
            }
            catch (COMException exception)
            {
                flag = true;
                if (DiagnosticTrace.Verbose)
                {
                    ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
                }
            }
            finally
            {
                if (flag)
                {
                    this.FinishEnlistment();
                }
            }
Label_01C1:
            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.EnlistmentDone");
            }
        }
        public void ForceRollback(Exception e)
        {
            IPhase0EnlistmentShim shim           = null;
            IEnlistmentShim       enlistmentShim = null;

            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxPreparingEnlistment.ForceRollback");
            }
            if (DiagnosticTrace.Warning)
            {
                EnlistmentCallbackNegativeTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentCallback.ForceRollback);
            }
            lock (this)
            {
                if (OletxEnlistmentState.Preparing == this.state)
                {
                    enlistmentShim = this.EnlistmentShim;
                }
                else
                {
                    if (OletxEnlistmentState.Phase0Preparing != this.state)
                    {
                        throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null);
                    }
                    shim = this.Phase0EnlistmentShim;
                    if (shim != null)
                    {
                        base.oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments();
                    }
                }
                this.state = OletxEnlistmentState.Aborted;
            }
            Interlocked.CompareExchange <Exception>(ref base.oletxTransaction.realOletxTransaction.innerException, e, null);
            try
            {
                if (enlistmentShim != null)
                {
                    try
                    {
                        enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.Failed);
                    }
                    finally
                    {
                        HandleTable.FreeHandle(this.phase1Handle);
                    }
                }
                if (shim != null)
                {
                    shim.Phase0Done(false);
                }
            }
            catch (COMException exception)
            {
                if ((System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN != exception.ErrorCode) && (System.Transactions.Oletx.NativeMethods.XACT_E_TMNOTAVAILABLE != exception.ErrorCode))
                {
                    throw;
                }
                if (DiagnosticTrace.Verbose)
                {
                    ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
                }
            }
            finally
            {
                this.FinishEnlistment();
            }
            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxPreparingEnlistment.ForceRollback");
            }
        }
 internal OletxEnlistment(bool canDoSinglePhase, IEnlistmentNotificationInternal enlistmentNotification, Guid transactionGuid, EnlistmentOptions enlistmentOptions, OletxResourceManager oletxResourceManager, OletxTransaction oletxTransaction) : base(oletxResourceManager, oletxTransaction)
 {
     this.transactionGuid = Guid.Empty;
     this.phase1Handle = IntPtr.Zero;
     this.enlistmentShim = null;
     this.phase0Shim = null;
     this.canDoSinglePhase = canDoSinglePhase;
     this.iEnlistmentNotification = enlistmentNotification;
     this.state = OletxEnlistmentState.Active;
     this.transactionGuid = transactionGuid;
     this.proxyPrepareInfoByteArray = null;
     if (DiagnosticTrace.Information)
     {
         EnlistmentTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentType.Durable, enlistmentOptions);
     }
     base.AddToEnlistmentTable();
 }
        internal OletxEnlistment(IEnlistmentNotificationInternal enlistmentNotification, OletxTransactionStatus xactStatus, byte[] prepareInfoByteArray, OletxResourceManager oletxResourceManager) : base(oletxResourceManager, null)
        {
            this.transactionGuid         = Guid.Empty;
            this.phase1Handle            = IntPtr.Zero;
            this.enlistmentShim          = null;
            this.phase0Shim              = null;
            this.canDoSinglePhase        = false;
            this.iEnlistmentNotification = enlistmentNotification;
            this.state = OletxEnlistmentState.Active;
            int length = prepareInfoByteArray.Length;

            this.proxyPrepareInfoByteArray = new byte[length];
            Array.Copy(prepareInfoByteArray, this.proxyPrepareInfoByteArray, length);
            byte[] destinationArray = new byte[0x10];
            Array.Copy(this.proxyPrepareInfoByteArray, destinationArray, 0x10);
            this.transactionGuid       = new Guid(destinationArray);
            base.transactionGuidString = this.transactionGuid.ToString();
            switch (xactStatus)
            {
            case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED:
                this.state = OletxEnlistmentState.Prepared;
                lock (oletxResourceManager.reenlistList)
                {
                    oletxResourceManager.reenlistList.Add(this);
                    oletxResourceManager.StartReenlistThread();
                    goto Label_01CD;
                }
                break;

            case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_ABORTED:
                this.state = OletxEnlistmentState.Aborting;
                if (DiagnosticTrace.Verbose)
                {
                    EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Rollback);
                }
                this.iEnlistmentNotification.Rollback(this);
                goto Label_01CD;

            case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_COMMITTED:
                this.state = OletxEnlistmentState.Committing;
                lock (oletxResourceManager.reenlistList)
                {
                    oletxResourceManager.reenlistPendingList.Add(this);
                }
                if (DiagnosticTrace.Verbose)
                {
                    EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Commit);
                }
                this.iEnlistmentNotification.Commit(this);
                goto Label_01CD;
            }
            if (DiagnosticTrace.Critical)
            {
                InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("OletxEnlistmentUnexpectedTransactionStatus"));
            }
            throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("OletxEnlistmentUnexpectedTransactionStatus"), null);
Label_01CD:
            if (DiagnosticTrace.Information)
            {
                EnlistmentTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentType.Durable, EnlistmentOptions.None);
            }
            base.AddToEnlistmentTable();
        }
        internal OletxEnlistment(IEnlistmentNotificationInternal enlistmentNotification, OletxTransactionStatus xactStatus, byte[] prepareInfoByteArray, OletxResourceManager oletxResourceManager) : base(oletxResourceManager, null)
        {
            this.transactionGuid = Guid.Empty;
            this.phase1Handle = IntPtr.Zero;
            this.enlistmentShim = null;
            this.phase0Shim = null;
            this.canDoSinglePhase = false;
            this.iEnlistmentNotification = enlistmentNotification;
            this.state = OletxEnlistmentState.Active;
            int length = prepareInfoByteArray.Length;
            this.proxyPrepareInfoByteArray = new byte[length];
            Array.Copy(prepareInfoByteArray, this.proxyPrepareInfoByteArray, length);
            byte[] destinationArray = new byte[0x10];
            Array.Copy(this.proxyPrepareInfoByteArray, destinationArray, 0x10);
            this.transactionGuid = new Guid(destinationArray);
            base.transactionGuidString = this.transactionGuid.ToString();
            switch (xactStatus)
            {
                case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED:
                    this.state = OletxEnlistmentState.Prepared;
                    lock (oletxResourceManager.reenlistList)
                    {
                        oletxResourceManager.reenlistList.Add(this);
                        oletxResourceManager.StartReenlistThread();
                        goto Label_01CD;
                    }
                    break;

                case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_ABORTED:
                    this.state = OletxEnlistmentState.Aborting;
                    if (DiagnosticTrace.Verbose)
                    {
                        EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Rollback);
                    }
                    this.iEnlistmentNotification.Rollback(this);
                    goto Label_01CD;

                case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_COMMITTED:
                    this.state = OletxEnlistmentState.Committing;
                    lock (oletxResourceManager.reenlistList)
                    {
                        oletxResourceManager.reenlistPendingList.Add(this);
                    }
                    if (DiagnosticTrace.Verbose)
                    {
                        EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Commit);
                    }
                    this.iEnlistmentNotification.Commit(this);
                    goto Label_01CD;
            }
            if (DiagnosticTrace.Critical)
            {
                InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("OletxEnlistmentUnexpectedTransactionStatus"));
            }
            throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("OletxEnlistmentUnexpectedTransactionStatus"), null);
        Label_01CD:
            if (DiagnosticTrace.Information)
            {
                EnlistmentTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentType.Durable, EnlistmentOptions.None);
            }
            base.AddToEnlistmentTable();
        }
 internal override void DecrementOutstandingNotifications(bool voteYes)
 {
     bool flag = false;
     IPhase0EnlistmentShim shim = null;
     lock (this)
     {
         if (DiagnosticTrace.Verbose)
         {
             string methodName = "OletxPhase0VolatileEnlistmentContainer.DecrementOutstandingNotifications, outstandingNotifications = " + this.outstandingNotifications.ToString(CultureInfo.CurrentCulture) + ", incompleteDependentClones = " + this.incompleteDependentClones.ToString(CultureInfo.CurrentCulture);
             MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), methodName);
         }
         base.outstandingNotifications--;
         base.collectedVoteYes = base.collectedVoteYes && voteYes;
         if ((base.outstandingNotifications == 0) && (base.incompleteDependentClones == 0))
         {
             if ((base.phase == 0) && !base.alreadyVoted)
             {
                 flag = true;
                 base.alreadyVoted = true;
                 shim = this.phase0EnlistmentShim;
             }
             base.realOletxTransaction.DecrementUndecidedEnlistments();
         }
     }
     try
     {
         if (flag && (shim != null))
         {
             shim.Phase0Done(base.collectedVoteYes && !base.realOletxTransaction.Doomed);
         }
     }
     catch (COMException exception)
     {
         if ((System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN == exception.ErrorCode) || (System.Transactions.Oletx.NativeMethods.XACT_E_TMNOTAVAILABLE == exception.ErrorCode))
         {
             if (DiagnosticTrace.Verbose)
             {
                 ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
             }
         }
         else
         {
             if (System.Transactions.Oletx.NativeMethods.XACT_E_PROTOCOL != exception.ErrorCode)
             {
                 throw;
             }
             this.phase0EnlistmentShim = null;
             if (DiagnosticTrace.Verbose)
             {
                 ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
             }
         }
     }
     if (DiagnosticTrace.Verbose)
     {
         string str = "OletxPhase0VolatileEnlistmentContainer.DecrementOutstandingNotifications";
         MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), str);
     }
 }
        internal OletxVolatileEnlistmentContainer AddDependentClone(bool delayCommit)
        {
            IVoterBallotShim      voterBallotShim = null;
            IPhase0EnlistmentShim shim2           = null;
            bool flag2 = false;
            bool flag  = false;
            OletxVolatileEnlistmentContainer       container3 = null;
            OletxPhase0VolatileEnlistmentContainer container  = null;
            OletxPhase1VolatileEnlistmentContainer target     = null;
            bool   flag3 = false;
            bool   flag5 = false;
            IntPtr zero  = IntPtr.Zero;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                lock (this)
                {
                    if (delayCommit)
                    {
                        if (this.phase0EnlistVolatilementContainerList == null)
                        {
                            this.phase0EnlistVolatilementContainerList = new ArrayList(1);
                        }
                        if (this.phase0EnlistVolatilementContainerList.Count == 0)
                        {
                            container = new OletxPhase0VolatileEnlistmentContainer(this);
                            flag      = true;
                        }
                        else
                        {
                            container = this.phase0EnlistVolatilementContainerList[this.phase0EnlistVolatilementContainerList.Count - 1] as OletxPhase0VolatileEnlistmentContainer;
                            if (container != null)
                            {
                                this.TakeContainerLock(container, ref flag5);
                            }
                            if (!container.NewEnlistmentsAllowed)
                            {
                                this.ReleaseContainerLock(container, ref flag5);
                                container = new OletxPhase0VolatileEnlistmentContainer(this);
                                flag      = true;
                            }
                            else
                            {
                                flag = false;
                            }
                        }
                        if (flag)
                        {
                            zero = HandleTable.AllocHandle(container);
                        }
                    }
                    else if (this.phase1EnlistVolatilementContainer == null)
                    {
                        target             = new OletxPhase1VolatileEnlistmentContainer(this);
                        flag2              = true;
                        target.voterHandle = HandleTable.AllocHandle(target);
                    }
                    else
                    {
                        flag2  = false;
                        target = this.phase1EnlistVolatilementContainer;
                    }
                    try
                    {
                        if (container != null)
                        {
                            this.TakeContainerLock(container, ref flag5);
                        }
                        if (flag)
                        {
                            this.transactionShim.Phase0Enlist(zero, out shim2);
                            container.Phase0EnlistmentShim = shim2;
                        }
                        if (flag2)
                        {
                            this.OletxTransactionManagerInstance.dtcTransactionManagerLock.AcquireReaderLock(-1);
                            try
                            {
                                this.transactionShim.CreateVoter(target.voterHandle, out voterBallotShim);
                                flag3 = true;
                            }
                            finally
                            {
                                this.OletxTransactionManagerInstance.dtcTransactionManagerLock.ReleaseReaderLock();
                            }
                            target.VoterBallotShim = voterBallotShim;
                        }
                        if (delayCommit)
                        {
                            if (flag)
                            {
                                this.phase0EnlistVolatilementContainerList.Add(container);
                            }
                            container.AddDependentClone();
                            return(container);
                        }
                        if (flag2)
                        {
                            this.phase1EnlistVolatilementContainer = target;
                        }
                        target.AddDependentClone();
                        return(target);
                    }
                    catch (COMException exception)
                    {
                        OletxTransactionManager.ProxyException(exception);
                        throw;
                    }
                    return(container3);
                }
            }
            finally
            {
                if (container != null)
                {
                    this.ReleaseContainerLock(container, ref flag5);
                }
                if ((zero != IntPtr.Zero) && (container.Phase0EnlistmentShim == null))
                {
                    HandleTable.FreeHandle(zero);
                }
                if ((!flag3 && (target != null)) && ((target.voterHandle != IntPtr.Zero) && flag2))
                {
                    HandleTable.FreeHandle(target.voterHandle);
                }
            }
            return(container3);
        }
        internal IPromotedEnlistment CommonEnlistVolatile(IEnlistmentNotificationInternal enlistmentNotification, EnlistmentOptions enlistmentOptions, OletxTransaction oletxTransaction)
        {
            OletxVolatileEnlistment enlistment = null;
            bool flag2 = false;
            bool flag  = false;
            OletxPhase0VolatileEnlistmentContainer target    = null;
            OletxPhase1VolatileEnlistmentContainer container = null;
            IntPtr                zero            = IntPtr.Zero;
            IVoterBallotShim      voterBallotShim = null;
            IPhase0EnlistmentShim shim            = null;
            bool flag3 = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                lock (this)
                {
                    enlistment = new OletxVolatileEnlistment(enlistmentNotification, enlistmentOptions, oletxTransaction);
                    if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None)
                    {
                        if (this.phase0EnlistVolatilementContainerList == null)
                        {
                            this.phase0EnlistVolatilementContainerList = new ArrayList(1);
                        }
                        if (this.phase0EnlistVolatilementContainerList.Count == 0)
                        {
                            target = new OletxPhase0VolatileEnlistmentContainer(this);
                            flag   = true;
                        }
                        else
                        {
                            target = this.phase0EnlistVolatilementContainerList[this.phase0EnlistVolatilementContainerList.Count - 1] as OletxPhase0VolatileEnlistmentContainer;
                            if (!target.NewEnlistmentsAllowed)
                            {
                                target = new OletxPhase0VolatileEnlistmentContainer(this);
                                flag   = true;
                            }
                            else
                            {
                                flag = false;
                            }
                        }
                        if (flag)
                        {
                            zero = HandleTable.AllocHandle(target);
                        }
                    }
                    else if (this.phase1EnlistVolatilementContainer == null)
                    {
                        flag2     = true;
                        container = new OletxPhase1VolatileEnlistmentContainer(this)
                        {
                            voterHandle = HandleTable.AllocHandle(container)
                        };
                    }
                    else
                    {
                        flag2     = false;
                        container = this.phase1EnlistVolatilementContainer;
                    }
                    try
                    {
                        if (flag)
                        {
                            lock (target)
                            {
                                this.transactionShim.Phase0Enlist(zero, out shim);
                                target.Phase0EnlistmentShim = shim;
                            }
                        }
                        if (flag2)
                        {
                            this.transactionShim.CreateVoter(container.voterHandle, out voterBallotShim);
                            flag3 = true;
                            container.VoterBallotShim = voterBallotShim;
                        }
                        if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None)
                        {
                            target.AddEnlistment(enlistment);
                            if (flag)
                            {
                                this.phase0EnlistVolatilementContainerList.Add(target);
                            }
                            return(enlistment);
                        }
                        container.AddEnlistment(enlistment);
                        if (flag2)
                        {
                            this.phase1EnlistVolatilementContainer = container;
                        }
                        return(enlistment);
                    }
                    catch (COMException exception)
                    {
                        OletxTransactionManager.ProxyException(exception);
                        throw;
                    }
                    return(enlistment);
                }
            }
            finally
            {
                if ((zero != IntPtr.Zero) && (target.Phase0EnlistmentShim == null))
                {
                    HandleTable.FreeHandle(zero);
                }
                if ((!flag3 && (container != null)) && ((container.voterHandle != IntPtr.Zero) && flag2))
                {
                    HandleTable.FreeHandle(container.voterHandle);
                }
            }
            return(enlistment);
        }
Esempio n. 16
0
        internal OletxEnlistment EnlistDurable(OletxTransaction oletxTransaction, bool canDoSinglePhase, IEnlistmentNotificationInternal enlistmentNotification, EnlistmentOptions enlistmentOptions)
        {
            IResourceManagerShim  resourceManagerShim = null;
            IPhase0EnlistmentShim shim2          = null;
            IEnlistmentShim       enlistmentShim = null;
            IntPtr          zero   = IntPtr.Zero;
            bool            flag3  = false;
            bool            flag2  = false;
            OletxEnlistment target = new OletxEnlistment(canDoSinglePhase, enlistmentNotification, oletxTransaction.RealTransaction.TxGuid, enlistmentOptions, this, oletxTransaction);
            bool            flag   = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None)
                {
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try
                    {
                    }
                    finally
                    {
                        oletxTransaction.RealTransaction.IncrementUndecidedEnlistments();
                        flag2 = true;
                    }
                }
                lock (target)
                {
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try
                    {
                        resourceManagerShim = this.ResourceManagerShim;
                        if (resourceManagerShim == null)
                        {
                            throw TransactionManagerCommunicationException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), null);
                        }
                        if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None)
                        {
                            zero = HandleTable.AllocHandle(target);
                            RuntimeHelpers.PrepareConstrainedRegions();
                            try
                            {
                            }
                            finally
                            {
                                oletxTransaction.RealTransaction.TransactionShim.Phase0Enlist(zero, out shim2);
                                flag3 = true;
                            }
                            target.Phase0EnlistmentShim = shim2;
                        }
                        target.phase1Handle = HandleTable.AllocHandle(target);
                        resourceManagerShim.Enlist(oletxTransaction.RealTransaction.TransactionShim, target.phase1Handle, out enlistmentShim);
                        target.EnlistmentShim = enlistmentShim;
                    }
                    catch (COMException exception)
                    {
                        if (System.Transactions.Oletx.NativeMethods.XACT_E_TOOMANY_ENLISTMENTS == exception.ErrorCode)
                        {
                            throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("OletxTooManyEnlistments"), exception);
                        }
                        OletxTransactionManager.ProxyException(exception);
                        throw;
                    }
                    finally
                    {
                        if (target.EnlistmentShim == null)
                        {
                            if ((zero != IntPtr.Zero) && !flag3)
                            {
                                HandleTable.FreeHandle(zero);
                            }
                            if (target.phase1Handle != IntPtr.Zero)
                            {
                                HandleTable.FreeHandle(target.phase1Handle);
                            }
                        }
                    }
                }
                flag = true;
            }
            finally
            {
                if ((!flag && ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None)) && flag2)
                {
                    oletxTransaction.RealTransaction.DecrementUndecidedEnlistments();
                }
            }
            return(target);
        }