コード例 #1
0
 internal void RemoveFromReenlistPending(OletxEnlistment enlistment)
 {
     lock (this.reenlistList)
     {
         this.reenlistPendingList.Remove(enlistment);
         lock (this)
         {
             if (((this.reenlistThreadTimer != null) && (this.reenlistList.Count == 0)) && ((this.reenlistPendingList.Count == 0) && !this.reenlistThreadTimer.Change(0, -1)))
             {
                 throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), System.Transactions.SR.GetString("UnexpectedTimerFailure"), null);
             }
         }
     }
 }
コード例 #2
0
        internal IPromotedEnlistment EnlistDurable(Guid resourceManagerIdentifier, ISinglePhaseNotificationInternal singlePhaseNotification, bool canDoSinglePhase, EnlistmentOptions enlistmentOptions)
        {
            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxTransaction.EnlistDurable( ISinglePhaseNotificationInternal )");
            }
            if ((this.realOletxTransaction == null) || this.realOletxTransaction.TooLateForEnlistments)
            {
                throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TooLate"), null);
            }
            OletxEnlistment enlistment = this.realOletxTransaction.OletxTransactionManagerInstance.FindOrRegisterResourceManager(resourceManagerIdentifier).EnlistDurable(this, canDoSinglePhase, singlePhaseNotification, enlistmentOptions);

            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxTransaction.EnlistDurable( ISinglePhaseNotificationInternal )");
            }
            return(enlistment);
        }
コード例 #3
0
        internal void TMDownFromInternalRM(OletxTransactionManager oletxTM)
        {
            OletxEnlistment       enlistment = null;
            IDictionaryEnumerator enumerator = null;
            Hashtable             hashtable  = null;

            this.ResourceManagerShim = null;
            lock (this.enlistmentHashtable.SyncRoot)
            {
                hashtable = (Hashtable)this.enlistmentHashtable.Clone();
            }
            enumerator = hashtable.GetEnumerator();
            while (enumerator.MoveNext())
            {
                enlistment = enumerator.Value as OletxEnlistment;
                if (enlistment != null)
                {
                    enlistment.TMDownFromInternalRM(oletxTM);
                }
            }
        }
コード例 #4
0
        internal OletxEnlistment ReenlistTransaction(
            Guid resourceManagerIdentifier,
            byte[] recoveryInformation,
            IEnlistmentNotificationInternal enlistmentNotification
            )
        {
            if (null == recoveryInformation)
            {
                throw new ArgumentNullException("recoveryInformation");
            }

            if (null == enlistmentNotification)
            {
                throw new ArgumentNullException("enlistmentNotification");
            }

            // Now go find the resource manager in the collection.
            OletxResourceManager oletxResourceManager = RegisterResourceManager(resourceManagerIdentifier);

            if (null == oletxResourceManager)
            {
                throw new ArgumentException(SR.GetString(SR.InvalidArgument), "resourceManagerIdentifier");
            }

            if (oletxResourceManager.RecoveryCompleteCalledByApplication)
            {
                throw new InvalidOperationException(SR.GetString(SR.ReenlistAfterRecoveryComplete));
            }

            // Now ask the resource manager to reenlist.
            OletxEnlistment returnValue = oletxResourceManager.Reenlist(
                recoveryInformation.Length,
                recoveryInformation,
                enlistmentNotification
                );


            return(returnValue);
        }
コード例 #5
0
        internal static void ShimNotificationCallback(object state, bool timeout)
        {
            IntPtr zero = IntPtr.Zero;
            ShimNotificationType none            = ShimNotificationType.None;
            bool                 isSinglePhase   = false;
            bool                 abortingHint    = false;
            uint                 prepareInfoSize = 0;
            CoTaskMemHandle      prepareInfo     = null;
            bool                 releaseRequired = false;
            bool                 flag3           = false;
            IDtcProxyShimFactory factory         = null;

            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxTransactionManager.ShimNotificationCallback");
            }
            Thread.BeginCriticalRegion();
            try
            {
Label_003D:
                factory = proxyShimFactory;
                try
                {
                    object obj2;
                    OletxResourceManager manager2;
                    byte[] buffer;
                    Thread.BeginThreadAffinity();
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try
                    {
                        factory.GetNotification(out zero, out none, out isSinglePhase, out abortingHint, out releaseRequired, out prepareInfoSize, out prepareInfo);
                    }
                    finally
                    {
                        if (releaseRequired)
                        {
                            if (HandleTable.FindHandle(zero) is OletxInternalResourceManager)
                            {
                                processingTmDown = true;
                                Monitor.Enter(proxyShimFactory);
                            }
                            else
                            {
                                releaseRequired = false;
                            }
                            factory.ReleaseNotificationLock();
                        }
                        Thread.EndThreadAffinity();
                    }
                    if (processingTmDown)
                    {
                        lock (proxyShimFactory)
                        {
                        }
                    }
                    if (none != ShimNotificationType.None)
                    {
                        obj2 = HandleTable.FindHandle(zero);
                        switch (none)
                        {
                        case ShimNotificationType.Phase0RequestNotify:
                            try
                            {
                                OletxPhase0VolatileEnlistmentContainer container5 = obj2 as OletxPhase0VolatileEnlistmentContainer;
                                if (container5 != null)
                                {
                                    DiagnosticTrace.SetActivityId(container5.TransactionIdentifier);
                                    container5.Phase0Request(abortingHint);
                                }
                                else
                                {
                                    OletxEnlistment enlistment8 = obj2 as OletxEnlistment;
                                    if (enlistment8 != null)
                                    {
                                        DiagnosticTrace.SetActivityId(enlistment8.TransactionIdentifier);
                                        enlistment8.Phase0Request(abortingHint);
                                    }
                                    else
                                    {
                                        Environment.FailFast(System.Transactions.SR.GetString("InternalError"));
                                    }
                                }
                                goto Label_0444;
                            }
                            finally
                            {
                                HandleTable.FreeHandle(zero);
                            }
                            break;

                        case ShimNotificationType.VoteRequestNotify:
                            break;

                        case ShimNotificationType.PrepareRequestNotify:
                            goto Label_02B0;

                        case ShimNotificationType.CommitRequestNotify:
                            goto Label_031A;

                        case ShimNotificationType.AbortRequestNotify:
                            goto Label_0358;

                        case ShimNotificationType.CommittedNotify:
                            try
                            {
                                OutcomeEnlistment enlistment7 = obj2 as OutcomeEnlistment;
                                if (enlistment7 != null)
                                {
                                    DiagnosticTrace.SetActivityId(enlistment7.TransactionIdentifier);
                                    enlistment7.Committed();
                                }
                                else
                                {
                                    OletxPhase1VolatileEnlistmentContainer container3 = obj2 as OletxPhase1VolatileEnlistmentContainer;
                                    if (container3 != null)
                                    {
                                        DiagnosticTrace.SetActivityId(container3.TransactionIdentifier);
                                        container3.Committed();
                                    }
                                    else
                                    {
                                        Environment.FailFast(System.Transactions.SR.GetString("InternalError"));
                                    }
                                }
                                goto Label_0444;
                            }
                            finally
                            {
                                HandleTable.FreeHandle(zero);
                            }
                            goto Label_0203;

                        case ShimNotificationType.AbortedNotify:
                            goto Label_0203;

                        case ShimNotificationType.InDoubtNotify:
                            goto Label_0251;

                        case ShimNotificationType.EnlistmentTmDownNotify:
                            goto Label_0396;

                        case ShimNotificationType.ResourceManagerTmDownNotify:
                            goto Label_03CD;

                        default:
                            goto Label_0410;
                        }
                        OletxPhase1VolatileEnlistmentContainer container4 = obj2 as OletxPhase1VolatileEnlistmentContainer;
                        if (container4 != null)
                        {
                            DiagnosticTrace.SetActivityId(container4.TransactionIdentifier);
                            container4.VoteRequest();
                        }
                        else
                        {
                            Environment.FailFast(System.Transactions.SR.GetString("InternalError"));
                        }
                    }
                    goto Label_0444;
                    Label_0203 :;
                    try
                    {
                        OutcomeEnlistment enlistment6 = obj2 as OutcomeEnlistment;
                        if (enlistment6 != null)
                        {
                            DiagnosticTrace.SetActivityId(enlistment6.TransactionIdentifier);
                            enlistment6.Aborted();
                        }
                        else
                        {
                            OletxPhase1VolatileEnlistmentContainer container2 = obj2 as OletxPhase1VolatileEnlistmentContainer;
                            if (container2 != null)
                            {
                                DiagnosticTrace.SetActivityId(container2.TransactionIdentifier);
                                container2.Aborted();
                            }
                        }
                        goto Label_0444;
                    }
                    finally
                    {
                        HandleTable.FreeHandle(zero);
                    }
                    Label_0251 :;
                    try
                    {
                        OutcomeEnlistment enlistment5 = obj2 as OutcomeEnlistment;
                        if (enlistment5 != null)
                        {
                            DiagnosticTrace.SetActivityId(enlistment5.TransactionIdentifier);
                            enlistment5.InDoubt();
                        }
                        else
                        {
                            OletxPhase1VolatileEnlistmentContainer container = obj2 as OletxPhase1VolatileEnlistmentContainer;
                            if (container != null)
                            {
                                DiagnosticTrace.SetActivityId(container.TransactionIdentifier);
                                container.InDoubt();
                            }
                            else
                            {
                                Environment.FailFast(System.Transactions.SR.GetString("InternalError"));
                            }
                        }
                        goto Label_0444;
                    }
                    finally
                    {
                        HandleTable.FreeHandle(zero);
                    }
Label_02B0:
                    buffer = new byte[prepareInfoSize];
                    Marshal.Copy(prepareInfo.DangerousGetHandle(), buffer, 0, Convert.ToInt32(prepareInfoSize));
                    bool flag2 = true;
                    try
                    {
                        OletxEnlistment enlistment4 = obj2 as OletxEnlistment;
                        if (enlistment4 != null)
                        {
                            DiagnosticTrace.SetActivityId(enlistment4.TransactionIdentifier);
                            flag2 = enlistment4.PrepareRequest(isSinglePhase, buffer);
                        }
                        else
                        {
                            Environment.FailFast(System.Transactions.SR.GetString("InternalError"));
                        }
                        goto Label_0444;
                    }
                    finally
                    {
                        if (flag2)
                        {
                            HandleTable.FreeHandle(zero);
                        }
                    }
                    Label_031A :;
                    try
                    {
                        OletxEnlistment enlistment3 = obj2 as OletxEnlistment;
                        if (enlistment3 != null)
                        {
                            DiagnosticTrace.SetActivityId(enlistment3.TransactionIdentifier);
                            enlistment3.CommitRequest();
                        }
                        else
                        {
                            Environment.FailFast(System.Transactions.SR.GetString("InternalError"));
                        }
                        goto Label_0444;
                    }
                    finally
                    {
                        HandleTable.FreeHandle(zero);
                    }
                    Label_0358 :;
                    try
                    {
                        OletxEnlistment enlistment2 = obj2 as OletxEnlistment;
                        if (enlistment2 != null)
                        {
                            DiagnosticTrace.SetActivityId(enlistment2.TransactionIdentifier);
                            enlistment2.AbortRequest();
                        }
                        else
                        {
                            Environment.FailFast(System.Transactions.SR.GetString("InternalError"));
                        }
                        goto Label_0444;
                    }
                    finally
                    {
                        HandleTable.FreeHandle(zero);
                    }
                    Label_0396 :;
                    try
                    {
                        OletxEnlistment enlistment = obj2 as OletxEnlistment;
                        if (enlistment != null)
                        {
                            DiagnosticTrace.SetActivityId(enlistment.TransactionIdentifier);
                            enlistment.TMDown();
                        }
                        else
                        {
                            Environment.FailFast(System.Transactions.SR.GetString("InternalError"));
                        }
                        goto Label_0444;
                    }
                    finally
                    {
                        HandleTable.FreeHandle(zero);
                    }
Label_03CD:
                    manager2 = obj2 as OletxResourceManager;
                    try
                    {
                        if (manager2 != null)
                        {
                            manager2.TMDown();
                        }
                        else
                        {
                            OletxInternalResourceManager manager = obj2 as OletxInternalResourceManager;
                            if (manager != null)
                            {
                                manager.TMDown();
                            }
                            else
                            {
                                Environment.FailFast(System.Transactions.SR.GetString("InternalError"));
                            }
                        }
                        goto Label_0444;
                    }
                    finally
                    {
                        HandleTable.FreeHandle(zero);
                    }
Label_0410:
                    Environment.FailFast(System.Transactions.SR.GetString("InternalError"));
                }
                finally
                {
                    if (prepareInfo != null)
                    {
                        prepareInfo.Close();
                    }
                    if (releaseRequired)
                    {
                        releaseRequired  = false;
                        processingTmDown = false;
                        Monitor.Exit(proxyShimFactory);
                    }
                }
Label_0444:
                if (none != ShimNotificationType.None)
                {
                    goto Label_003D;
                }
                flag3 = true;
            }
            finally
            {
                if (releaseRequired)
                {
                    releaseRequired  = false;
                    processingTmDown = false;
                    Monitor.Exit(proxyShimFactory);
                }
                if (!flag3 && (zero != IntPtr.Zero))
                {
                    HandleTable.FreeHandle(zero);
                }
                Thread.EndCriticalRegion();
            }
            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxTransactionManager.ShimNotificationCallback");
            }
        }
コード例 #6
0
ファイル: OletxResourceManager.cs プロジェクト: JianwenSun/cc
        // This routine searches the reenlistPendingList for the specified enlistment and if it finds
        // it, removes it from the list.  An enlistment calls this routine when it is "finishing" because
        // the RM has called EnlistmentDone or it was InDoubt.  But it only calls it if the enlistment does NOT
        // have a WrappedTransactionEnlistmentAsync value, indicating that it is a recovery enlistment.
        internal void RemoveFromReenlistPending( OletxEnlistment enlistment )
        {
            // We lock the reenlistList because we have decided to lock that list when accessing either
            // the reenlistList or the reenlistPendingList.
            lock ( reenlistList )
            {
                // This will do a linear search of the list, but that is what we need to do because
                // the enlistments may change indicies while notifications are outstanding.  Also,
                // this does not throw if the enlistment isn't on the list.
                reenlistPendingList.Remove( enlistment );

                lock ( this )
                {
                    // If we have a ReenlistThread timer and both the reenlistList and the reenlistPendingList
                    // are empty, kick the ReenlistThread now.
                    if ( ( null != this.reenlistThreadTimer ) &&
                        ( 0 == this.reenlistList.Count ) &&
                        ( 0 == this.reenlistPendingList.Count )
                        )
                    {
                        if ( !this.reenlistThreadTimer.Change( 0, Timeout.Infinite ))
                        {
                            throw TransactionException.CreateInvalidOperationException(
                                SR.GetString( SR.TraceSourceLtm ), 
                                SR.GetString(SR.UnexpectedTimerFailure), 
                                null
                                );
                        }
                    }
                }
            }
        }
コード例 #7
0
ファイル: OletxResourceManager.cs プロジェクト: JianwenSun/cc
        internal OletxEnlistment Reenlist(
            int prepareInfoLength,
            byte[] prepareInfo,
            IEnlistmentNotificationInternal enlistmentNotification
            )
        {
            OletxTransactionOutcome outcome = OletxTransactionOutcome.NotKnownYet;
            OletxTransactionStatus xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_NONE;

            // Put the recovery information into a stream.
            MemoryStream stream = new MemoryStream( prepareInfo );

            // First extract the OletxRecoveryInformation from the stream.
            IFormatter formatter = new BinaryFormatter();
            OletxRecoveryInformation oletxRecoveryInformation;
            try
            {
                oletxRecoveryInformation = formatter.Deserialize( stream ) as OletxRecoveryInformation;
            }
            catch (SerializationException se)
            {
                throw new ArgumentException( SR.GetString( SR.InvalidArgument ), "prepareInfo", se );
            }
            
            if ( null == oletxRecoveryInformation )
            {
                throw new ArgumentException( SR.GetString( SR.InvalidArgument ), "prepareInfo" );
            }

            // Verify that the resource manager guid in the recovery info matches that of the calling resource manager.
            byte[] rmGuidArray = new byte[16];
            for ( int i = 0; i < 16; i++ )
            {
                rmGuidArray[i] = oletxRecoveryInformation.proxyRecoveryInformation[i + 16];
            }
            Guid rmGuid = new Guid( rmGuidArray );
            if ( rmGuid != this.resourceManagerIdentifier )
            {
                throw TransactionException.Create( SR.GetString( SR.TraceSourceOletx ), SR.GetString( SR.ResourceManagerIdDoesNotMatchRecoveryInformation ), null );
            }

            // Ask the proxy resource manager to reenlist.
            IResourceManagerShim localResourceManagerShim = null;
            try
            {
                localResourceManagerShim = this.ResourceManagerShim;
                if ( null == localResourceManagerShim )
                {
                    // The TM must be down.  Throw the exception that will get caught below and will cause
                    // the enlistment to start the ReenlistThread.  The TMDown thread will be trying to reestablish
                    // connection with the TM and will start the reenlist thread when it does.
                    throw new COMException( SR.GetString( SR.DtcTransactionManagerUnavailable ), NativeMethods.XACT_E_CONNECTION_DOWN );
                }

                // Only wait for 5 milliseconds.  If the TM doesn't have the outcome now, we will
                // put the enlistment on the reenlistList for later processing.
                localResourceManagerShim.Reenlist(
                    Convert.ToUInt32( oletxRecoveryInformation.proxyRecoveryInformation.Length, CultureInfo.InvariantCulture ),
                    oletxRecoveryInformation.proxyRecoveryInformation,
                    out outcome
                    );

                if ( OletxTransactionOutcome.Committed == outcome )
                {
                    xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_COMMITTED;
                }
                else if ( OletxTransactionOutcome.Aborted == outcome )
                {
                    xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_ABORTED;
                }
                else  // we must not know the outcome yet.
                {
                    xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED;
                    StartReenlistThread();
                }
            }
            catch ( COMException ex )
            {
                if ( NativeMethods.XACT_E_CONNECTION_DOWN == ex.ErrorCode )
                {
                    xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED;
                    this.ResourceManagerShim = null;
                    StartReenlistThread();
                    if ( DiagnosticTrace.Verbose )
                    {
                        ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            ex );
                    }

                }
                else
                {
                    throw;
                }
            }
            finally
            {
                localResourceManagerShim = null;
            }

            // Now create our enlistment to tell the client the outcome.
            OletxEnlistment enlistment = new OletxEnlistment(
                enlistmentNotification,
                xactStatus,
                oletxRecoveryInformation.proxyRecoveryInformation,
                this
                );

            return enlistment;
        }
コード例 #8
0
ファイル: OletxResourceManager.cs プロジェクト: JianwenSun/cc
        internal OletxEnlistment EnlistDurable(
            OletxTransaction oletxTransaction,
            bool canDoSinglePhase,
            IEnlistmentNotificationInternal enlistmentNotification,
            EnlistmentOptions enlistmentOptions
            )
        {
            IResourceManagerShim localResourceManagerShim = null;

            Debug.Assert( null != oletxTransaction, "Argument is null" );
            Debug.Assert( null != enlistmentNotification, "Argument is null" );

            IEnlistmentShim enlistmentShim = null;
            IPhase0EnlistmentShim phase0Shim = null;
            Guid txUow = Guid.Empty;
            IntPtr handlePhase0 = IntPtr.Zero;
            bool phase0EnlistSucceeded = false;
            bool undecidedEnlistmentsIncremented = false;

            // Create our enlistment object.
            OletxEnlistment enlistment = new OletxEnlistment(
                canDoSinglePhase,
                enlistmentNotification,
                oletxTransaction.RealTransaction.TxGuid,
                enlistmentOptions,
                this,
                oletxTransaction
                );

            bool enlistmentSucceeded = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                if ( (enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != 0 )
                {
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try { }
                    finally
                    {                    
                        oletxTransaction.RealTransaction.IncrementUndecidedEnlistments();
                        undecidedEnlistmentsIncremented = true;
                    }
                }

                // This entire sequense needs to be executed before we can go on.
                lock ( enlistment )
                {
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try
                    {
                        // Do the enlistment on the proxy.
                        localResourceManagerShim = this.ResourceManagerShim;
                        if ( null == localResourceManagerShim )
                        {
                            // The TM must be down.  Throw the appropriate exception.
                            throw TransactionManagerCommunicationException.Create( SR.GetString( SR.TraceSourceOletx),  null );
                        }
                        
                        if ( (enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != 0 )
                        {
                            // We need to create an EnlistmentNotifyShim if native threads are not allowed to enter managed code.
                            handlePhase0 = HandleTable.AllocHandle( enlistment );

                            RuntimeHelpers.PrepareConstrainedRegions();
                            try { }
                            finally
                            {
                                oletxTransaction.RealTransaction.TransactionShim.Phase0Enlist(
                                    handlePhase0,
                                    out phase0Shim );
                                phase0EnlistSucceeded = true;
                            }
                            enlistment.Phase0EnlistmentShim = phase0Shim;
                        }

                        enlistment.phase1Handle = HandleTable.AllocHandle( enlistment );
                        localResourceManagerShim.Enlist(
                            oletxTransaction.RealTransaction.TransactionShim,
                            enlistment.phase1Handle,
                            out enlistmentShim );

                        enlistment.EnlistmentShim = enlistmentShim;
                    }
                    catch (COMException comException)
                    {
                        // There is no string mapping for XACT_E_TOOMANY_ENLISTMENTS, so we need to do it here.
                        if ( NativeMethods.XACT_E_TOOMANY_ENLISTMENTS == comException.ErrorCode )
                        {
                            throw TransactionException.Create(
                                SR.GetString( SR.TraceSourceOletx ),
                                SR.GetString( SR.OletxTooManyEnlistments ),
                                comException );
                        }

                        OletxTransactionManager.ProxyException( comException );

                        throw;
                    }
                    finally
                    {
                        if ( enlistment.EnlistmentShim == null )
                        {
                            // If the enlistment shim was never assigned then something blew up.
                            // Perform some cleanup.
                            if ( handlePhase0 != IntPtr.Zero && !phase0EnlistSucceeded )
                            {
                                // Only clean up the phase0 handle if the phase 0 enlistment did not succeed.
                                // This is because the notification processing code expects it to exist.
                                HandleTable.FreeHandle( handlePhase0 );
                            }

                            if ( enlistment.phase1Handle != IntPtr.Zero )
                            {
                                HandleTable.FreeHandle( enlistment.phase1Handle );
                            }

                            // Note this code used to call unenlist however this allows race conditions where
                            // it is unclear if the handlePhase0 should be freed or not.  The notification
                            // thread should get a phase0Request and it will free the Handle at that point.
                        }
                    }
                }

                enlistmentSucceeded = true;
            }
            finally
            {
                if ( !enlistmentSucceeded &&
                    ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != 0) && 
                    undecidedEnlistmentsIncremented )
                {
                    oletxTransaction.RealTransaction.DecrementUndecidedEnlistments();
                }
            }

            return enlistment;
        }
コード例 #9
0
        internal static void ShimNotificationCallback(object state, bool timeout)
        {
            // First we need to get the notification from the shim factory.
            IntPtr enlistmentHandleIntPtr             = IntPtr.Zero;
            ShimNotificationType shimNotificationType = ShimNotificationType.None;
            bool isSinglePhase = false;
            bool abortingHint  = false;

            UInt32          prepareInfoSize   = 0;
            CoTaskMemHandle prepareInfoBuffer = null;

            bool holdingNotificationLock = false;
            bool cleanExit = false;

            IDtcProxyShimFactory localProxyShimFactory = null;

            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx),
                                               "OletxTransactionManager.ShimNotificationCallback"
                                               );
            }

            // This lock doesn't really protect any of our data.  It is here so that if an exception occurs
            // while calling out to the app, we get an escalation to AppDomainUnload.
            Thread.BeginCriticalRegion();
            try
            {
                do
                {
                    // Take a local copy of the proxyShimFactory because if we get an RM TMDown notification,
                    // we will still hold the critical section in that factory, but processing of the TMDown will
                    // cause replacement of the OletxTransactionManager.proxyShimFactory.
                    localProxyShimFactory = OletxTransactionManager.proxyShimFactory;
                    try
                    {
                        Thread.BeginThreadAffinity();
                        RuntimeHelpers.PrepareConstrainedRegions();
                        try
                        {
                            localProxyShimFactory.GetNotification(
                                out enlistmentHandleIntPtr,
                                out shimNotificationType,
                                out isSinglePhase,
                                out abortingHint,
                                out holdingNotificationLock,
                                out prepareInfoSize,
                                out prepareInfoBuffer
                                );
                        }
                        finally
                        {
                            if (holdingNotificationLock)
                            {
                                if ((HandleTable.FindHandle(enlistmentHandleIntPtr)) is OletxInternalResourceManager)
                                {
                                    // In this case we know that the TM has gone down and we need to exchange
                                    // the native lock for a managed lock.
                                    processingTmDown = true;
#pragma warning disable 0618
                                    //@
                                    System.Threading.Monitor.Enter(OletxTransactionManager.proxyShimFactory);
#pragma warning restore 0618
                                }
                                else
                                {
                                    holdingNotificationLock = false;
                                }
                                localProxyShimFactory.ReleaseNotificationLock();
                            }
                            Thread.EndThreadAffinity();
                        }

                        // If a TM down is being processed it is possible that the native lock
                        // has been exchanged for a managed lock.  In that case we need to attempt
                        // to take a lock to hold up processing more events until the TM down
                        // processing is complete.
                        if (processingTmDown)
                        {
                            lock (OletxTransactionManager.proxyShimFactory)
                            {
                                // We don't do any work under this lock just make sure that we
                                // can take it.
                            }
                        }

                        if (ShimNotificationType.None != shimNotificationType)
                        {
                            Object target = HandleTable.FindHandle(enlistmentHandleIntPtr);

                            // Next, based on the notification type, cast the Handle accordingly and make
                            // the appropriate call on the enlistment.
                            switch (shimNotificationType)
                            {
                            case ShimNotificationType.Phase0RequestNotify:
                            {
                                try
                                {
                                    OletxPhase0VolatileEnlistmentContainer ph0VolEnlistContainer = target as OletxPhase0VolatileEnlistmentContainer;
                                    if (null != ph0VolEnlistContainer)
                                    {
                                        DiagnosticTrace.SetActivityId(
                                            ph0VolEnlistContainer.TransactionIdentifier);
                                        //CSDMain 91509 - We now synchronize this call with the AddDependentClone call in RealOleTxTransaction
                                        ph0VolEnlistContainer.Phase0Request(abortingHint);
                                    }
                                    else
                                    {
                                        OletxEnlistment enlistment = target as OletxEnlistment;
                                        if (null != enlistment)
                                        {
                                            DiagnosticTrace.SetActivityId(
                                                enlistment.TransactionIdentifier);
                                            enlistment.Phase0Request(abortingHint);
                                        }
                                        else
                                        {
                                            Environment.FailFast(SR.GetString(SR.InternalError));
                                        }
                                    }
                                }
                                finally
                                {
                                    // We aren't going to get any more notifications on this.
                                    HandleTable.FreeHandle(enlistmentHandleIntPtr);
                                }
                                break;
                            }

                            case ShimNotificationType.VoteRequestNotify:
                            {
                                OletxPhase1VolatileEnlistmentContainer ph1VolEnlistContainer = target as OletxPhase1VolatileEnlistmentContainer;
                                if (null != ph1VolEnlistContainer)
                                {
                                    DiagnosticTrace.SetActivityId(
                                        ph1VolEnlistContainer.TransactionIdentifier);
                                    ph1VolEnlistContainer.VoteRequest();
                                }
                                else
                                {
                                    Environment.FailFast(SR.GetString(SR.InternalError));
                                }

                                break;
                            }

                            case ShimNotificationType.CommittedNotify:
                            {
                                try
                                {
                                    OutcomeEnlistment outcomeEnlistment = target as OutcomeEnlistment;
                                    if (null != outcomeEnlistment)
                                    {
                                        DiagnosticTrace.SetActivityId(
                                            outcomeEnlistment.TransactionIdentifier);
                                        outcomeEnlistment.Committed();
                                    }
                                    else
                                    {
                                        OletxPhase1VolatileEnlistmentContainer ph1VolEnlistContainer = target as OletxPhase1VolatileEnlistmentContainer;
                                        if (null != ph1VolEnlistContainer)
                                        {
                                            DiagnosticTrace.SetActivityId(
                                                ph1VolEnlistContainer.TransactionIdentifier);
                                            ph1VolEnlistContainer.Committed();
                                        }
                                        else
                                        {
                                            Environment.FailFast(SR.GetString(SR.InternalError));
                                        }
                                    }
                                }
                                finally
                                {
                                    // We aren't going to get any more notifications on this.
                                    HandleTable.FreeHandle(enlistmentHandleIntPtr);
                                }
                                break;
                            }

                            case ShimNotificationType.AbortedNotify:
                            {
                                try
                                {
                                    OutcomeEnlistment outcomeEnlistment = target as OutcomeEnlistment;
                                    if (null != outcomeEnlistment)
                                    {
                                        DiagnosticTrace.SetActivityId(
                                            outcomeEnlistment.TransactionIdentifier);
                                        outcomeEnlistment.Aborted();
                                    }
                                    else
                                    {
                                        OletxPhase1VolatileEnlistmentContainer ph1VolEnlistContainer = target as OletxPhase1VolatileEnlistmentContainer;
                                        if (null != ph1VolEnlistContainer)
                                        {
                                            DiagnosticTrace.SetActivityId(
                                                ph1VolEnlistContainer.TransactionIdentifier);
                                            ph1VolEnlistContainer.Aborted();
                                        }
                                        // else
                                        // Voters may receive notifications even
                                        // in cases where they therwise respond
                                        // negatively to the vote request.  It is
                                        // also not guaranteed that we will get a
                                        // notification if we do respond negatively.
                                        // The only safe thing to do is to free the
                                        // Handle when we abort the transaction
                                        // with a voter.  These two things together
                                        // mean that we cannot guarantee that this
                                        // Handle will be alive when we get this
                                        // notification.
                                    }
                                }
                                finally
                                {
                                    // We aren't going to get any more notifications on this.
                                    HandleTable.FreeHandle(enlistmentHandleIntPtr);
                                }
                                break;
                            }

                            case ShimNotificationType.InDoubtNotify:
                            {
                                try
                                {
                                    OutcomeEnlistment outcomeEnlistment = target as OutcomeEnlistment;
                                    if (null != outcomeEnlistment)
                                    {
                                        DiagnosticTrace.SetActivityId(
                                            outcomeEnlistment.TransactionIdentifier);
                                        outcomeEnlistment.InDoubt();
                                    }
                                    else
                                    {
                                        OletxPhase1VolatileEnlistmentContainer ph1VolEnlistContainer = target as OletxPhase1VolatileEnlistmentContainer;
                                        if (null != ph1VolEnlistContainer)
                                        {
                                            DiagnosticTrace.SetActivityId(
                                                ph1VolEnlistContainer.TransactionIdentifier);
                                            ph1VolEnlistContainer.InDoubt();
                                        }
                                        else
                                        {
                                            Environment.FailFast(SR.GetString(SR.InternalError));
                                        }
                                    }
                                }
                                finally
                                {
                                    // We aren't going to get any more notifications on this.
                                    HandleTable.FreeHandle(enlistmentHandleIntPtr);
                                }
                                break;
                            }

                            case ShimNotificationType.PrepareRequestNotify:
                            {
                                byte[] prepareInfo = new byte[prepareInfoSize];
                                Marshal.Copy(prepareInfoBuffer.DangerousGetHandle(), prepareInfo, 0, Convert.ToInt32(prepareInfoSize));
                                bool enlistmentDone = true;

                                try
                                {
                                    OletxEnlistment enlistment = target as OletxEnlistment;
                                    if (null != enlistment)
                                    {
                                        DiagnosticTrace.SetActivityId(
                                            enlistment.TransactionIdentifier);
                                        enlistmentDone = enlistment.PrepareRequest(
                                            isSinglePhase,
                                            prepareInfo
                                            );
                                    }
                                    else
                                    {
                                        Environment.FailFast(SR.GetString(SR.InternalError));
                                    }
                                }
                                finally
                                {
                                    if (enlistmentDone)
                                    {
                                        HandleTable.FreeHandle(enlistmentHandleIntPtr);
                                    }
                                }

                                break;
                            }

                            case ShimNotificationType.CommitRequestNotify:
                            {
                                try
                                {
                                    OletxEnlistment enlistment = target as OletxEnlistment;
                                    if (null != enlistment)
                                    {
                                        DiagnosticTrace.SetActivityId(
                                            enlistment.TransactionIdentifier);
                                        enlistment.CommitRequest();
                                    }
                                    else
                                    {
                                        Environment.FailFast(SR.GetString(SR.InternalError));
                                    }
                                }
                                finally
                                {
                                    // We aren't going to get any more notifications on this.
                                    HandleTable.FreeHandle(enlistmentHandleIntPtr);
                                }

                                break;
                            }

                            case ShimNotificationType.AbortRequestNotify:
                            {
                                try
                                {
                                    OletxEnlistment enlistment = target as OletxEnlistment;
                                    if (null != enlistment)
                                    {
                                        DiagnosticTrace.SetActivityId(
                                            enlistment.TransactionIdentifier);
                                        enlistment.AbortRequest();
                                    }
                                    else
                                    {
                                        Environment.FailFast(SR.GetString(SR.InternalError));
                                    }
                                }
                                finally
                                {
                                    // We aren't going to get any more notifications on this.
                                    HandleTable.FreeHandle(enlistmentHandleIntPtr);
                                }

                                break;
                            }

                            case ShimNotificationType.EnlistmentTmDownNotify:
                            {
                                try
                                {
                                    OletxEnlistment enlistment = target as OletxEnlistment;
                                    if (null != enlistment)
                                    {
                                        DiagnosticTrace.SetActivityId(
                                            enlistment.TransactionIdentifier);
                                        enlistment.TMDown();
                                    }
                                    else
                                    {
                                        Environment.FailFast(SR.GetString(SR.InternalError));
                                    }
                                }
                                finally
                                {
                                    // We aren't going to get any more notifications on this.
                                    HandleTable.FreeHandle(enlistmentHandleIntPtr);
                                }

                                break;
                            }


                            case ShimNotificationType.ResourceManagerTmDownNotify:
                            {
                                OletxResourceManager resourceManager = target as OletxResourceManager;
                                try
                                {
                                    if (null != resourceManager)
                                    {
                                        resourceManager.TMDown();
                                    }
                                    else
                                    {
                                        OletxInternalResourceManager internalResourceManager = target as OletxInternalResourceManager;
                                        if (null != internalResourceManager)
                                        {
                                            internalResourceManager.TMDown();
                                        }
                                        else
                                        {
                                            Environment.FailFast(SR.GetString(SR.InternalError));
                                        }
                                    }
                                }
                                finally
                                {
                                    HandleTable.FreeHandle(enlistmentHandleIntPtr);
                                }

                                // Note that we don't free the gchandle on the OletxResourceManager.  These objects
                                // are not going to go away.
                                break;
                            }

                            default:
                            {
                                Environment.FailFast(SR.GetString(SR.InternalError));
                                break;
                            }
                            }
                        }
                    }
                    finally
                    {
                        if (null != prepareInfoBuffer)
                        {
                            prepareInfoBuffer.Close();
                        }

                        if (holdingNotificationLock)
                        {
                            holdingNotificationLock = false;
                            processingTmDown        = false;
                            System.Threading.Monitor.Exit(OletxTransactionManager.proxyShimFactory);
                        }
                    }
                }while (ShimNotificationType.None != shimNotificationType);

                cleanExit = true;
            }
            finally
            {
                if (holdingNotificationLock)
                {
                    holdingNotificationLock = false;
                    processingTmDown        = false;
                    System.Threading.Monitor.Exit(OletxTransactionManager.proxyShimFactory);
                }

                if (!cleanExit && enlistmentHandleIntPtr != IntPtr.Zero)
                {
                    HandleTable.FreeHandle(enlistmentHandleIntPtr);
                }

                Thread.EndCriticalRegion();
            }

            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx),
                                              "OletxTransactionManager.ShimNotificationCallback"
                                              );
            }
        }
コード例 #10
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);
        }
コード例 #11
0
        internal void ReenlistThread(object state)
        {
            int                  count               = 0;
            bool                 flag                = false;
            OletxEnlistment      enlistment          = null;
            IResourceManagerShim resourceManagerShim = null;
            Timer                reenlistThreadTimer = null;
            bool                 flag2               = false;
            OletxResourceManager manager             = (OletxResourceManager)state;

            try
            {
                if (DiagnosticTrace.Information)
                {
                    MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxResourceManager.ReenlistThread");
                }
                lock (manager)
                {
                    resourceManagerShim         = manager.ResourceManagerShim;
                    reenlistThreadTimer         = manager.reenlistThreadTimer;
                    manager.reenlistThreadTimer = null;
                    manager.reenlistThread      = Thread.CurrentThread;
                }
                if (resourceManagerShim != null)
                {
                    lock (manager.reenlistList)
                    {
                        count = manager.reenlistList.Count;
                    }
                    flag = false;
                    while ((!flag && (count > 0)) && (resourceManagerShim != null))
                    {
                        lock (manager.reenlistList)
                        {
                            enlistment = null;
                            count--;
                            if (manager.reenlistList.Count == 0)
                            {
                                flag = true;
                            }
                            else
                            {
                                enlistment = manager.reenlistList[0] as OletxEnlistment;
                                if (enlistment == null)
                                {
                                    if (DiagnosticTrace.Critical)
                                    {
                                        InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                                    }
                                    throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("InternalError"), null);
                                }
                                manager.reenlistList.RemoveAt(0);
                                object obj7 = enlistment;
                                lock (obj7)
                                {
                                    if (OletxEnlistment.OletxEnlistmentState.Done == enlistment.State)
                                    {
                                        enlistment = null;
                                    }
                                    else if (OletxEnlistment.OletxEnlistmentState.Prepared != enlistment.State)
                                    {
                                        manager.reenlistList.Add(enlistment);
                                        enlistment = null;
                                    }
                                }
                            }
                        }
                        if (enlistment != null)
                        {
                            OletxTransactionOutcome notKnownYet = OletxTransactionOutcome.NotKnownYet;
                            try
                            {
                                if (enlistment.ProxyPrepareInfoByteArray == null)
                                {
                                    if (DiagnosticTrace.Critical)
                                    {
                                        InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                                    }
                                    throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("InternalError"), null);
                                }
                                resourceManagerShim.Reenlist((uint)enlistment.ProxyPrepareInfoByteArray.Length, enlistment.ProxyPrepareInfoByteArray, out notKnownYet);
                                if (notKnownYet == OletxTransactionOutcome.NotKnownYet)
                                {
                                    object obj5 = enlistment;
                                    lock (obj5)
                                    {
                                        if (OletxEnlistment.OletxEnlistmentState.Done == enlistment.State)
                                        {
                                            enlistment = null;
                                        }
                                        else
                                        {
                                            lock (manager.reenlistList)
                                            {
                                                manager.reenlistList.Add(enlistment);
                                                enlistment = null;
                                            }
                                        }
                                    }
                                }
                            }
                            catch (COMException exception)
                            {
                                if (System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN != exception.ErrorCode)
                                {
                                    throw;
                                }
                                if (DiagnosticTrace.Verbose)
                                {
                                    ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
                                }
                                if (System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN == exception.ErrorCode)
                                {
                                    manager.ResourceManagerShim = null;
                                    resourceManagerShim         = manager.ResourceManagerShim;
                                }
                            }
                            if (enlistment != null)
                            {
                                object obj3 = enlistment;
                                lock (obj3)
                                {
                                    if (OletxEnlistment.OletxEnlistmentState.Done != enlistment.State)
                                    {
                                        lock (manager.reenlistList)
                                        {
                                            manager.reenlistPendingList.Add(enlistment);
                                        }
                                        if (OletxTransactionOutcome.Committed != notKnownYet)
                                        {
                                            if (OletxTransactionOutcome.Aborted != notKnownYet)
                                            {
                                                if (DiagnosticTrace.Critical)
                                                {
                                                    InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                                                }
                                                throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("InternalError"), null);
                                            }
                                            enlistment.State = OletxEnlistment.OletxEnlistmentState.Aborting;
                                            if (DiagnosticTrace.Verbose)
                                            {
                                                EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), enlistment.EnlistmentTraceId, NotificationCall.Rollback);
                                            }
                                            enlistment.EnlistmentNotification.Rollback(enlistment);
                                        }
                                        else
                                        {
                                            enlistment.State = OletxEnlistment.OletxEnlistmentState.Committing;
                                            if (DiagnosticTrace.Verbose)
                                            {
                                                EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), enlistment.EnlistmentTraceId, NotificationCall.Commit);
                                            }
                                            enlistment.EnlistmentNotification.Commit(enlistment);
                                        }
                                    }
                                    else
                                    {
                                        enlistment = null;
                                    }
                                    continue;
                                }
                            }
                        }
                    }
                }
                resourceManagerShim = null;
                lock (manager.reenlistList)
                {
                    lock (manager)
                    {
                        count = manager.reenlistList.Count;
                        if ((0 >= count) && (0 >= manager.reenlistPendingList.Count))
                        {
                            if (!manager.CallProxyReenlistComplete())
                            {
                                manager.reenlistThreadTimer = reenlistThreadTimer;
                                if (!reenlistThreadTimer.Change(0x2710, -1))
                                {
                                    throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), System.Transactions.SR.GetString("UnexpectedTimerFailure"), null);
                                }
                            }
                            else
                            {
                                flag2 = true;
                            }
                        }
                        else
                        {
                            manager.reenlistThreadTimer = reenlistThreadTimer;
                            if (!reenlistThreadTimer.Change(0x2710, -1))
                            {
                                throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), System.Transactions.SR.GetString("UnexpectedTimerFailure"), null);
                            }
                        }
                        manager.reenlistThread = null;
                    }
                    if (DiagnosticTrace.Information)
                    {
                        MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxResourceManager.ReenlistThread");
                    }
                }
            }
            finally
            {
                resourceManagerShim = null;
                if (flag2 && (reenlistThreadTimer != null))
                {
                    reenlistThreadTimer.Dispose();
                }
            }
        }
 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;
 }
 internal void RemoveFromReenlistPending(OletxEnlistment enlistment)
 {
     lock (this.reenlistList)
     {
         this.reenlistPendingList.Remove(enlistment);
         lock (this)
         {
             if (((this.reenlistThreadTimer != null) && (this.reenlistList.Count == 0)) && ((this.reenlistPendingList.Count == 0) && !this.reenlistThreadTimer.Change(0, -1)))
             {
                 throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), System.Transactions.SR.GetString("UnexpectedTimerFailure"), null);
             }
         }
     }
 }