Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / RunTime / Lock.cs / 1305376 / Lock.cs
// **************************************************************************** // Copyright (C) Microsoft Corporation. All rights reserved. // // CONTENTS // Value-add wrapper on top of standard CLR monitor // using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.Xml; using System.Reflection; using System.Threading; using System.Diagnostics; using System.Transactions; using System.Workflow.Runtime.Hosting; namespace System.Workflow.Runtime { internal static class LockFactory { internal static InstanceLock CreateWorkflowExecutorLock(Guid id) { return new InstanceLock(id, "Workflow Executor Lock: " + id.ToString(), 50, LockPriorityOperator.GreaterThanOrReentrant); } internal static InstanceLock CreateWorkflowSchedulerLock(Guid id) { return new InstanceLock(id, "Workflow Scheduler Lock: " + id.ToString(), 40, LockPriorityOperator.GreaterThan); } internal static InstanceLock CreateWorkflowMessageDeliveryLock(Guid id) { return new InstanceLock(id, "Workflow Message Delivery Lock: " + id.ToString(), 35, LockPriorityOperator.GreaterThanOrReentrant); } } internal enum LockPriorityOperator { GreaterThan, GreaterThanOrReentrant, } internal sealed class InstanceLock { #region Static Data/Methods [ThreadStaticAttribute()] private static Listt_heldLocks = null; [Conditional("DEBUG")] internal static void AssertNoLocksHeld() { #if DEBUG System.Diagnostics.Debug.Assert(HeldLocks.Count == 0, "No locks should be held."); #endif } [Conditional("DEBUG")] internal static void AssertIsLocked(InstanceLock theLock) { #if DEBUG System.Diagnostics.Debug.Assert(HeldLocks.Contains(theLock), "Lock should be held."); #endif } private static List HeldLocks { get { List tLocks = InstanceLock.t_heldLocks; if (tLocks == null) { InstanceLock.t_heldLocks = new List (); tLocks = InstanceLock.t_heldLocks; } return tLocks; } } #endregion Static Data/Methods private Guid m_instanceId; private String m_name; private int m_priority; private LockPriorityOperator m_operator; internal int Priority { get { return this.m_priority; } } internal LockPriorityOperator Operator { get { return this.m_operator; } } internal InstanceLock(Guid id, String name, int priority, LockPriorityOperator lockOperator) { this.m_instanceId = id; this.m_name = name; this.m_priority = priority; this.m_operator = lockOperator; } internal Guid InstanceId { get { return this.m_instanceId; } } internal InstanceLockGuard Enter() { return new InstanceLockGuard(this); } internal bool TryEnter() { InstanceLockGuard.EnforceGuard(this); bool lockHeld = false; bool success = false; try { Monitor.TryEnter(this, ref lockHeld); if (lockHeld) { HeldLocks.Add(this); success = true; } } finally { if (lockHeld && !success) { Monitor.Exit(this); } } return success; } internal void Exit() { try { HeldLocks.Remove(this); } finally { Monitor.Exit(this); } } internal struct InstanceLockGuard : IDisposable { readonly InstanceLock m_lock; internal static void EnforceGuard(InstanceLock theLock) { foreach (InstanceLock heldLock in HeldLocks) { switch (theLock.Operator) { case LockPriorityOperator.GreaterThan: if (heldLock.InstanceId == theLock.InstanceId && heldLock.Priority <= theLock.Priority) throw new InvalidOperationException(ExecutionStringManager.InstanceOperationNotValidinWorkflowThread); break; case LockPriorityOperator.GreaterThanOrReentrant: // the checks here assume that locks have unique priorities if (heldLock.InstanceId == theLock.InstanceId && heldLock.Priority < theLock.Priority) throw new InvalidOperationException(ExecutionStringManager.InstanceOperationNotValidinWorkflowThread); break; default: System.Diagnostics.Debug.Assert(false, "Unrecognized lock operator"); break; } } } internal InstanceLockGuard(InstanceLock theLock) { this.m_lock = theLock; // Note: the following operations are logically atomic, but since the // list we are using is thread local there is no need to take a lock. EnforceGuard(theLock); try { } finally { bool success = false; #pragma warning disable 0618 //@ Monitor.Enter(this.m_lock); #pragma warning restore 0618 try { HeldLocks.Add(this.m_lock); success = true; } finally { if (!success) { Monitor.Exit(this.m_lock); } } } } internal void Pulse() { Monitor.Pulse(this.m_lock); } internal void Wait() { Monitor.Wait(this.m_lock); } public void Dispose() { // Note: the following operations are logically atomic, but since the // list we are using is thread local there is no need to take a lock. try { HeldLocks.Remove(this.m_lock); } finally { Monitor.Exit(this.m_lock); } } } } internal sealed class SchedulerLockGuard : IDisposable { private InstanceLock.InstanceLockGuard lg; private WorkflowExecutor workflowExec; internal SchedulerLockGuard(InstanceLock il, WorkflowExecutor w) { lg = il.Enter(); workflowExec = w; } private static void FireEvents(List eventList, WorkflowExecutor workflowExec) { if (!workflowExec.IsInstanceValid && (workflowExec.WorkflowStatus == WorkflowStatus.Completed || workflowExec.WorkflowStatus == WorkflowStatus.Terminated)) { // The workflow is dead, let the instance have a hard ref to the corpse for support of the query apis. workflowExec.WorkflowInstance.DeadWorkflow = workflowExec; } for (int i = 0; i < eventList.Count; i++) { SchedulerLockGuardInfo eseg = eventList[i]; // eseg.EventInfo is non-null only if the event type is Suspended or Terminated // If the event type is Suspended, then call FireWorkflowSuspended after casting // the event argument to a String. // If the event type is Terminated, then call FireWorkflowTerminated after casting // the event argument to either a String or an Exception. switch (eseg.EventType) { case WorkflowEventInternal.Suspended: workflowExec.FireWorkflowSuspended((String)eseg.EventInfo); break; case WorkflowEventInternal.Terminated: if ((eseg.EventInfo as System.Exception) != null) { workflowExec.FireWorkflowTerminated((Exception)eseg.EventInfo); } else { workflowExec.FireWorkflowTerminated((String)eseg.EventInfo); } break; default: workflowExec.FireWorkflowExecutionEvent(eseg.Sender, eseg.EventType); break; } } } internal static void Exit(InstanceLock il, WorkflowExecutor w) { List eventList = new List (w.EventsToFireList); w.EventsToFireList.Clear(); il.Exit(); FireEvents(eventList, w); } public void Dispose() { List eventList = new List (workflowExec.EventsToFireList); workflowExec.EventsToFireList.Clear(); lg.Dispose(); FireEvents(eventList, workflowExec); } } internal sealed class SchedulerLockGuardInfo { private Object sender; private WorkflowEventInternal eventType; private object eventInfo; internal SchedulerLockGuardInfo(Object _sender, WorkflowEventInternal _eventType) { sender = _sender; eventType = _eventType; eventInfo = null; } internal SchedulerLockGuardInfo(Object _sender, WorkflowEventInternal _eventType, object _eventInfo) : this(_sender, _eventType) { eventInfo = _eventInfo; } internal Object Sender { get { return sender; } } internal WorkflowEventInternal EventType { get { return eventType; } } internal Object EventInfo { get { return eventInfo; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. // **************************************************************************** // Copyright (C) Microsoft Corporation. All rights reserved. // // CONTENTS // Value-add wrapper on top of standard CLR monitor // using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.Xml; using System.Reflection; using System.Threading; using System.Diagnostics; using System.Transactions; using System.Workflow.Runtime.Hosting; namespace System.Workflow.Runtime { internal static class LockFactory { internal static InstanceLock CreateWorkflowExecutorLock(Guid id) { return new InstanceLock(id, "Workflow Executor Lock: " + id.ToString(), 50, LockPriorityOperator.GreaterThanOrReentrant); } internal static InstanceLock CreateWorkflowSchedulerLock(Guid id) { return new InstanceLock(id, "Workflow Scheduler Lock: " + id.ToString(), 40, LockPriorityOperator.GreaterThan); } internal static InstanceLock CreateWorkflowMessageDeliveryLock(Guid id) { return new InstanceLock(id, "Workflow Message Delivery Lock: " + id.ToString(), 35, LockPriorityOperator.GreaterThanOrReentrant); } } internal enum LockPriorityOperator { GreaterThan, GreaterThanOrReentrant, } internal sealed class InstanceLock { #region Static Data/Methods [ThreadStaticAttribute()] private static List t_heldLocks = null; [Conditional("DEBUG")] internal static void AssertNoLocksHeld() { #if DEBUG System.Diagnostics.Debug.Assert(HeldLocks.Count == 0, "No locks should be held."); #endif } [Conditional("DEBUG")] internal static void AssertIsLocked(InstanceLock theLock) { #if DEBUG System.Diagnostics.Debug.Assert(HeldLocks.Contains(theLock), "Lock should be held."); #endif } private static List HeldLocks { get { List tLocks = InstanceLock.t_heldLocks; if (tLocks == null) { InstanceLock.t_heldLocks = new List (); tLocks = InstanceLock.t_heldLocks; } return tLocks; } } #endregion Static Data/Methods private Guid m_instanceId; private String m_name; private int m_priority; private LockPriorityOperator m_operator; internal int Priority { get { return this.m_priority; } } internal LockPriorityOperator Operator { get { return this.m_operator; } } internal InstanceLock(Guid id, String name, int priority, LockPriorityOperator lockOperator) { this.m_instanceId = id; this.m_name = name; this.m_priority = priority; this.m_operator = lockOperator; } internal Guid InstanceId { get { return this.m_instanceId; } } internal InstanceLockGuard Enter() { return new InstanceLockGuard(this); } internal bool TryEnter() { InstanceLockGuard.EnforceGuard(this); bool lockHeld = false; bool success = false; try { Monitor.TryEnter(this, ref lockHeld); if (lockHeld) { HeldLocks.Add(this); success = true; } } finally { if (lockHeld && !success) { Monitor.Exit(this); } } return success; } internal void Exit() { try { HeldLocks.Remove(this); } finally { Monitor.Exit(this); } } internal struct InstanceLockGuard : IDisposable { readonly InstanceLock m_lock; internal static void EnforceGuard(InstanceLock theLock) { foreach (InstanceLock heldLock in HeldLocks) { switch (theLock.Operator) { case LockPriorityOperator.GreaterThan: if (heldLock.InstanceId == theLock.InstanceId && heldLock.Priority <= theLock.Priority) throw new InvalidOperationException(ExecutionStringManager.InstanceOperationNotValidinWorkflowThread); break; case LockPriorityOperator.GreaterThanOrReentrant: // the checks here assume that locks have unique priorities if (heldLock.InstanceId == theLock.InstanceId && heldLock.Priority < theLock.Priority) throw new InvalidOperationException(ExecutionStringManager.InstanceOperationNotValidinWorkflowThread); break; default: System.Diagnostics.Debug.Assert(false, "Unrecognized lock operator"); break; } } } internal InstanceLockGuard(InstanceLock theLock) { this.m_lock = theLock; // Note: the following operations are logically atomic, but since the // list we are using is thread local there is no need to take a lock. EnforceGuard(theLock); try { } finally { bool success = false; #pragma warning disable 0618 //@ Monitor.Enter(this.m_lock); #pragma warning restore 0618 try { HeldLocks.Add(this.m_lock); success = true; } finally { if (!success) { Monitor.Exit(this.m_lock); } } } } internal void Pulse() { Monitor.Pulse(this.m_lock); } internal void Wait() { Monitor.Wait(this.m_lock); } public void Dispose() { // Note: the following operations are logically atomic, but since the // list we are using is thread local there is no need to take a lock. try { HeldLocks.Remove(this.m_lock); } finally { Monitor.Exit(this.m_lock); } } } } internal sealed class SchedulerLockGuard : IDisposable { private InstanceLock.InstanceLockGuard lg; private WorkflowExecutor workflowExec; internal SchedulerLockGuard(InstanceLock il, WorkflowExecutor w) { lg = il.Enter(); workflowExec = w; } private static void FireEvents(List eventList, WorkflowExecutor workflowExec) { if (!workflowExec.IsInstanceValid && (workflowExec.WorkflowStatus == WorkflowStatus.Completed || workflowExec.WorkflowStatus == WorkflowStatus.Terminated)) { // The workflow is dead, let the instance have a hard ref to the corpse for support of the query apis. workflowExec.WorkflowInstance.DeadWorkflow = workflowExec; } for (int i = 0; i < eventList.Count; i++) { SchedulerLockGuardInfo eseg = eventList[i]; // eseg.EventInfo is non-null only if the event type is Suspended or Terminated // If the event type is Suspended, then call FireWorkflowSuspended after casting // the event argument to a String. // If the event type is Terminated, then call FireWorkflowTerminated after casting // the event argument to either a String or an Exception. switch (eseg.EventType) { case WorkflowEventInternal.Suspended: workflowExec.FireWorkflowSuspended((String)eseg.EventInfo); break; case WorkflowEventInternal.Terminated: if ((eseg.EventInfo as System.Exception) != null) { workflowExec.FireWorkflowTerminated((Exception)eseg.EventInfo); } else { workflowExec.FireWorkflowTerminated((String)eseg.EventInfo); } break; default: workflowExec.FireWorkflowExecutionEvent(eseg.Sender, eseg.EventType); break; } } } internal static void Exit(InstanceLock il, WorkflowExecutor w) { List eventList = new List (w.EventsToFireList); w.EventsToFireList.Clear(); il.Exit(); FireEvents(eventList, w); } public void Dispose() { List eventList = new List (workflowExec.EventsToFireList); workflowExec.EventsToFireList.Clear(); lg.Dispose(); FireEvents(eventList, workflowExec); } } internal sealed class SchedulerLockGuardInfo { private Object sender; private WorkflowEventInternal eventType; private object eventInfo; internal SchedulerLockGuardInfo(Object _sender, WorkflowEventInternal _eventType) { sender = _sender; eventType = _eventType; eventInfo = null; } internal SchedulerLockGuardInfo(Object _sender, WorkflowEventInternal _eventType, object _eventInfo) : this(_sender, _eventType) { eventInfo = _eventInfo; } internal Object Sender { get { return sender; } } internal WorkflowEventInternal EventType { get { return eventType; } } internal Object EventInfo { get { return eventInfo; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- FixedPosition.cs
- ApplicationManager.cs
- DataGridViewCellValidatingEventArgs.cs
- ReferencedCollectionType.cs
- OpacityConverter.cs
- CheckPair.cs
- PatternMatcher.cs
- RawTextInputReport.cs
- XMLSyntaxException.cs
- Scanner.cs
- GridViewAutomationPeer.cs
- DiffuseMaterial.cs
- XmlLangPropertyAttribute.cs
- Geometry3D.cs
- SqlOuterApplyReducer.cs
- ReadOnlyDictionary.cs
- HtmlForm.cs
- storagemappingitemcollection.viewdictionary.cs
- SelectionItemPattern.cs
- RenderingEventArgs.cs
- ObjRef.cs
- StoryFragments.cs
- RightsManagementManager.cs
- WebColorConverter.cs
- ClrProviderManifest.cs
- SafeFileMappingHandle.cs
- XPathSelectionIterator.cs
- SessionStateItemCollection.cs
- BuildProvider.cs
- VisualBasicHelper.cs
- HTMLTagNameToTypeMapper.cs
- ArrayConverter.cs
- TlsSspiNegotiation.cs
- SqlXmlStorage.cs
- XPathNodeIterator.cs
- SimpleTypesSurrogate.cs
- CodeTypeDeclaration.cs
- SR.cs
- BinaryMethodMessage.cs
- DbQueryCommandTree.cs
- BeginStoryboard.cs
- SemaphoreFullException.cs
- WsatServiceCertificate.cs
- ListView.cs
- RelationshipConverter.cs
- StickyNoteAnnotations.cs
- JsonMessageEncoderFactory.cs
- DisplayInformation.cs
- HttpListenerElement.cs
- CharacterMetrics.cs
- EventMap.cs
- JapaneseLunisolarCalendar.cs
- InstalledFontCollection.cs
- TextEditorContextMenu.cs
- ResourceFallbackManager.cs
- AnnotationAdorner.cs
- HttpHandlerActionCollection.cs
- BlockingCollection.cs
- EntityStoreSchemaFilterEntry.cs
- MouseButton.cs
- PropertyPushdownHelper.cs
- webeventbuffer.cs
- NetNamedPipeBinding.cs
- XslCompiledTransform.cs
- SmtpNetworkElement.cs
- QueryableDataSource.cs
- JoinElimination.cs
- PageThemeCodeDomTreeGenerator.cs
- SurrogateDataContract.cs
- SqlFacetAttribute.cs
- CodeMemberProperty.cs
- HtmlForm.cs
- ExpressionBindingCollection.cs
- WindowHideOrCloseTracker.cs
- WebPartEditorOkVerb.cs
- FullTextState.cs
- HttpEncoder.cs
- Baml2006ReaderSettings.cs
- RootAction.cs
- PathData.cs
- PreviewPrintController.cs
- AbstractDataSvcMapFileLoader.cs
- SubclassTypeValidator.cs
- CompilerCollection.cs
- WebPartsPersonalization.cs
- LinqExpressionNormalizer.cs
- HtmlTableRow.cs
- TextCompositionManager.cs
- peersecuritysettings.cs
- BooleanStorage.cs
- CharacterMetrics.cs
- Domain.cs
- BamlStream.cs
- SerializableTypeCodeDomSerializer.cs
- CompositeCollectionView.cs
- RoleExceptions.cs
- IBuiltInEvidence.cs
- brushes.cs
- SerializeAbsoluteContext.cs
- Version.cs