internal void VoteRequest() { OletxVolatileEnlistment enlistment = null; int count = 0; bool flag = false; lock (this) { if (DiagnosticTrace.Verbose) { string methodName = "OletxPhase1VolatileEnlistmentContainer.VoteRequest"; MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), methodName); } base.phase = 1; if (0 < base.incompleteDependentClones) { flag = true; base.outstandingNotifications = 1; } else { base.outstandingNotifications = base.enlistmentList.Count; count = base.enlistmentList.Count; if (count == 0) { base.outstandingNotifications = 1; } } base.realOletxTransaction.TooLateForEnlistments = true; } if (flag) { this.DecrementOutstandingNotifications(false); } else if (count == 0) { this.DecrementOutstandingNotifications(true); } else { for (int i = 0; i < count; i++) { enlistment = base.enlistmentList[i] as OletxVolatileEnlistment; if (enlistment == null) { if (DiagnosticTrace.Critical) { InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), ""); } throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError")); } enlistment.Prepare(this); } } if (DiagnosticTrace.Verbose) { string str = "OletxPhase1VolatileEnlistmentContainer.VoteRequest"; MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), str); } }
internal void AddEnlistment(OletxVolatileEnlistment enlistment) { lock (this) { if (-1 != base.phase) { throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TooLate"), null); } base.enlistmentList.Add(enlistment); } }
internal void AddEnlistment(OletxVolatileEnlistment enlistment) { lock (this) { if (-1 != base.phase) { throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TooLate"), null); } base.enlistmentList.Add(enlistment); } }
internal override void Committed() { OletxVolatileEnlistment enlistment = null; int count = 0; lock (this) { base.phase = 2; count = base.enlistmentList.Count; } for (int i = 0; i < count; i++) { enlistment = base.enlistmentList[i] as OletxVolatileEnlistment; if (enlistment == null) { if (DiagnosticTrace.Critical) { InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), ""); } throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError")); } enlistment.Commit(); } }
internal void Phase0Request(bool abortHint) { OletxVolatileEnlistment enlistment = null; int count = 0; OletxCommittableTransaction committableTransaction = null; bool flag = false; lock (this) { if (DiagnosticTrace.Verbose) { string methodName = "OletxPhase0VolatileEnlistmentContainer.Phase0Request, abortHint = " + abortHint.ToString(CultureInfo.CurrentCulture) + ", phase = " + this.phase.ToString(CultureInfo.CurrentCulture); MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), methodName); } this.aborting = abortHint; committableTransaction = base.realOletxTransaction.committableTransaction; if ((committableTransaction != null) && !committableTransaction.CommitCalled) { flag = true; this.aborting = true; } if ((2 == base.phase) || (-1 == base.phase)) { if (-1 == base.phase) { base.phase = 0; } if ((this.aborting || this.tmWentDown) || (flag || (2 == base.phase))) { if (this.phase0EnlistmentShim != null) { try { this.phase0EnlistmentShim.Phase0Done(false); base.alreadyVoted = true; } catch (COMException exception) { if (DiagnosticTrace.Verbose) { ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception); } } } return; } base.outstandingNotifications = base.enlistmentList.Count; count = base.enlistmentList.Count; if (count == 0) { base.outstandingNotifications = 1; } } else { if (DiagnosticTrace.Critical) { InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxPhase0VolatileEnlistmentContainer.Phase0Request, phase != -1"); } throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError")); } } if (count == 0) { this.DecrementOutstandingNotifications(true); } else { for (int i = 0; i < count; i++) { enlistment = base.enlistmentList[i] as OletxVolatileEnlistment; if (enlistment == null) { if (DiagnosticTrace.Critical) { InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), ""); } throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError")); } enlistment.Prepare(this); } } if (DiagnosticTrace.Verbose) { string str = "OletxPhase0VolatileEnlistmentContainer.Phase0Request, abortHint = " + abortHint.ToString(CultureInfo.CurrentCulture); MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), str); } }
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; }
// Returns true if this container is enlisted for Phase 0. internal void AddEnlistment( OletxVolatileEnlistment enlistment ) { Debug.Assert( null != enlistment, "Argument is null" ); lock ( this ) { if ( -1 != phase ) { throw TransactionException.Create( SR.GetString( SR.TraceSourceOletx ), SR.GetString( SR.TooLate ), null ); } enlistmentList.Add( enlistment ); } }
internal IPromotedEnlistment CommonEnlistVolatile( IEnlistmentNotificationInternal enlistmentNotification, EnlistmentOptions enlistmentOptions, OletxTransaction oletxTransaction ) { OletxVolatileEnlistment enlistment = null; bool needVoterEnlistment = false; bool needPhase0Enlistment = false; OletxPhase0VolatileEnlistmentContainer localPhase0VolatileContainer = null; OletxPhase1VolatileEnlistmentContainer localPhase1VolatileContainer = null; IntPtr phase0Handle = IntPtr.Zero; IVoterBallotShim voterShim = null; IPhase0EnlistmentShim phase0Shim = null; bool enlistmentSucceeded = false; // Yes, we are talking to the proxy while holding the lock on the RealOletxTransaction. // If we don't then things get real sticky with other threads allocating containers. // We only do this the first time we get a depenent clone of a given type (delay vs. non-delay). // After that, we don't create a new container, except for Phase0 if we need to create one // for a second wave. RuntimeHelpers.PrepareConstrainedRegions(); try { lock ( this ) { enlistment = new OletxVolatileEnlistment( enlistmentNotification, enlistmentOptions, oletxTransaction ); if ( (enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != 0 ) { if ( null == this.phase0EnlistVolatilementContainerList ) { // Not using a MemoryBarrier because all access to this member variable is done when holding // a lock on the object. this.phase0EnlistVolatilementContainerList = new ArrayList(1); } // We may have failed the proxy enlistment for the first container, but we would have // allocated the list. That is why we have this check here. if ( 0 == this.phase0EnlistVolatilementContainerList.Count ) { localPhase0VolatileContainer = new OletxPhase0VolatileEnlistmentContainer( this ); needPhase0Enlistment = true; } else { localPhase0VolatileContainer = this.phase0EnlistVolatilementContainerList[this.phase0EnlistVolatilementContainerList.Count - 1] as OletxPhase0VolatileEnlistmentContainer; if ( ! localPhase0VolatileContainer.NewEnlistmentsAllowed ) { localPhase0VolatileContainer = new OletxPhase0VolatileEnlistmentContainer( this ); needPhase0Enlistment = true; } else { needPhase0Enlistment = false; } } if ( needPhase0Enlistment ) { // We need to create a VoterNotifyShim if native threads are not allowed to enter managed code. phase0Handle = HandleTable.AllocHandle( localPhase0VolatileContainer ); } } else // not EDPR = TRUE - may need a voter... { if ( null == this.phase1EnlistVolatilementContainer ) { needVoterEnlistment = true; localPhase1VolatileContainer = new OletxPhase1VolatileEnlistmentContainer( this ); // We need to create a VoterNotifyShim. localPhase1VolatileContainer.voterHandle = HandleTable.AllocHandle( localPhase1VolatileContainer ); } else { needVoterEnlistment = false; localPhase1VolatileContainer = this.phase1EnlistVolatilementContainer; } } try { // If enlistDuringPrepareRequired is true, we need to ask the proxy to create a Phase0 enlistment. if ( needPhase0Enlistment ) { lock ( localPhase0VolatileContainer ) { transactionShim.Phase0Enlist( phase0Handle, out phase0Shim ); localPhase0VolatileContainer.Phase0EnlistmentShim = phase0Shim; } } if ( needVoterEnlistment ) { this.transactionShim.CreateVoter( localPhase1VolatileContainer.voterHandle, out voterShim ); enlistmentSucceeded = true; localPhase1VolatileContainer.VoterBallotShim = voterShim; } if ( (enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != 0 ) { localPhase0VolatileContainer.AddEnlistment( enlistment ); if ( needPhase0Enlistment ) { this.phase0EnlistVolatilementContainerList.Add( localPhase0VolatileContainer ); } } else { localPhase1VolatileContainer.AddEnlistment( enlistment ); if ( needVoterEnlistment ) { Debug.Assert( ( null == this.phase1EnlistVolatilementContainer ), "RealOletxTransaction.CommonEnlistVolatile - phase1VolContainer not null when expected." ); this.phase1EnlistVolatilementContainer = localPhase1VolatileContainer; } } } catch (COMException comException) { OletxTransactionManager.ProxyException( comException ); throw; } } } finally { if ( phase0Handle != IntPtr.Zero && localPhase0VolatileContainer.Phase0EnlistmentShim == null ) { HandleTable.FreeHandle( phase0Handle ); } if ( !enlistmentSucceeded && null != localPhase1VolatileContainer && localPhase1VolatileContainer.voterHandle != IntPtr.Zero && needVoterEnlistment ) { HandleTable.FreeHandle( localPhase1VolatileContainer.voterHandle ); } } return enlistment; }
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); }