Click here to Skip to main content
15,886,724 members
Articles / Programming Languages / C#

Lock Manager for .NET

Rate me:
Please Sign up or sign in to vote.
3.57/5 (10 votes)
11 Aug 200313 min read 83.5K   1K   50  
Deadlock resolver for muti-threading applications.
/// <disclaimer>
/// This software is protected by your own conscience (c).
/// You can use it however you want and wherever you want.
/// You are allowed to change this code, copy this code, or delete this code.
/// You can buy this code; sell this code; present this code to your mom on her birthday.
/// You can replace author�s name with your own. You also can replace all the code with your own leaving
/// only author�s name.
/// The only thing you cannot do, is to violate this license agreement. You simply are not able to.
/// </disclaimer>
/// <author>
/// Sergei Zotin 
/// szotin@shaw.ca
/// Burnaby, BC, Canada
/// Feel free to contact me for bug reports, feature requests and contract offers.
/// </author>
/// <version>1.6</version>

using System;
using System.Threading;
using ZEN.Threading;

class A
{
	private B b;
	private int x;
	private int y;

	public B TheB
	{
		// NEW: We change all lock(this) to LockManager.Lock(this) to resolve deadlocks
		get
		{
			LockManager.Lock ( this );
			try
			{
				return b;
			}
			finally
			{
				LockManager.Unlock ( this );
			}
		}

		// NEW: We change all lock(this) to LockManager.Lock(this) to resolve deadlocks
		set
		{
			LockManager.Lock ( this );
			try
			{
				b = value;
			}
			finally
			{
				LockManager.Unlock ( this );
			}
		}
	}

	public int X
	{
		// NEW: We change all lock(this) to LockManager.Lock(this) to resolve deadlocks
		get
		{
			LockManager.Lock ( this );
			try
			{
				return x;
			}
			finally
			{
				LockManager.Unlock ( this );
			}
		}

		// NEW: We change all lock(this) to LockManager.Lock(this) to resolve deadlocks
		set
		{
			LockManager.Lock ( this );
			try
			{
				Thread.Sleep ( 10 ); // just to increase the odds of a deadlock
				x = value;
				b.X = value;
			}
			finally
			{
				LockManager.Unlock ( this );
			}
		}
	}

	public int Y
	{
		// NEW: We change all lock(this) to LockManager.Lock(this) to resolve deadlocks
		get
		{
			LockManager.Lock ( this );
			try
			{
				return y;
			}
			finally
			{
				LockManager.Unlock ( this );
			}
		}

		// NEW: We change all lock(this) to LockManager.Lock(this) to resolve deadlocks
		set
		{
			LockManager.Lock ( this );
			try
			{
				Thread.Sleep ( 10 ); // just to increase the odds of a deadlock
				y = value;
			}
			finally
			{
				LockManager.Unlock ( this );
			}
		}
	}
}

class B
{
	private A a;
	private int x;
	private int y;

	public A TheA
	{
		// NEW: We change all lock(this) to LockManager.Lock(this) to resolve deadlocks
		get
		{
			LockManager.Lock ( this );
			try
			{
				return a;
			}
			finally
			{
				LockManager.Unlock ( this );
			}
		}

		// NEW: We change all lock(this) to LockManager.Lock(this) to resolve deadlocks
		set
		{
			LockManager.Lock ( this );
			try
			{
				a = value;
			}
			finally
			{
				LockManager.Unlock ( this );
			}
		}
	}

	public int X
	{
		// NEW: We change all lock(this) to LockManager.Lock(this) to resolve deadlocks
		get
		{
			LockManager.Lock ( this );
			try
			{
				return x;
			}
			finally
			{
				LockManager.Unlock ( this );
			}
		}

		// NEW: We change all lock(this) to LockManager.Lock(this) to resolve deadlocks
		set
		{
			LockManager.Lock ( this );
			try
			{
				Thread.Sleep ( 10 ); // just to increase the odds of a deadlock
				x = value;
			}
			finally
			{
				LockManager.Unlock ( this );
			}
		}
	}

	public int Y
	{
		// NEW: We change all lock(this) to LockManager.Lock(this) to resolve deadlocks
		get
		{
			LockManager.Lock ( this );
			try
			{
				return y;
			}
			finally
			{
				LockManager.Unlock ( this );
			}
		}

		// NEW: We change all lock(this) to LockManager.Lock(this) to resolve deadlocks
		set
		{
			LockManager.Lock ( this );
			try
			{
				Thread.Sleep ( 10 ); // just to increase the odds of a deadlock
				y = value;
				a.Y = value;
			}
			finally
			{
				LockManager.Unlock ( this );
			}
		}
	}
}

class Step2
{
	private A a;
	private B b;

	private Step2 ( A _a, B _b )
	{
		a = _a;
		b = _b;
		a.TheB = b;
		b.TheA = a;
	}

	// NEW: Now we need to catch exceptions, because a.X = i may throw DeadlockException.
	private void RunX ()
	{
		try
		{
			for ( int i = 0; i < 20; i++ )
			{
				a.X = i;
				System.Console.WriteLine ( "Thread X: a.X={0}; b.X={1}", a.X, b.X );
			}
		}
		catch ( Exception exc )
		{
			System.Console.WriteLine ( "Fatal error in thread {0}: {1}", Thread.CurrentThread.Name, exc.Message );
		}
	}

	// NEW: Now we need to catch exceptions, because b.Y = i may throw DeadlockException.
	private void RunY ()
	{
		try
		{
			for ( int i = 0; i < 20; i++ )
			{
				b.Y = i;
				System.Console.WriteLine ( "Thread Y: a.Y={0}; b.Y={1}", a.Y, b.Y );
			}
		}
		catch ( Exception exc )
		{
			System.Console.WriteLine ( "Fatal error in thread {0}: {1}", Thread.CurrentThread.Name, exc.Message );
		}
	}

	[STAThread]
	static void Main ( string[] args )
	{
		A a = new A();
		B b = new B();
		Step2 step2 = new Step2 ( a, b );

		LockManager.Log = System.Console.Out;

		Thread threadX = new Thread ( new ThreadStart ( step2.RunX ) );
		Thread threadY = new Thread ( new ThreadStart ( step2.RunY ) );

		threadX.Name = "X";
		threadY.Name = "Y";

		threadX.Start ();
		threadY.Start ();

		threadX.Join ();
		threadY.Join ();

		System.Console.WriteLine ( "Press Enter..." );
		System.Console.In.Read();
		System.Environment.Exit ( 0 );
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions