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(); }
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(); }
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(); }
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(); }
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(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 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); }
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); }