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
- PropertyGroupDescription.cs
- TextModifier.cs
- HwndSourceKeyboardInputSite.cs
- SynchronizedDispatch.cs
- XmlSchemaValidator.cs
- MaterializeFromAtom.cs
- StylusTip.cs
- OdbcCommand.cs
- DataGridView.cs
- LambdaCompiler.Unary.cs
- MergeFailedEvent.cs
- SQLBinary.cs
- VirtualizedContainerService.cs
- UserMapPath.cs
- CompressionTransform.cs
- ByeMessageApril2005.cs
- PenLineJoinValidation.cs
- ObjectListFieldsPage.cs
- SqlBulkCopy.cs
- LockCookie.cs
- Aes.cs
- MetadataArtifactLoaderFile.cs
- XmlDataContract.cs
- SafeLibraryHandle.cs
- RelationalExpressions.cs
- Stroke2.cs
- WindowsFormsSectionHandler.cs
- SqlDataSource.cs
- Win32SafeHandles.cs
- NullableIntMinMaxAggregationOperator.cs
- ToolStripItemDataObject.cs
- ToolStripGripRenderEventArgs.cs
- EntityDataSourceContainerNameItem.cs
- StringUtil.cs
- NavigationProgressEventArgs.cs
- CodeDirectoryCompiler.cs
- XmlNavigatorStack.cs
- SqlNodeTypeOperators.cs
- PropertyPathWorker.cs
- TabControlEvent.cs
- Accessible.cs
- altserialization.cs
- x509store.cs
- ToolStripDesignerAvailabilityAttribute.cs
- SystemIPAddressInformation.cs
- InputBinding.cs
- WebEvents.cs
- returneventsaver.cs
- TypeTypeConverter.cs
- DataList.cs
- MD5CryptoServiceProvider.cs
- DynamicRenderer.cs
- EntityDataSourceSelectedEventArgs.cs
- RayMeshGeometry3DHitTestResult.cs
- SqlBulkCopyColumnMappingCollection.cs
- SecurityTokenSerializer.cs
- XsdCachingReader.cs
- BooleanSwitch.cs
- DelayedRegex.cs
- CellConstant.cs
- NonSerializedAttribute.cs
- TemplateEditingFrame.cs
- CharStorage.cs
- DragEventArgs.cs
- WebColorConverter.cs
- DesignerActionMethodItem.cs
- MonitoringDescriptionAttribute.cs
- BamlCollectionHolder.cs
- Avt.cs
- HitTestParameters.cs
- Point.cs
- DocumentGridContextMenu.cs
- XmlException.cs
- MapPathBasedVirtualPathProvider.cs
- SoapFault.cs
- ComboBox.cs
- CngAlgorithm.cs
- _BufferOffsetSize.cs
- Operator.cs
- AutoGeneratedField.cs
- PeerResolverElement.cs
- EnumConverter.cs
- TreeNode.cs
- datacache.cs
- SecureConversationServiceElement.cs
- SwitchAttribute.cs
- MobileControlDesigner.cs
- PageContentAsyncResult.cs
- EntityStoreSchemaFilterEntry.cs
- XmlHierarchyData.cs
- GridViewColumnCollection.cs
- TripleDES.cs
- LayoutManager.cs
- InheritanceContextHelper.cs
- DataServiceConfiguration.cs
- SemanticBasicElement.cs
- MemoryPressure.cs
- CallSiteHelpers.cs
- CounterSample.cs
- SqlCacheDependency.cs