// 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 (ReenlistThreadTimer != null && ReenlistList.Count == 0 && ReenlistPendingList.Count == 0)
                {
                    if (!ReenlistThreadTimer.Change(0, Timeout.Infinite))
                    {
                        throw TransactionException.CreateInvalidOperationException(
                                  TraceSourceType.TraceSourceOleTx,
                                  SR.UnexpectedTimerFailure,
                                  null);
                    }
                }
            }
        }
    }
Beispiel #2
0
 internal EnlistmentNotifyShim(DtcProxyShimFactory shimFactory, OletxEnlistment enlistmentIdentifier)
     : base(shimFactory, enlistmentIdentifier)
 {
     _ignoreSpuriousProxyNotifications = false;
 }