コード例 #1
0
        protected void ResetEvent(InstancePersistenceEvent persistenceEvent, InstanceOwner owner)
        {
            if (persistenceEvent == null)
            {
                throw Fx.Exception.ArgumentNull(nameof(persistenceEvent));
            }
            if (owner == null)
            {
                throw Fx.Exception.ArgumentNull(nameof(owner));
            }

            lock (ThisLock)
            {
                if (!_owners.TryGetValue(owner.InstanceOwnerId, out WeakReference ownerReference) || !object.ReferenceEquals(ownerReference.Target, owner))
                {
                    throw Fx.Exception.Argument(nameof(owner), SR.OwnerBelongsToWrongStore);
                }

                if (!owner.Events.TryGetValue(persistenceEvent.Name, out InstanceNormalEvent normal))
                {
                    return;
                }

                if (normal.IsSignaled)
                {
                    normal.IsSignaled = false;
                    if (normal.BoundHandles.Count == 0 && normal.PendingHandles.Count == 0)
                    {
                        owner.Events.Remove(persistenceEvent.Name);
                    }
                }
            }
        }
コード例 #2
0
 internal void Signaled(InstancePersistenceEvent persistenceEvent)
 {
     Signaled(new List <InstancePersistenceEvent>(1)
     {
         persistenceEvent
     });
 }
コード例 #3
0
 // Must be called under ThisLock.  Doesn't validate the InstanceOwner.
 private InstanceNormalEvent GetOwnerEventHelper(InstancePersistenceEvent persistenceEvent, InstanceOwner owner)
 {
     if (!owner.Events.TryGetValue(persistenceEvent.Name, out InstanceNormalEvent normal))
     {
         normal = new InstanceNormalEvent(persistenceEvent);
         owner.Events.Add(persistenceEvent.Name, normal);
     }
     return(normal);
 }
コード例 #4
0
        internal void PendHandleToEvent(InstanceHandle handle, InstancePersistenceEvent persistenceEvent, InstanceOwner owner)
        {
            lock (ThisLock)
            {
                Fx.Assert(_owners.ContainsKey(owner.InstanceOwnerId), "InstanceHandle called PendHandleToEvent on wrong InstanceStore!!");
                Fx.Assert(object.ReferenceEquals(_owners[owner.InstanceOwnerId].Target, owner), "How did multiple of the same owner become simultaneously active?");

                InstanceNormalEvent normal = GetOwnerEventHelper(persistenceEvent, owner);
                Fx.Assert(!normal.PendingHandles.Contains(handle), "Should not have already pended the handle.");
                Fx.Assert(!normal.BoundHandles.Contains(handle), "Should not be able to pend an already-bound handle.");
                normal.PendingHandles.Add(handle);
            }
        }
コード例 #5
0
        internal InstancePersistenceEvent AddHandleToEvent(InstanceHandle handle, InstancePersistenceEvent persistenceEvent, InstanceOwner owner)
        {
            lock (ThisLock)
            {
                Fx.Assert(_owners.ContainsKey(owner.InstanceOwnerId), "InstanceHandle called AddHandleToEvent on wrong InstanceStore!!");
                Fx.Assert(object.ReferenceEquals(_owners[owner.InstanceOwnerId].Target, owner), "How did multiple instances of the same owner become simultaneously active?");

                InstanceNormalEvent normal = GetOwnerEventHelper(persistenceEvent, owner);
                Fx.Assert(normal.PendingHandles.Contains(handle), "Should have already pended the handle.");
                Fx.Assert(!normal.BoundHandles.Contains(handle), "Should not be able to add a handle to an event twice.");
                normal.BoundHandles.Add(handle);
                normal.PendingHandles.Remove(handle);
                return(normal.IsSignaled ? normal : null);
            }
        }
コード例 #6
0
        internal void EventReady(InstancePersistenceEvent persistenceEvent)
        {
            WaitForEventsAsyncResult resultToComplete = null;

            lock (ThisLock)
            {
                if (_waitResult != null)
                {
                    resultToComplete = _waitResult;
                    _waitResult      = null;
                }
            }

            if (resultToComplete != null)
            {
                resultToComplete.Signaled(persistenceEvent);
            }
        }
コード例 #7
0
        protected void SignalEvent(InstancePersistenceEvent persistenceEvent, InstanceOwner owner)
        {
            if (persistenceEvent == null)
            {
                throw Fx.Exception.ArgumentNull("persistenceEvent");
            }
            if (owner == null)
            {
                throw Fx.Exception.ArgumentNull("owner");
            }

            InstanceNormalEvent normal;

            InstanceHandle[] handlesToNotify = null;
            lock (ThisLock)
            {
                WeakReference ownerReference;
                if (!_owners.TryGetValue(owner.InstanceOwnerId, out ownerReference) || !object.ReferenceEquals(ownerReference.Target, owner))
                {
                    throw Fx.Exception.Argument("owner", SR.OwnerBelongsToWrongStore);
                }

                normal = GetOwnerEventHelper(persistenceEvent, owner);
                if (!normal.IsSignaled)
                {
                    normal.IsSignaled = true;
                    if (normal.BoundHandles.Count > 0)
                    {
                        handlesToNotify = normal.BoundHandles.ToArray();
                    }
                }
            }
            if (handlesToNotify != null)
            {
                foreach (InstanceHandle handle in handlesToNotify)
                {
                    handle.EventReady(normal);
                }
            }
        }
コード例 #8
0
        internal void BindOwnerEvent(InstancePersistenceEvent persistenceEvent)
        {
            lock (ThisLock)
            {
                Fx.Assert(OperationPending, "Should only be called during an operation.");
                Fx.Assert(AcquirePending == null, "Should only be called after acquiring the transaction.");
                Fx.Assert(Owner != null, "Must be bound to owner to have an owner-scoped event.");

                if (IsValid && (_boundOwnerEvents == null || !_boundOwnerEvents.Contains(persistenceEvent.Name)))
                {
                    if (_pendingOwnerEvents == null)
                    {
                        _pendingOwnerEvents = new HashSet <InstancePersistenceEvent>();
                    }
                    else if (_pendingOwnerEvents.Contains(persistenceEvent))
                    {
                        return;
                    }
                    _pendingOwnerEvents.Add(persistenceEvent);
                    Store.PendHandleToEvent(this, persistenceEvent, Owner);
                }
            }
        }
コード例 #9
0
        // Returns null if an InstanceHandleConflictException should be thrown.
        internal InstanceView Commit(InstanceView newState)
        {
            Fx.Assert(newState != null, "Null view passed to Commit.");
            newState.MakeReadOnly();
            View = newState;

            List <InstanceHandleReference> handlesPendingResolution = null;
            InstanceHandle handleToFree                      = null;
            List <InstancePersistenceEvent> normals          = null;
            WaitForEventsAsyncResult        resultToComplete = null;

            try
            {
                lock (ThisLock)
                {
                    if (_inProgressBind != null)
                    {
                        // If there's a Version, it should be committed.
                        if (Version != -1)
                        {
                            if (!Owner.TryCompleteBind(ref _inProgressBind, ref handlesPendingResolution, out handleToFree))
                            {
                                return(null);
                            }
                        }
                        else
                        {
                            Fx.Assert(OperationPending, "Should have cancelled this bind in FinishOperation.");
                            Fx.Assert(AcquirePending == null, "Should not be in Commit during AcquirePending.");
                            Owner.CancelBind(ref _inProgressBind, ref handlesPendingResolution);
                        }
                    }

                    if (_pendingOwnerEvents != null && IsValid)
                    {
                        if (_boundOwnerEvents == null)
                        {
                            _boundOwnerEvents = new HashSet <XName>();
                        }

                        foreach (InstancePersistenceEvent persistenceEvent in _pendingOwnerEvents)
                        {
                            if (!_boundOwnerEvents.Add(persistenceEvent.Name))
                            {
                                Fx.Assert("Should not have conflicts between pending and bound events.");
                                continue;
                            }

                            InstancePersistenceEvent normal = Store.AddHandleToEvent(this, persistenceEvent, Owner);
                            if (normal != null)
                            {
                                if (normals == null)
                                {
                                    normals = new List <InstancePersistenceEvent>(_pendingOwnerEvents.Count);
                                }
                                normals.Add(normal);
                            }
                        }

                        _pendingOwnerEvents = null;

                        if (normals != null && _waitResult != null)
                        {
                            resultToComplete = _waitResult;
                            _waitResult      = null;
                        }
                    }

                    return(View);
                }
            }
            finally
            {
                InstanceOwner.ResolveHandles(handlesPendingResolution);

                // This is a convenience, it is not required for correctness.
                if (handleToFree != null)
                {
                    Fx.Assert(!object.ReferenceEquals(handleToFree, this), "Shouldn't have been told to free ourselves.");
                    handleToFree.Free();
                }

                if (resultToComplete != null)
                {
                    resultToComplete.Signaled(normals);
                }
            }
        }
コード例 #10
0
 internal InstanceNormalEvent(InstancePersistenceEvent persistenceEvent)
     : base(persistenceEvent.Name)
 {
 }