InstanceStore.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / System.Runtime.DurableInstancing / System / Runtime / DurableInstancing / InstanceStore.cs / 1305376 / InstanceStore.cs

                            //---------------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//---------------------------------------------------------------

namespace System.Runtime.DurableInstancing 
{
    using System; 
    using System.Collections.Generic; 
    using System.Linq;
    using System.Transactions; 
    using System.Xml.Linq;

    // Persistence Lock Order:
    // InstanceHandle.ThisLock then InstanceStore.ThisLock 
    // InstanceHandle.ThisLock then InstanceOwner.HandlesLock
 
    [Fx.Tag.XamlVisible(false)] 
    public abstract class InstanceStore
    { 
        readonly Dictionary owners = new Dictionary(1);

        Guid[] ownerKeysToScan = new Guid[0];
        int ownerKeysIndexToScan = 0; 

        protected InstanceStore() 
        { 
        }
 
        object ThisLock
        {
            get
            { 
                return this.owners;
            } 
        } 

        public InstanceOwner DefaultInstanceOwner { get; set; } 

        public InstanceHandle CreateInstanceHandle()
        {
            return CreateInstanceHandle(DefaultInstanceOwner); 
        }
 
        public InstanceHandle CreateInstanceHandle(InstanceOwner owner) 
        {
            return PrepareInstanceHandle(new InstanceHandle(this, owner)); 
        }

        public InstanceHandle CreateInstanceHandle(Guid instanceId)
        { 
            return CreateInstanceHandle(DefaultInstanceOwner, instanceId);
        } 
 
        public InstanceHandle CreateInstanceHandle(InstanceOwner owner, Guid instanceId)
        { 
            if (instanceId == Guid.Empty)
            {
                throw Fx.Exception.Argument("instanceId", SRCore.CannotCreateContextWithNullId);
            } 
            return PrepareInstanceHandle(new InstanceHandle(this, owner, instanceId));
        } 
 
        [Fx.Tag.Throws.Timeout("The operation timed out; the InstanceHandle is no longer valid.")]
        [Fx.Tag.Throws(typeof(OperationCanceledException), "The operation was canceled; the InstanceHandle is no longer valid.")] 
        [Fx.Tag.Throws(typeof(InstancePersistenceException), "A command failed.")]
        [Fx.Tag.Throws(typeof(TransactionException), "The transaction in use for the command failed.")]
        [Fx.Tag.Blocking(CancelMethod = "Free", CancelDeclaringType = typeof(InstanceHandle))]
        public InstanceView Execute(InstanceHandle handle, InstancePersistenceCommand command, TimeSpan timeout) 
        {
            if (command == null) 
            { 
                throw Fx.Exception.ArgumentNull("command");
            } 
            if (handle == null)
            {
                throw Fx.Exception.ArgumentNull("handle");
            } 
            if (!object.ReferenceEquals(this, handle.Store))
            { 
                throw Fx.Exception.Argument("handle", SRCore.ContextNotFromThisStore); 
            }
            TimeoutHelper.ThrowIfNegativeArgument(timeout); 

            return InstancePersistenceContext.OuterExecute(handle, command, Transaction.Current, timeout);
        }
 
        [Fx.Tag.InheritThrows(From = "Execute")]
        public IAsyncResult BeginExecute(InstanceHandle handle, InstancePersistenceCommand command, TimeSpan timeout, AsyncCallback callback, object state) 
        { 
            if (command == null)
            { 
                throw Fx.Exception.ArgumentNull("command");
            }
            if (handle == null)
            { 
                throw Fx.Exception.ArgumentNull("handle");
            } 
            if (!object.ReferenceEquals(this, handle.Store)) 
            {
                throw Fx.Exception.Argument("handle", SRCore.ContextNotFromThisStore); 
            }
            TimeoutHelper.ThrowIfNegativeArgument(timeout);

            return InstancePersistenceContext.BeginOuterExecute(handle, command, Transaction.Current, timeout, callback, state); 
        }
 
        [Fx.Tag.InheritThrows(From = "Execute")] 
        [Fx.Tag.Blocking(CancelMethod = "Free", CancelDeclaringType = typeof(InstanceHandle), Conditional = "!result.IsCompleted")]
        public InstanceView EndExecute(IAsyncResult result) 
        {
            return InstancePersistenceContext.EndOuterExecute(result);
        }
 
        [Fx.Tag.Throws.Timeout("The operation timed out.")]
        [Fx.Tag.Throws(typeof(OperationCanceledException), "The operation was canceled; the InstanceHandle is no longer valid.")] 
        [Fx.Tag.Blocking(CancelMethod = "Free", CancelDeclaringType = typeof(InstanceHandle), Conditional = "timeout != TimeSpan.Zero")] 
        public List WaitForEvents(InstanceHandle handle, TimeSpan timeout)
        { 
            // This has to block on something... might as well be the async result, if the caller is already willing to waste a thread.
            // (The TimeSpan.Zero case isn't fully optimized, but it is special-cased internally to not create timers / wait, it always
            // completes synchronously or throws TimeoutException from BeginWaitForEvents.)
            return EndWaitForEvents(BeginWaitForEvents(handle, timeout, null, null)); 
        }
 
        [Fx.Tag.InheritThrows(From = "WaitForEvents")] 
        public IAsyncResult BeginWaitForEvents(InstanceHandle handle, TimeSpan timeout, AsyncCallback callback, object state)
        { 
            if (handle == null)
            {
                throw Fx.Exception.ArgumentNull("handle");
            } 
            if (!object.ReferenceEquals(this, handle.Store))
            { 
                throw Fx.Exception.Argument("handle", SRCore.ContextNotFromThisStore); 
            }
            TimeoutHelper.ThrowIfNegativeArgument(timeout); 

            return InstanceHandle.BeginWaitForEvents(handle, timeout, callback, state);
        }
 
        [Fx.Tag.InheritThrows(From = "WaitForEvents")]
        [Fx.Tag.Blocking(CancelMethod = "Free", CancelDeclaringType = typeof(InstanceHandle), Conditional = "!result.IsCompleted")] 
        public List EndWaitForEvents(IAsyncResult result) 
        {
            return InstanceHandle.EndWaitForEvents(result); 
        }

        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 (!this.owners.TryGetValue(owner.InstanceOwnerId, out ownerReference) || !object.ReferenceEquals(ownerReference.Target, owner))
                {
                    throw Fx.Exception.Argument("owner", SRCore.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);
                }
            } 
        }
 
        protected void ResetEvent(InstancePersistenceEvent persistenceEvent, InstanceOwner owner) 
        {
            if (persistenceEvent == null) 
            {
                throw Fx.Exception.ArgumentNull("persistenceEvent");
            }
            if (owner == null) 
            {
                throw Fx.Exception.ArgumentNull("owner"); 
            } 

            InstanceNormalEvent normal; 
            lock (ThisLock)
            {
                WeakReference ownerReference;
                if (!this.owners.TryGetValue(owner.InstanceOwnerId, out ownerReference) || !object.ReferenceEquals(ownerReference.Target, owner)) 
                {
                    throw Fx.Exception.Argument("owner", SRCore.OwnerBelongsToWrongStore); 
                } 

                if (!owner.Events.TryGetValue(persistenceEvent.Name, out normal)) 
                {
                    return;
                }
 
                if (normal.IsSignaled)
                { 
                    normal.IsSignaled = false; 
                    if (normal.BoundHandles.Count == 0 && normal.PendingHandles.Count == 0)
                    { 
                        owner.Events.Remove(persistenceEvent.Name);
                    }
                }
            } 
        }
 
        protected virtual object OnNewInstanceHandle(InstanceHandle instanceHandle) 
        {
            return null; 
        }

        protected virtual void OnFreeInstanceHandle(InstanceHandle instanceHandle, object userContext)
        { 
        }
 
        [Fx.Tag.InheritThrows(From = "Execute")] 
        [Fx.Tag.Blocking(CancelMethod = "Free", CancelDeclaringType = typeof(InstanceHandle))]
        protected internal virtual bool TryCommand(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout) 
        {
            return EndTryCommand(BeginTryCommand(context, command, timeout, null, null));
        }
 
        [Fx.Tag.InheritThrows(From = "TryCommand")]
        protected internal virtual IAsyncResult BeginTryCommand(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout, AsyncCallback callback, object state) 
        { 
            return new CompletedAsyncResult(false, callback, state);
        } 

        [Fx.Tag.InheritThrows(From = "TryCommand")]
        [Fx.Tag.Blocking(CancelMethod = "Free", CancelDeclaringType = typeof(InstanceHandle), Conditional = "!result.IsCompleted")]
        protected internal virtual bool EndTryCommand(IAsyncResult result) 
        {
            return CompletedAsyncResult.End(result); 
        } 

        protected InstanceOwner[] GetInstanceOwners() 
        {
            lock (ThisLock)
            {
                return this.owners.Values.Select(weakReference => (InstanceOwner)weakReference.Target).Where(owner => owner != null).ToArray(); 
            }
        } 
 
        protected InstancePersistenceEvent[] GetEvents(InstanceOwner owner)
        { 
            if (owner == null)
            {
                throw Fx.Exception.ArgumentNull("owner");
            } 

            lock (ThisLock) 
            { 
                WeakReference ownerReference;
                if (!this.owners.TryGetValue(owner.InstanceOwnerId, out ownerReference) || !object.ReferenceEquals(ownerReference.Target, owner)) 
                {
                    throw Fx.Exception.Argument("owner", SRCore.OwnerBelongsToWrongStore);
                }
 
                return owner.Events.Values.ToArray();
            } 
        } 

        internal InstanceOwner GetOrCreateOwner(Guid instanceOwnerId, Guid lockToken) 
        {
            lock (ThisLock)
            {
                WeakReference ownerRef; 
                InstanceOwner owner;
                if (this.owners.TryGetValue(instanceOwnerId, out ownerRef)) 
                { 
                    owner = (InstanceOwner)ownerRef.Target;
                    if (owner == null) 
                    {
                        owner = new InstanceOwner(instanceOwnerId, lockToken);
                        ownerRef.Target = owner;
                    } 
                    else if (owner.OwnerToken != lockToken)
                    { 
                        throw Fx.Exception.AsError(new InvalidOperationException(SRCore.StoreReportedConflictingLockTokens)); 
                    }
                } 
                else
                {
                    owner = new InstanceOwner(instanceOwnerId, lockToken);
                    this.owners.Add(instanceOwnerId, new WeakReference(owner)); 
                }
 
                while (true) 
                {
                    if (this.ownerKeysToScan.Length == this.ownerKeysIndexToScan) 
                    {
                        this.ownerKeysToScan = new Guid[this.owners.Count];
                        this.owners.Keys.CopyTo(this.ownerKeysToScan, 0);
                        this.ownerKeysIndexToScan = 0; 
                        break;
                    } 
 
                    Guid current = this.ownerKeysToScan[this.ownerKeysIndexToScan++];
                    if (this.owners.TryGetValue(current, out ownerRef)) 
                    {
                        if (ownerRef.Target == null)
                        {
                            this.owners.Remove(current); 
                        }
                        else 
                        { 
                            break;
                        } 
                    }
                }

                return owner; 
            }
        } 
 
        internal void PendHandleToEvent(InstanceHandle handle, InstancePersistenceEvent persistenceEvent, InstanceOwner owner)
        { 
            lock (ThisLock)
            {
                Fx.Assert(this.owners.ContainsKey(owner.InstanceOwnerId), "InstanceHandle called PendHandleToEvent on wrong InstanceStore!!");
                Fx.Assert(object.ReferenceEquals(this.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); 
            }
        }

        internal InstancePersistenceEvent AddHandleToEvent(InstanceHandle handle, InstancePersistenceEvent persistenceEvent, InstanceOwner owner) 
        {
            lock (ThisLock) 
            { 
                Fx.Assert(this.owners.ContainsKey(owner.InstanceOwnerId), "InstanceHandle called AddHandleToEvent on wrong InstanceStore!!");
                Fx.Assert(object.ReferenceEquals(this.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; 
            }
        } 

        internal List SelectSignaledEvents(IEnumerable eventNames, InstanceOwner owner)
        {
            List readyEvents = null; 
            lock (ThisLock)
            { 
                Fx.Assert(this.owners.ContainsKey(owner.InstanceOwnerId), "InstanceHandle called SelectSignaledEvents on wrong InstanceStore!!"); 
                Fx.Assert(object.ReferenceEquals(this.owners[owner.InstanceOwnerId].Target, owner), "How did multiple instances of the same owner become simultaneously active?");
 
                // Entry must exist since it is still registered by the handle.
                foreach (InstanceNormalEvent normal in eventNames.Select(name => owner.Events[name]))
                {
                    if (normal.IsSignaled) 
                    {
                        if (readyEvents == null) 
                        { 
                            readyEvents = new List(1);
                        } 
                        readyEvents.Add(normal);
                    }
                }
            } 
            return readyEvents;
        } 
 
        internal void RemoveHandleFromEvents(InstanceHandle handle, IEnumerable eventNames, InstanceOwner owner)
        { 
            lock (ThisLock)
            {
                Fx.Assert(this.owners.ContainsKey(owner.InstanceOwnerId), "InstanceHandle called RemoveHandleFromEvents on wrong InstanceStore!!");
                Fx.Assert(object.ReferenceEquals(this.owners[owner.InstanceOwnerId].Target, owner), "How did multiple instances of the same owner become simultaneously active in RemoveHandleFromEvents?"); 

                // Entry must exist since it is still registered by the handle. 
                foreach (InstanceNormalEvent normal in eventNames.Select(name => owner.Events[name])) 
                {
                    Fx.Assert(normal.BoundHandles.Contains(handle) || normal.PendingHandles.Contains(handle), "Event should still have handle registration."); 

                    normal.PendingHandles.Remove(handle);
                    normal.BoundHandles.Remove(handle);
                    if (!normal.IsSignaled && normal.BoundHandles.Count == 0 && normal.PendingHandles.Count == 0) 
                    {
                        owner.Events.Remove(normal.Name); 
                    } 
                }
            } 
        }

        // Must be called under ThisLock.  Doesn't validate the InstanceOwner.
        InstanceNormalEvent GetOwnerEventHelper(InstancePersistenceEvent persistenceEvent, InstanceOwner owner) 
        {
            InstanceNormalEvent normal; 
            if (!owner.Events.TryGetValue(persistenceEvent.Name, out normal)) 
            {
                normal = new InstanceNormalEvent(persistenceEvent); 
                owner.Events.Add(persistenceEvent.Name, normal);
            }
            return normal;
        } 

        internal void FreeInstanceHandle(InstanceHandle handle, object providerObject) 
        { 
            try
            { 
                OnFreeInstanceHandle(handle, providerObject);
            }
            catch (Exception exception)
            { 
                if (Fx.IsFatal(exception))
                { 
                    throw; 
                }
                throw Fx.Exception.AsError(new CallbackException(SRCore.OnFreeInstanceHandleThrew, exception)); 
            }
        }

        InstanceHandle PrepareInstanceHandle(InstanceHandle handle) 
        {
            handle.ProviderObject = OnNewInstanceHandle(handle); 
            return handle; 
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK