Click here to Skip to main content
12,627,681 members (33,104 online)
Click here to Skip to main content

Stats

72.1K views
907 downloads
49 bookmarked
Posted

Lock Manager for .NET

, 11 Aug 2003
Deadlock resolver for muti-threading applications.
Free
bin
LockManager.csproj.user
obj
Step1
App.ico
bin
obj
Step1.csproj.user
Step2
App.ico
bin
obj
Step2.csproj.user
Step3
App.ico
bin
obj
Step3.csproj.user
Step4
App.ico
bin
obj
Step4.csproj.user
Step5
App.ico
bin
obj
Step5.csproj.user
ThreeObjectsTest
App.ico
bin
obj
ThreeObjectsTest.csproj.user
/// <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;
using System.IO;

class ThreeObjectsTest
{
	// If you set NUMBER_OF_THREADS to a big value and NUMBER_OF_SYNC_OBJECTS to a small value
	// (for example NUMBER_OF_THREADS = 20; NUMBER_OF_SYNC_OBJECTS = 2; - may be you need other values
	// - different computers behave differently), you'll probably face a deadlock of a very interesting
	// type. LockManager will continuously interrupt wrong thread, which will always be replaced by the
	// similar one, repeating deadlock again and again without any progress.
	// This bug was fixed in version 2.0. However, I don't distribute version 2 freely. I have spent a lot
	// of time debuging and fixing various type of deadlocks, and I feel, I need some compensation for my work.
	// Contact me at szotin@shaw.ca if you need better version of LockManager.
	private const int NUMBER_OF_THREADS = 3;
	private const int NUMBER_OF_SYNC_OBJECTS = 3;
	private const int LOOP_ITTERATIONS = 20;

	// 0 - no log; 1 - console; 2 - file "deadlock.log"
	private const int LOG_TO = 1;

	private class ThreadClass
	{
		private static object m_go = new Object();

		private object m_sync1;
		private object m_sync2;
		private Thread m_thread;

		public ThreadClass ( string name, object sync1, object sync2 )
		{
			m_sync1 = sync1;
			m_sync2 = sync2;
			m_thread = new Thread ( new ThreadStart ( Run ) );
			m_thread.Name = name;
			m_thread.Start();
		}

		public static void Go ()
		{
			lock ( m_go )
			{
				Monitor.PulseAll ( m_go );
			}
		}

		public void Join ()
		{
			m_thread.Join ();
		}

		private void Run ()
		{
			lock ( m_go )
			{
				Monitor.Wait ( m_go );
			}

			for ( int i = 0; i < LOOP_ITTERATIONS; i++ )
			{
				bool retry = true;
				bool printed = false;
				while ( retry )
				{
					retry = false;
					LockManager.Lock ( m_sync1 );
					if ( !printed )
					{
						System.Console.WriteLine ( "{0}: a.{1}", Thread.CurrentThread.Name, i + 1 );
						printed = true;
					}
				
					try
					{
						LockManager.Lock ( m_sync2 );
						try
						{
							System.Console.WriteLine ( "{0}: b.{1}", Thread.CurrentThread.Name, i + 1 );
						}
						finally
						{
							LockManager.Unlock ( m_sync2 );
						}
					}
					catch ( DeadlockException )
					{
						//System.Console.WriteLine ( "{0}: lock failed, retrying", Thread.CurrentThread.Name );
						Thread.Sleep ( 100 );
						retry = true;
					}
					finally
					{
						LockManager.Unlock ( m_sync1 );
					}
				}
			}
		}
	}
			
	public static void Main ( string[] args )
	{
		int logType = LOG_TO;
			
		switch ( logType )
		{
			case 1:
				LockManager.Log = System.Console.Out;
				break;
			case 2:
				LockManager.Log = new StreamWriter ( "deadlock.log", false );
				break;
		}

		System.Console.WriteLine ( "Initializing threads..." );

		string[] sync = new String[NUMBER_OF_SYNC_OBJECTS];
		for ( int i = 0; i < NUMBER_OF_SYNC_OBJECTS; i++ )
			sync[i] = "sync " + ( i + 1 );

		ThreadClass[] threads = new ThreadClass[NUMBER_OF_THREADS];
		int currentSyncObject = 0;
		for ( int i = 0; i < NUMBER_OF_THREADS; i++ )
		{
			int nextSyncObject = currentSyncObject + 1;
			if ( nextSyncObject >= NUMBER_OF_SYNC_OBJECTS )
				nextSyncObject = 0;
			object sync1 = sync[currentSyncObject];
			object sync2 = sync[nextSyncObject];
			currentSyncObject = nextSyncObject;

			threads[i] = new ThreadClass ( "Thread " + ( i + 1 ), sync1, sync2 );
		}

		System.Console.Write ( "Waiting 3 seconds while all the threads start" );
		for ( int i = 0; i < 3; i++ )
		{
			Thread.Sleep ( 1000 );
			System.Console.Write ( "." );
		}
		System.Console.WriteLine();

		System.Console.WriteLine ( "Starting..." );
		int start = Environment.TickCount;
		ThreadClass.Go();

		for ( int i = 0; i < NUMBER_OF_THREADS; i++ )
			threads[i].Join ();

		System.Console.WriteLine ( "{0} ms.", Environment.TickCount - start );

		// close the file if opened
		if ( logType == 2 )
		{
			TextWriter writer = LockManager.Log;
			LockManager.Log = null;
			writer.Flush ();
			writer.Close ();
		}

		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

Share

About the Author

SZotin
Canada Canada
No Biography provided

You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.161205.3 | Last Updated 12 Aug 2003
Article Copyright 2003 by SZotin
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid