Hi,
I'm trying to create a pair of NAnt tasks so that I can syncronize
access to shared resources when two builds are running concurrently.
I run the two builds, the first aquires the mutex properly, sleeps ten
seconds, then releases it properly.
The second build correctly blocks when it hits WaitOne, but then throws
an AbandonedMutexE xception when the first build calls ReleaseMutex.
The thing is, the thread doesn't seem to be abandoned.
Here's the code.
[TaskName( "aquireLock " )]
public class AquireLock : Task {
#region Fields
[ThreadStatic]
internal static Mutex mutex;
private string lockName;
#endregion
#region Properties
[TaskAttribute( "resourceNa me",
Required = true, ExpandPropertie s = true)]
public string LockName {
get { return lockName; }
set { lockName = value; }
}
#endregion
#region Task overrides
/// <summary>Execut es the task.</summary>
protected override void ExecuteTask() {
mutex = new Mutex( true, LockName );
Log(
Level.Info,
string.Format(
"Requesting lock: {0}, Thread {1}",
LockName,
AppDomain.GetCu rrentThreadId()
)
);
mutex.WaitOne() ;
Log(
Level.Info,
string.Format(
"Lock aquired: {0}, Thread {1}",
LockName,
AppDomain.GetCu rrentThreadId()
)
);
}
#endregion
}
[TaskName( "releaseLoc k" )]
public class ReleaseLock : Task {
#region Fields
private string lockName;
#endregion
#region Properties
[TaskAttribute( "resourceNa me",
Required = true, ExpandPropertie s = true )]
public string LockName {
get { return lockName; }
set { lockName = value; }
}
#endregion
#region Task overrides
/// <summary>Execut es the task.</summary>
protected override void ExecuteTask() {
if ( AquireLock.mute x == null ) {
Log( Level.Error, "No lock found" );
}
else {
using ( AquireLock.mute x ) {
Log(
Level.Info,
string.Format(
"Releasing lock: {0}, Thread {1}",
LockName,
AppDomain.GetCu rrentThreadId()
)
);
AquireLock.mute x.ReleaseMutex( );
Log(
Level.Info,
string.Format(
"Lock released: {0}, Thread {1}",
LockName,
AppDomain.GetCu rrentThreadId()
)
);
}
}
}
#endregion
}
Here's the build:
<?xml version="1.0" encoding="utf-8"?>
<project default="main" xmlns="http://nant.sf.net/schemas/nant.xsd"
name="Test">
<target name="main">
<loadtasks assembly="Med.N Ant.Extensions. dll" />
<aquireLock resourceName="T est" />
<sleep seconds="10"/>
<releaseLock resourceName="T est" />
</target>
</project>
I'm trying to create a pair of NAnt tasks so that I can syncronize
access to shared resources when two builds are running concurrently.
I run the two builds, the first aquires the mutex properly, sleeps ten
seconds, then releases it properly.
The second build correctly blocks when it hits WaitOne, but then throws
an AbandonedMutexE xception when the first build calls ReleaseMutex.
The thing is, the thread doesn't seem to be abandoned.
Here's the code.
[TaskName( "aquireLock " )]
public class AquireLock : Task {
#region Fields
[ThreadStatic]
internal static Mutex mutex;
private string lockName;
#endregion
#region Properties
[TaskAttribute( "resourceNa me",
Required = true, ExpandPropertie s = true)]
public string LockName {
get { return lockName; }
set { lockName = value; }
}
#endregion
#region Task overrides
/// <summary>Execut es the task.</summary>
protected override void ExecuteTask() {
mutex = new Mutex( true, LockName );
Log(
Level.Info,
string.Format(
"Requesting lock: {0}, Thread {1}",
LockName,
AppDomain.GetCu rrentThreadId()
)
);
mutex.WaitOne() ;
Log(
Level.Info,
string.Format(
"Lock aquired: {0}, Thread {1}",
LockName,
AppDomain.GetCu rrentThreadId()
)
);
}
#endregion
}
[TaskName( "releaseLoc k" )]
public class ReleaseLock : Task {
#region Fields
private string lockName;
#endregion
#region Properties
[TaskAttribute( "resourceNa me",
Required = true, ExpandPropertie s = true )]
public string LockName {
get { return lockName; }
set { lockName = value; }
}
#endregion
#region Task overrides
/// <summary>Execut es the task.</summary>
protected override void ExecuteTask() {
if ( AquireLock.mute x == null ) {
Log( Level.Error, "No lock found" );
}
else {
using ( AquireLock.mute x ) {
Log(
Level.Info,
string.Format(
"Releasing lock: {0}, Thread {1}",
LockName,
AppDomain.GetCu rrentThreadId()
)
);
AquireLock.mute x.ReleaseMutex( );
Log(
Level.Info,
string.Format(
"Lock released: {0}, Thread {1}",
LockName,
AppDomain.GetCu rrentThreadId()
)
);
}
}
}
#endregion
}
Here's the build:
<?xml version="1.0" encoding="utf-8"?>
<project default="main" xmlns="http://nant.sf.net/schemas/nant.xsd"
name="Test">
<target name="main">
<loadtasks assembly="Med.N Ant.Extensions. dll" />
<aquireLock resourceName="T est" />
<sleep seconds="10"/>
<releaseLock resourceName="T est" />
</target>
</project>
Comment