BreakSafeBase.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / RunTime / DebugEngine / BreakSafeBase.cs / 1305376 / BreakSafeBase.cs

                            // Copyright (c) Microsoft Corp., 2004. All rights reserved. 
#region Using directives

using System;
using System.Threading; 

#endregion 
 
namespace System.Workflow.Runtime.DebugEngine
{ 
 	//
	// IMPORTANT: Do not edit this file without consulting Break Safe Synchronization.doc!
	//
	internal abstract class BreakSafeBase where T: ICloneable, new() 
 	{
		#region Data members 
 
 		private volatile object currentData;					// object because type parameters instances cannot be volatile.
 		private T nonEEDataClone; 
		private volatile bool nonEEDataConsistent;
 		private volatile bool nonEEIgnoreUpdate;
		private Mutex nonEELock;
		private object controllerUpdateObject; 
		private int controllerManagedThreadId;
 
 		#endregion 

		#region Methods and properties 

 		protected BreakSafeBase(int controllerManagedThreadId)
 		{
			this.currentData = new T(); 
 			this.nonEEDataClone = default(T);
			this.nonEEDataConsistent = false; 
			this.nonEEIgnoreUpdate = false; 
			this.nonEELock = new Mutex(false);
 			this.controllerManagedThreadId = controllerManagedThreadId; 
		}

 		private bool IsEECall
 		{ 
			get
 			{ 
				return Thread.CurrentThread.ManagedThreadId == this.controllerManagedThreadId; 
			}
		} 

 		protected object GetControllerUpdateObject()
		{
 			return this.controllerUpdateObject; 
 		}
 
		protected void SetControllerUpdateObject(object updateObject) 
 		{
			// Ensure that the access to the variable this.controllerUpdateObject is exactly one instruction - StFld in this case. 
			this.controllerUpdateObject = updateObject;
		}

 		protected T GetReaderData() 
		{
 			// Ensure that the access to the variable this.currentData is exactly one instruction - LdFld in this case. 
 			object data = this.currentData; 
			return (T)data;
 		} 

		protected T GetWriterData()
		{
			if (IsEECall) 
 			{
				if (this.nonEEDataConsistent && this.nonEEIgnoreUpdate == false) 
 				{ 
 					// Modify the object referred to by this.currentData directly.
					return (T) this.currentData; 
 				}
				else
				{
					// Clone and discard any non-EE update. 
 					this.nonEEIgnoreUpdate = true;
					return (T)((T)this.currentData).Clone(); 
 				} 
 			}
			else 
 			{
				// Reset the flag so that we can keep track of any concurrent EE updates.
				this.nonEEIgnoreUpdate = false;
 
				// Ensure that the access to the variable this.currentData is exactly one instruction - LdFld in this case.
 				object data = this.currentData; 
				return (T)((T)data).Clone(); 
 			}
 		} 

		protected void SaveData(T data)
 		{
			if (IsEECall) 
				this.currentData = data;
			else 
 			{ 
				// The non-EE clone is now in a consistent state.
 				this.nonEEDataClone = data; 
 				this.nonEEDataConsistent = true;

				this.controllerUpdateObject = null;
 
 				// If an EE call has already modified the data, it would have also performed current non-EE update
				// when the debugger entered break mode. So discard the update. Asl ensure that the access to the 
				// variable this.currentData is exactly one instruction - StFld in this case. 
				if (this.nonEEIgnoreUpdate == false)
 					this.currentData = data; 

				// Clear the flag because we will clear the this.nonEEDataClone.
 				this.nonEEDataConsistent = false;
 				this.nonEEDataClone = default(T); 
			}
 		} 
 
		protected void Lock()
		{ 
			// Serialize non-EE calls and do not invoke synchronization primitives during FuncEval.
 			if (!IsEECall)
				this.nonEELock.WaitOne();
 		} 

 		protected void Unlock() 
		{ 
 			// Serialize non-EE calls and do not invoke synchronization primitives during FuncEval.
			if (!IsEECall) 
				this.nonEELock.ReleaseMutex();
		}

 		#endregion 
	}
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corp., 2004. All rights reserved. 
#region Using directives

using System;
using System.Threading; 

#endregion 
 
namespace System.Workflow.Runtime.DebugEngine
{ 
 	//
	// IMPORTANT: Do not edit this file without consulting Break Safe Synchronization.doc!
	//
	internal abstract class BreakSafeBase where T: ICloneable, new() 
 	{
		#region Data members 
 
 		private volatile object currentData;					// object because type parameters instances cannot be volatile.
 		private T nonEEDataClone; 
		private volatile bool nonEEDataConsistent;
 		private volatile bool nonEEIgnoreUpdate;
		private Mutex nonEELock;
		private object controllerUpdateObject; 
		private int controllerManagedThreadId;
 
 		#endregion 

		#region Methods and properties 

 		protected BreakSafeBase(int controllerManagedThreadId)
 		{
			this.currentData = new T(); 
 			this.nonEEDataClone = default(T);
			this.nonEEDataConsistent = false; 
			this.nonEEIgnoreUpdate = false; 
			this.nonEELock = new Mutex(false);
 			this.controllerManagedThreadId = controllerManagedThreadId; 
		}

 		private bool IsEECall
 		{ 
			get
 			{ 
				return Thread.CurrentThread.ManagedThreadId == this.controllerManagedThreadId; 
			}
		} 

 		protected object GetControllerUpdateObject()
		{
 			return this.controllerUpdateObject; 
 		}
 
		protected void SetControllerUpdateObject(object updateObject) 
 		{
			// Ensure that the access to the variable this.controllerUpdateObject is exactly one instruction - StFld in this case. 
			this.controllerUpdateObject = updateObject;
		}

 		protected T GetReaderData() 
		{
 			// Ensure that the access to the variable this.currentData is exactly one instruction - LdFld in this case. 
 			object data = this.currentData; 
			return (T)data;
 		} 

		protected T GetWriterData()
		{
			if (IsEECall) 
 			{
				if (this.nonEEDataConsistent && this.nonEEIgnoreUpdate == false) 
 				{ 
 					// Modify the object referred to by this.currentData directly.
					return (T) this.currentData; 
 				}
				else
				{
					// Clone and discard any non-EE update. 
 					this.nonEEIgnoreUpdate = true;
					return (T)((T)this.currentData).Clone(); 
 				} 
 			}
			else 
 			{
				// Reset the flag so that we can keep track of any concurrent EE updates.
				this.nonEEIgnoreUpdate = false;
 
				// Ensure that the access to the variable this.currentData is exactly one instruction - LdFld in this case.
 				object data = this.currentData; 
				return (T)((T)data).Clone(); 
 			}
 		} 

		protected void SaveData(T data)
 		{
			if (IsEECall) 
				this.currentData = data;
			else 
 			{ 
				// The non-EE clone is now in a consistent state.
 				this.nonEEDataClone = data; 
 				this.nonEEDataConsistent = true;

				this.controllerUpdateObject = null;
 
 				// If an EE call has already modified the data, it would have also performed current non-EE update
				// when the debugger entered break mode. So discard the update. Asl ensure that the access to the 
				// variable this.currentData is exactly one instruction - StFld in this case. 
				if (this.nonEEIgnoreUpdate == false)
 					this.currentData = data; 

				// Clear the flag because we will clear the this.nonEEDataClone.
 				this.nonEEDataConsistent = false;
 				this.nonEEDataClone = default(T); 
			}
 		} 
 
		protected void Lock()
		{ 
			// Serialize non-EE calls and do not invoke synchronization primitives during FuncEval.
 			if (!IsEECall)
				this.nonEELock.WaitOne();
 		} 

 		protected void Unlock() 
		{ 
 			// Serialize non-EE calls and do not invoke synchronization primitives during FuncEval.
			if (!IsEECall) 
				this.nonEELock.ReleaseMutex();
		}

 		#endregion 
	}
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

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