Code:
/ 4.0 / 4.0 / 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.
//----------------------------------------------------------------
// 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

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SimpleApplicationHost.cs
- ProfilePropertyNameValidator.cs
- OrderedDictionary.cs
- PagesChangedEventArgs.cs
- Accessible.cs
- EditorAttribute.cs
- BreakRecordTable.cs
- WindowsPrincipal.cs
- AutomationIdentifier.cs
- FtpRequestCacheValidator.cs
- QilDataSource.cs
- OLEDB_Util.cs
- Int16KeyFrameCollection.cs
- Message.cs
- ConfigurationStrings.cs
- SimplePropertyEntry.cs
- DataTransferEventArgs.cs
- TextServicesPropertyRanges.cs
- MetadataArtifactLoaderCompositeFile.cs
- iisPickupDirectory.cs
- DesignTimeResourceProviderFactoryAttribute.cs
- EventMap.cs
- QilChoice.cs
- MergablePropertyAttribute.cs
- SharedPerformanceCounter.cs
- _PooledStream.cs
- ComPlusServiceHost.cs
- CommentAction.cs
- IncrementalCompileAnalyzer.cs
- TokenizerHelper.cs
- ToolStripSettings.cs
- TemplateControlCodeDomTreeGenerator.cs
- SimpleBitVector32.cs
- BrowserTree.cs
- SequentialWorkflowRootDesigner.cs
- DeviceSpecific.cs
- PolyBezierSegment.cs
- _Events.cs
- DmlSqlGenerator.cs
- SafeCryptContextHandle.cs
- CultureInfo.cs
- AnnotationObservableCollection.cs
- WebMethodAttribute.cs
- WebServiceHost.cs
- DataRowIndexBuffer.cs
- VersionedStream.cs
- TimeSpanConverter.cs
- ProtectedConfigurationProviderCollection.cs
- BinarySerializer.cs
- ArrangedElement.cs
- CharStorage.cs
- ConfigXmlElement.cs
- ExpressionBuilderContext.cs
- MultiBindingExpression.cs
- LogEntrySerializer.cs
- TextDecorationLocationValidation.cs
- IxmlLineInfo.cs
- SqlPersonalizationProvider.cs
- Decimal.cs
- CqlBlock.cs
- CompatibleComparer.cs
- ExpandCollapseProviderWrapper.cs
- LineServices.cs
- CqlErrorHelper.cs
- ModelUIElement3D.cs
- TemplateContainer.cs
- OLEDB_Enum.cs
- GroupItemAutomationPeer.cs
- BatchParser.cs
- ObjectDataSourceMethodEventArgs.cs
- NativeCppClassAttribute.cs
- DecoderExceptionFallback.cs
- DataPagerCommandEventArgs.cs
- CacheDependency.cs
- DataComponentNameHandler.cs
- DrawingContextDrawingContextWalker.cs
- MatrixAnimationBase.cs
- XmlSerializationGeneratedCode.cs
- Bitmap.cs
- UnauthorizedWebPart.cs
- ValidatorCollection.cs
- StrongName.cs
- DragDropHelper.cs
- ChildDocumentBlock.cs
- MatrixConverter.cs
- SafeWaitHandle.cs
- PropertyInformation.cs
- IntegerValidatorAttribute.cs
- SafeNativeMemoryHandle.cs
- Operator.cs
- TextElement.cs
- PathGeometry.cs
- GridView.cs
- RadioButtonAutomationPeer.cs
- RtType.cs
- CodeValidator.cs
- ToolboxComponentsCreatedEventArgs.cs
- DocumentSequence.cs
- PackageDigitalSignatureManager.cs
- MailSettingsSection.cs