예제 #1
0
        public void Free()
        {
            if (!this.providerObjectSet)
            {
                throw Fx.Exception.AsError(new InvalidOperationException(SRCore.HandleFreedBeforeInitialized));
            }

            if (!IsValid)
            {
                return;
            }

            List <InstanceHandleReference> handlesPendingResolution = null;
            WaitForEventsAsyncResult       resultToCancel           = null;

            try
            {
                bool needNotification = false;
                InstancePersistenceContext currentContext = null;

                lock (ThisLock)
                {
                    if (!IsValid)
                    {
                        return;
                    }
                    IsValid = false;

                    IEnumerable <XName> eventsToUnbind = null;
                    if (this.pendingOwnerEvents != null && this.pendingOwnerEvents.Count > 0)
                    {
                        eventsToUnbind = this.pendingOwnerEvents.Select(persistenceEvent => persistenceEvent.Name);
                    }
                    if (this.boundOwnerEvents != null && this.boundOwnerEvents.Count > 0)
                    {
                        eventsToUnbind = eventsToUnbind == null ? this.boundOwnerEvents : eventsToUnbind.Concat(this.boundOwnerEvents);
                    }
                    if (eventsToUnbind != null)
                    {
                        Fx.Assert(Owner != null, "How do we have owner events without an owner.");
                        Store.RemoveHandleFromEvents(this, eventsToUnbind, Owner);
                    }
                    if (this.waitResult != null)
                    {
                        resultToCancel  = this.waitResult;
                        this.waitResult = null;
                    }

                    if (OperationPending)
                    {
                        if (AcquirePending != null)
                        {
                            // If in this stage, we need to short-circuit the pending transaction.
                            Fx.Assert(CurrentTransactionalAsyncResult != null, "Should have a pending transaction if we are waiting for it.");
                            CurrentTransactionalAsyncResult.WaitForHostTransaction.Set();
                            this.needFreedNotification = true;
                        }
                        else
                        {
                            // Here, just notify the currently executing command.
                            Fx.Assert(CurrentExecutionContext != null, "Must have either this or AcquirePending set.");
                            currentContext = CurrentExecutionContext;
                        }
                    }
                    else
                    {
                        needNotification = true;

                        if (this.inProgressBind != null)
                        {
                            Owner.CancelBind(ref this.inProgressBind, ref handlesPendingResolution);
                        }
                        else if (Version != -1)
                        {
                            // This means the handle was successfully bound in the past.  Need to remove it from the table of handles.
                            Owner.Unbind(this);
                        }
                    }
                }

                if (currentContext != null)
                {
                    // Need to do this not in a lock.
                    currentContext.NotifyHandleFree();

                    lock (ThisLock)
                    {
                        if (OperationPending)
                        {
                            this.needFreedNotification = true;

                            // Cancel any pending lock reclaim here.
                            if (this.inProgressBind != null)
                            {
                                Fx.Assert(Owner != null, "Must be bound to owner to have an inProgressBind for the lock in CancelReclaim.");

                                // Null reason defaults to OperationCanceledException.  (Defer creating it since this might not be a
                                // reclaim attempt, but we don't know until we take the HandlesLock.)
                                Owner.FaultBind(ref this.inProgressBind, ref handlesPendingResolution, null);
                            }
                        }
                        else
                        {
                            needNotification = true;
                        }
                    }
                }

                if (needNotification)
                {
                    Store.FreeInstanceHandle(this, ProviderObject);
                }
            }
            finally
            {
                if (resultToCancel != null)
                {
                    resultToCancel.Canceled();
                }

                InstanceOwner.ResolveHandles(handlesPendingResolution);
            }
        }
예제 #2
0
 public void Free()
 {
     if (!this.providerObjectSet)
     {
         throw Fx.Exception.AsError(new InvalidOperationException(SRCore.HandleFreedBeforeInitialized));
     }
     if (this.IsValid)
     {
         List <InstanceHandleReference> handlesPendingResolution = null;
         WaitForEventsAsyncResult       waitResult = null;
         try
         {
             bool flag = false;
             InstancePersistenceContext currentExecutionContext = null;
             lock (this.ThisLock)
             {
                 if (!this.IsValid)
                 {
                     return;
                 }
                 this.IsValid = false;
                 IEnumerable <XName> first = null;
                 if ((this.pendingOwnerEvents != null) && (this.pendingOwnerEvents.Count > 0))
                 {
                     first = from persistenceEvent in this.pendingOwnerEvents select persistenceEvent.Name;
                 }
                 if ((this.boundOwnerEvents != null) && (this.boundOwnerEvents.Count > 0))
                 {
                     first = (first == null) ? this.boundOwnerEvents : first.Concat <XName>(this.boundOwnerEvents);
                 }
                 if (first != null)
                 {
                     this.Store.RemoveHandleFromEvents(this, first, this.Owner);
                 }
                 if (this.waitResult != null)
                 {
                     waitResult      = this.waitResult;
                     this.waitResult = null;
                 }
                 if (this.OperationPending)
                 {
                     if (this.AcquirePending != null)
                     {
                         this.CurrentTransactionalAsyncResult.WaitForHostTransaction.Set();
                         this.needFreedNotification = true;
                     }
                     else
                     {
                         currentExecutionContext = this.CurrentExecutionContext;
                     }
                 }
                 else
                 {
                     flag = true;
                     if (this.inProgressBind != null)
                     {
                         this.Owner.CancelBind(ref this.inProgressBind, ref handlesPendingResolution);
                     }
                     else if (this.Version != -1L)
                     {
                         this.Owner.Unbind(this);
                     }
                 }
             }
             if (currentExecutionContext != null)
             {
                 currentExecutionContext.NotifyHandleFree();
                 lock (this.ThisLock)
                 {
                     if (this.OperationPending)
                     {
                         this.needFreedNotification = true;
                         if (this.inProgressBind != null)
                         {
                             this.Owner.FaultBind(ref this.inProgressBind, ref handlesPendingResolution, null);
                         }
                     }
                     else
                     {
                         flag = true;
                     }
                 }
             }
             if (flag)
             {
                 this.Store.FreeInstanceHandle(this, this.ProviderObject);
             }
         }
         finally
         {
             if (waitResult != null)
             {
                 waitResult.Canceled();
             }
             InstanceOwner.ResolveHandles(handlesPendingResolution);
         }
     }
 }