Strange behaviour of ReleaseMutex/NtReleaseMutant/KeReleaseMutant

Hello.

Actually I’m writing a user-mode application but we struck the sutuation when it can be kernel problem indeed.

Background: I’m writing a user-mode application that acts like a server for network redirector driver. The driver maps client requests to our custom protocol and sends them to the server. The server executes requets and sends requsts back. We may say that NtReadFile API call at the client side maps to corresponding NtReadFile API call at the server side. Other API calls are mapped in the same manner.

The server has thread pool based on I/O completion port. One of two functions may be executed when NtRemoveIoCompletion routine removes completion notification from the IOCP queue:

#define DEADLOCK_TIMEOUT 15000

void Func1()
{
DWORD waitResult = WAIT_FAILED;
do {
waitResult = WaitForSingleObjectEx(mutex1, DEADLOCK_TIMEOUT, TRUE);
} while (WAIT_IO_COMPLETION == waitResult);

if (WAIT_OBJECT_0 != waitResult)
{
// Deadlock, restart Func1
}

// Do something useful

ReleaseMutex(mutex1);
}
void Func2()
{
HANDLE handlesToWaitFor = { mutext1, mutex2 };

DWORD waitResult = WAIT_FAILED;
do {
waitResult =
WaitForMultipleObjectsEx(NUMBER_OF(handlesToWaitFor), handlesToWaitFor, TRUE, DEADLOCK_TIMEOUT, TRUE);
} while (WAIT_IO_COMPLETION == waitResult);

if (WAIT_OBJECT_0 != waitResult)
{
// Deadlock, restart Func2
}

// Do something useful (1)

ReleaseMutex(mutex2);

// Do something useful (2)

ReleaseMutex(mutex1);
}

Note that at “Do something useful (2)” point threads may call NtReadFile/NtWriteFile/NtQueryDirectoryFile rountines in asynchronous mode BUT completion of operations are reported using IOCP notifications.

Two deadlock guards allow to restart requests if a thread will not be able to take mutex ownership. If it happed the failed request is returnted back to the IOCP queue by means of PostQueuedCompletionStatus call.

The problem: So the problem is that ReleaseMutex(mutex2) call in Func2 can take up to DEADLOCK_TIMEOUT milliseconds to execute. I tried several values for DEADLOCK_TIMEOUT. Each time ReleaseMutex call took either nanoseconds or DEADLOCK_TIMEOUT milliseconds (i.e. 10-15 seconds!). The situation is rare enough but absolutely unexplainable for me.

Also I can say that waiting in alertable state is redundunt for this case. I don’t issue any asynchronous call with APC callback and I never get WAIT_IO_COMPLETION result from any of my wait function calls.

BTW I was able to reproduce this only under Windows XP Professional on P4 with hyper-threading computer only. Windows 2000 and Windows 2003 works fine for me (on the same computer).

Does anyone encounter with long execution of ReleaseMutex/NtReleaseMutant? What can be the reason of it? Thanks for any help.

Best regards,
Alexey.

Why do you use 2 mutexes? Any need in this? Maybe use 1 and only 1 CRITICAL_SECTION instead?

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com

----- Original Message -----
From: Alexey Pakhunov
To: Windows System Software Devs Interest List
Sent: Tuesday, May 25, 2004 6:31 PM
Subject: [ntdev] Strange behaviour of ReleaseMutex/NtReleaseMutant/KeReleaseMutant

Hello.

Actually I'm writing a user-mode application but we struck the sutuation when it can be kernel problem indeed.

Background: I'm writing a user-mode application that acts like a server for network redirector driver. The driver maps client requests to our custom protocol and sends them to the server. The server executes requets and sends requsts back. We may say that NtReadFile API call at the client side maps to corresponding NtReadFile API call at the server side. Other API calls are mapped in the same manner.

The server has thread pool based on I/O completion port. One of two functions may be executed when NtRemoveIoCompletion routine removes completion notification from the IOCP queue:

#define DEADLOCK_TIMEOUT 15000

void Func1()
{
DWORD waitResult = WAIT_FAILED;
do {
waitResult = WaitForSingleObjectEx(mutex1, DEADLOCK_TIMEOUT, TRUE);
} while (WAIT_IO_COMPLETION == waitResult);

if (WAIT_OBJECT_0 != waitResult)
{
// Deadlock, restart Func1
}

// Do something useful

ReleaseMutex(mutex1);
}
void Func2()
{
HANDLE handlesToWaitFor = { mutext1, mutex2 };

DWORD waitResult = WAIT_FAILED;
do {
waitResult =
WaitForMultipleObjectsEx(NUMBER_OF(handlesToWaitFor), handlesToWaitFor, TRUE, DEADLOCK_TIMEOUT, TRUE);
} while (WAIT_IO_COMPLETION == waitResult);

if (WAIT_OBJECT_0 != waitResult)
{
// Deadlock, restart Func2
}

// Do something useful (1)

ReleaseMutex(mutex2);

// Do something useful (2)

ReleaseMutex(mutex1);
}

Note that at "Do something useful (2)" point threads may call NtReadFile/NtWriteFile/NtQueryDirectoryFile rountines in asynchronous mode BUT completion of operations are reported using IOCP notifications.

Two deadlock guards allow to restart requests if a thread will not be able to take mutex ownership. If it happed the failed request is returnted back to the IOCP queue by means of PostQueuedCompletionStatus call.

The problem: So the problem is that ReleaseMutex(mutex2) call in Func2 can take up to DEADLOCK_TIMEOUT milliseconds to execute. I tried several values for DEADLOCK_TIMEOUT. Each time ReleaseMutex call took either nanoseconds or DEADLOCK_TIMEOUT milliseconds (i.e. 10-15 seconds!). The situation is rare enough but absolutely unexplainable for me.

Also I can say that waiting in alertable state is redundunt for this case. I don't issue any asynchronous call with APC callback and I never get WAIT_IO_COMPLETION result from any of my wait function calls.

BTW I was able to reproduce this only under Windows XP Professional on P4 with hyper-threading computer only. Windows 2000 and Windows 2003 works fine for me (on the same computer).

Does anyone encounter with long execution of ReleaseMutex/NtReleaseMutant? What can be the reason of it? Thanks for any help.

Best regards,
Alexey.

Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@storagecraft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Also how many threads are there in pool. All are in same priority?.
And this problem occur in any special case, I mean in higher load (or happen even with single connection) ?.

After completing the wait the other thread will get priority boost, but don't think this is because of that.

----- Original Message -----
From: Maxim S. Shatskih
To: Windows System Software Devs Interest List
Sent: Tuesday, May 25, 2004 9:24 PM
Subject: Re: [ntdev] Strange behaviour of ReleaseMutex/NtReleaseMutant/KeReleaseMutant

Why do you use 2 mutexes? Any need in this? Maybe use 1 and only 1 CRITICAL_SECTION instead?

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

----- Original Message -----
From: Alexey Pakhunov
To: Windows System Software Devs Interest List
Sent: Tuesday, May 25, 2004 6:31 PM
Subject: [ntdev] Strange behaviour of ReleaseMutex/NtReleaseMutant/KeReleaseMutant

Hello.

Actually I'm writing a user-mode application but we struck the sutuation when it can be kernel problem indeed.

Background: I'm writing a user-mode application that acts like a server for network redirector driver. The driver maps client requests to our custom protocol and sends them to the server. The server executes requets and sends requsts back. We may say that NtReadFile API call at the client side maps to corresponding NtReadFile API call at the server side. Other API calls are mapped in the same manner.

The server has thread pool based on I/O completion port. One of two functions may be executed when NtRemoveIoCompletion routine removes completion notification from the IOCP queue:

#define DEADLOCK_TIMEOUT 15000

void Func1()
{
DWORD waitResult = WAIT_FAILED;
do {
waitResult = WaitForSingleObjectEx(mutex1, DEADLOCK_TIMEOUT, TRUE);
} while (WAIT_IO_COMPLETION == waitResult);

if (WAIT_OBJECT_0 != waitResult)
{
// Deadlock, restart Func1
}

// Do something useful

ReleaseMutex(mutex1);
}
void Func2()
{
HANDLE handlesToWaitFor = { mutext1, mutex2 };

DWORD waitResult = WAIT_FAILED;
do {
waitResult =
WaitForMultipleObjectsEx(NUMBER_OF(handlesToWaitFor), handlesToWaitFor, TRUE, DEADLOCK_TIMEOUT, TRUE);
} while (WAIT_IO_COMPLETION == waitResult);

if (WAIT_OBJECT_0 != waitResult)
{
// Deadlock, restart Func2
}

// Do something useful (1)

ReleaseMutex(mutex2);

// Do something useful (2)

ReleaseMutex(mutex1);
}

Note that at "Do something useful (2)" point threads may call NtReadFile/NtWriteFile/NtQueryDirectoryFile rountines in asynchronous mode BUT completion of operations are reported using IOCP notifications.

Two deadlock guards allow to restart requests if a thread will not be able to take mutex ownership. If it happed the failed request is returnted back to the IOCP queue by means of PostQueuedCompletionStatus call.

The problem: So the problem is that ReleaseMutex(mutex2) call in Func2 can take up to DEADLOCK_TIMEOUT milliseconds to execute. I tried several values for DEADLOCK_TIMEOUT. Each time ReleaseMutex call took either nanoseconds or DEADLOCK_TIMEOUT milliseconds (i.e. 10-15 seconds!). The situation is rare enough but absolutely unexplainable for me.

Also I can say that waiting in alertable state is redundunt for this case. I don't issue any asynchronous call with APC callback and I never get WAIT_IO_COMPLETION result from any of my wait function calls.

BTW I was able to reproduce this only under Windows XP Professional on P4 with hyper-threading computer only. Windows 2000 and Windows 2003 works fine for me (on the same computer).

Does anyone encounter with long execution of ReleaseMutex/NtReleaseMutant? What can be the reason of it? Thanks for any help.

Best regards,
Alexey.

Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@storagecraft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@calsoftinc.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Maxim,

Two reasons:

  1. We used critical sections instead of mutexes when we encounter with this problem for the 1st time. Mutexes allow us to implement "deadlock protection" mechanism. I mean restarting of locked request.

BTW now I can conclude that ReleaseMutex and SetEvent called by LeaveCriticalSection behave in the same way in this case. Well I cannot say this for sure but it seems to be so.

  1. Two mutextes protects different resources. 'mutex1' protects requests queue. 'mutex2' perform ordering of requests (they should be executed in FIFO manner) as well as protects other resources during execution. Using two mutextes allows to avoid unnecessary locking of requests queue during execution of requests at "Do something useful (2)" point. In other words this allows to send/receive something while executing pending.

Best regards,
Alexey.
----- Original Message -----
From: Maxim S. Shatskih
To: Windows System Software Devs Interest List
Sent: Tuesday, May 25, 2004 6:54 PM
Subject: Re: [ntdev] Strange behaviour of ReleaseMutex/NtReleaseMutant/KeReleaseMutant

Why do you use 2 mutexes? Any need in this? Maybe use 1 and only 1 CRITICAL_SECTION instead?

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

----- Original Message -----
From: Alexey Pakhunov
To: Windows System Software Devs Interest List
Sent: Tuesday, May 25, 2004 6:31 PM
Subject: [ntdev] Strange behaviour of ReleaseMutex/NtReleaseMutant/KeReleaseMutant

Hello.

Actually I'm writing a user-mode application but we struck the sutuation when it can be kernel problem indeed.

Background: I'm writing a user-mode application that acts like a server for network redirector driver. The driver maps client requests to our custom protocol and sends them to the server. The server executes requets and sends requsts back. We may say that NtReadFile API call at the client side maps to corresponding NtReadFile API call at the server side. Other API calls are mapped in the same manner.

The server has thread pool based on I/O completion port. One of two functions may be executed when NtRemoveIoCompletion routine removes completion notification from the IOCP queue:

#define DEADLOCK_TIMEOUT 15000

void Func1()
{
DWORD waitResult = WAIT_FAILED;
do {
waitResult = WaitForSingleObjectEx(mutex1, DEADLOCK_TIMEOUT, TRUE);
} while (WAIT_IO_COMPLETION == waitResult);

if (WAIT_OBJECT_0 != waitResult)
{
// Deadlock, restart Func1
}

// Do something useful

ReleaseMutex(mutex1);
}
void Func2()
{
HANDLE handlesToWaitFor = { mutext1, mutex2 };

DWORD waitResult = WAIT_FAILED;
do {
waitResult =
WaitForMultipleObjectsEx(NUMBER_OF(handlesToWaitFor), handlesToWaitFor, TRUE, DEADLOCK_TIMEOUT, TRUE);
} while (WAIT_IO_COMPLETION == waitResult);

if (WAIT_OBJECT_0 != waitResult)
{
// Deadlock, restart Func2
}

// Do something useful (1)

ReleaseMutex(mutex2);

// Do something useful (2)

ReleaseMutex(mutex1);
}

Note that at "Do something useful (2)" point threads may call NtReadFile/NtWriteFile/NtQueryDirectoryFile rountines in asynchronous mode BUT completion of operations are reported using IOCP notifications.

Two deadlock guards allow to restart requests if a thread will not be able to take mutex ownership. If it happed the failed request is returnted back to the IOCP queue by means of PostQueuedCompletionStatus call.

The problem: So the problem is that ReleaseMutex(mutex2) call in Func2 can take up to DEADLOCK_TIMEOUT milliseconds to execute. I tried several values for DEADLOCK_TIMEOUT. Each time ReleaseMutex call took either nanoseconds or DEADLOCK_TIMEOUT milliseconds (i.e. 10-15 seconds!). The situation is rare enough but absolutely unexplainable for me.

Also I can say that waiting in alertable state is redundunt for this case. I don't issue any asynchronous call with APC callback and I never get WAIT_IO_COMPLETION result from any of my wait function calls.

BTW I was able to reproduce this only under Windows XP Professional on P4 with hyper-threading computer only. Windows 2000 and Windows 2003 works fine for me (on the same computer).

Does anyone encounter with long execution of ReleaseMutex/NtReleaseMutant? What can be the reason of it? Thanks for any help.

Best regards,
Alexey.

Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@storagecraft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@cooldev.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Hello,

Also how many threads are there in pool.

“Richter” rule - 2 * number of processors. In my case 4 worker threads on HT machine. I don’t dinamically change number of thread depending on load.

All are in same priority?.

Exactly.

And this problem occur in any special case, I mean in higher load (or happen even with single connection) ?.

It occurs in higher load.

Best regards,
Alexey.
----- Original Message -----
From: Sisimon
To: Windows System Software Devs Interest List
Sent: Tuesday, May 25, 2004 7:15 PM
Subject: Re: [ntdev] Strange behaviour of ReleaseMutex/NtReleaseMutant/KeReleaseMutant

Also how many threads are there in pool. All are in same priority?.
And this problem occur in any special case, I mean in higher load (or happen even with single connection) ?.

After completing the wait the other thread will get priority boost, but don’t think this is because of that.

----- Original Message -----
From: Maxim S. Shatskih
To: Windows System Software Devs Interest List
Sent: Tuesday, May 25, 2004 9:24 PM
Subject: Re: [ntdev] Strange behaviour of ReleaseMutex/NtReleaseMutant/KeReleaseMutant

Why do you use 2 mutexes? Any need in this? Maybe use 1 and only 1 CRITICAL_SECTION instead?

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

I can’t think of any reason at all why a ReleaseMutex() should block. It is not a comforting thought.

I have never used WaitFormMultipleObjects to acquire two mutexes at the same time (bWaitAll = TRUE) and it bothers me a little - is there a possibility that the mutexes could be acquired in different order by different threads causing deadlocks ?

-tz

“Alexey Pakhunov” wrote in message news:xxxxx@ntdev…
Hello.

Actually I’m writing a user-mode application but we struck the sutuation when it can be kernel problem indeed.

Background: I’m writing a user-mode application that acts like a server for network redirector driver. The driver maps client requests to our custom protocol and sends them to the server. The server executes requets and sends requsts back. We may say that NtReadFile API call at the client side maps to corresponding NtReadFile API call at the server side. Other API calls are mapped in the same manner.

The server has thread pool based on I/O completion port. One of two functions may be executed when NtRemoveIoCompletion routine removes completion notification from the IOCP queue:

#define DEADLOCK_TIMEOUT 15000

void Func1()
{
DWORD waitResult = WAIT_FAILED;
do {
waitResult = WaitForSingleObjectEx(mutex1, DEADLOCK_TIMEOUT, TRUE);
} while (WAIT_IO_COMPLETION == waitResult);

if (WAIT_OBJECT_0 != waitResult)
{
// Deadlock, restart Func1
}

// Do something useful

ReleaseMutex(mutex1);
}
void Func2()
{
HANDLE handlesToWaitFor = { mutext1, mutex2 };

DWORD waitResult = WAIT_FAILED;
do {
waitResult =
WaitForMultipleObjectsEx(NUMBER_OF(handlesToWaitFor), handlesToWaitFor, TRUE, DEADLOCK_TIMEOUT, TRUE);
} while (WAIT_IO_COMPLETION == waitResult);

if (WAIT_OBJECT_0 != waitResult)
{
// Deadlock, restart Func2
}

// Do something useful (1)

ReleaseMutex(mutex2);

// Do something useful (2)

ReleaseMutex(mutex1);
}

Note that at “Do something useful (2)” point threads may call NtReadFile/NtWriteFile/NtQueryDirectoryFile rountines in asynchronous mode BUT completion of operations are reported using IOCP notifications.

Two deadlock guards allow to restart requests if a thread will not be able to take mutex ownership. If it happed the failed request is returnted back to the IOCP queue by means of PostQueuedCompletionStatus call.

The problem: So the problem is that ReleaseMutex(mutex2) call in Func2 can take up to DEADLOCK_TIMEOUT milliseconds to execute. I tried several values for DEADLOCK_TIMEOUT. Each time ReleaseMutex call took either nanoseconds or DEADLOCK_TIMEOUT milliseconds (i.e. 10-15 seconds!). The situation is rare enough but absolutely unexplainable for me.

Also I can say that waiting in alertable state is redundunt for this case. I don’t issue any asynchronous call with APC callback and I never get WAIT_IO_COMPLETION result from any of my wait function calls.

BTW I was able to reproduce this only under Windows XP Professional on P4 with hyper-threading computer only. Windows 2000 and Windows 2003 works fine for me (on the same computer).

Does anyone encounter with long execution of ReleaseMutex/NtReleaseMutant? What can be the reason of it? Thanks for any help.

Best regards,
Alexey.

WaitForMultipleObjects with bWaitAll ensures that all of the mutexes are
acquired at once or that none of them are. It does not acquire each
mutex individually and then wait for the others so you don’t need to
worry about the order it acquires locks in.

-p


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tzvetan Mikov
Sent: Tuesday, May 25, 2004 11:58 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Strange behaviour of
ReleaseMutex/NtReleaseMutant/KeReleaseMutant

I can’t think of any reason at all why a ReleaseMutex() should block. It
is not a comforting thought.

I have never used WaitFormMultipleObjects to acquire two mutexes at the
same time (bWaitAll = TRUE) and it bothers me a little - is there a
possibility that the mutexes could be acquired in different order by
different threads causing deadlocks ?

-tz

“Alexey Pakhunov” wrote in message
news:xxxxx@ntdev…
Hello.

Actually I’m writing a user-mode application but we struck the
sutuation when it can be kernel problem indeed.

Background: I’m writing a user-mode application that acts like a
server for network redirector driver. The driver maps client requests to
our custom protocol and sends them to the server. The server executes
requets and sends requsts back. We may say that NtReadFile API call at
the client side maps to corresponding NtReadFile API call at the server
side. Other API calls are mapped in the same manner.

The server has thread pool based on I/O completion port. One of
two functions may be executed when NtRemoveIoCompletion routine removes
completion notification from the IOCP queue:

#define DEADLOCK_TIMEOUT 15000

void Func1()
{
DWORD waitResult = WAIT_FAILED;
do {
waitResult = WaitForSingleObjectEx(mutex1,
DEADLOCK_TIMEOUT, TRUE);
} while (WAIT_IO_COMPLETION == waitResult);

if (WAIT_OBJECT_0 != waitResult)
{
// Deadlock, restart Func1
}

// Do something useful

ReleaseMutex(mutex1);
}
void Func2()
{
HANDLE handlesToWaitFor = { mutext1, mutex2 };

DWORD waitResult = WAIT_FAILED;
do {
waitResult =

WaitForMultipleObjectsEx(NUMBER_OF(handlesToWaitFor), handlesToWaitFor,
TRUE, DEADLOCK_TIMEOUT, TRUE);
} while (WAIT_IO_COMPLETION == waitResult);

if (WAIT_OBJECT_0 != waitResult)
{
// Deadlock, restart Func2
}

// Do something useful (1)

ReleaseMutex(mutex2);

// Do something useful (2)

ReleaseMutex(mutex1);
}

Note that at “Do something useful (2)” point threads may call
NtReadFile/NtWriteFile/NtQueryDirectoryFile rountines in asynchronous
mode BUT completion of operations are reported using IOCP notifications.

Two deadlock guards allow to restart requests if a thread will
not be able to take mutex ownership. If it happed the failed request is
returnted back to the IOCP queue by means of PostQueuedCompletionStatus
call.

The problem: So the problem is that ReleaseMutex(mutex2) call in
Func2 can take up to DEADLOCK_TIMEOUT milliseconds to execute. I tried
several values for DEADLOCK_TIMEOUT. Each time ReleaseMutex call took
either nanoseconds or DEADLOCK_TIMEOUT milliseconds (i.e. 10-15
seconds!). The situation is rare enough but absolutely unexplainable for
me.

Also I can say that waiting in alertable state is redundunt for
this case. I don’t issue any asynchronous call with APC callback and I
never get WAIT_IO_COMPLETION result from any of my wait function calls.

BTW I was able to reproduce this only under Windows XP
Professional on P4 with hyper-threading computer only. Windows 2000 and
Windows 2003 works fine for me (on the same computer).

Does anyone encounter with long execution of
ReleaseMutex/NtReleaseMutant? What can be the reason of it? Thanks for
any help.

Best regards,
Alexey.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

> I have never used WaitFormMultipleObjects to acquire two mutexes at the same time

(bWaitAll = TRUE) and it bothers me a little - is there a possibility that the
mutexes could be acquired in different order by different threads causing deadlocks ?

Well, I guess it should not influence somehow. Func2 is the only place where I use mutex2. Func1 and Func2 are only functions that use mutex1. bWaitAll just guarantee that either both mutexes or none of them will be acquired.


Best regards,
Alexey.
“Tzvetan Mikov” wrote in message news:…
I can’t think of any reason at all why a ReleaseMutex() should block. It is not a comforting thought.

I have never used WaitFormMultipleObjects to acquire two mutexes at the same time (bWaitAll = TRUE) and it bothers me a little - is there a possibility that the mutexes could be acquired in different order by different threads causing deadlocks ?

-tz

> WaitForMultipleObjects with bWaitAll ensures that all of the mutexes are

acquired at once or that none of them are. It does not acquire each
mutex individually and then wait for the others so you don’t need to
worry about the order it acquires locks in.

This is exactly what I wanted to tell but you do it better. Thanks. :slight_smile:

Best regards,
Alexey.

----- Original Message -----
From: “Peter Wieland”
To: “Windows System Software Devs Interest List”
Sent: Tuesday, May 25, 2004 10:08 PM
Subject: RE: [ntdev] Strange behaviour of
ReleaseMutex/NtReleaseMutant/KeReleaseMutant

WaitForMultipleObjects with bWaitAll ensures that all of the mutexes are
acquired at once or that none of them are. It does not acquire each
mutex individually and then wait for the others so you don’t need to
worry about the order it acquires locks in.

-p

________________________________

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tzvetan Mikov
Sent: Tuesday, May 25, 2004 11:58 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Strange behaviour of
ReleaseMutex/NtReleaseMutant/KeReleaseMutant

I can’t think of any reason at all why a ReleaseMutex() should block. It
is not a comforting thought.

I have never used WaitFormMultipleObjects to acquire two mutexes at the
same time (bWaitAll = TRUE) and it bothers me a little - is there a
possibility that the mutexes could be acquired in different order by
different threads causing deadlocks ?

-tz

In theory (but in theory ReleaseMutex should not block either :-).
I am refering to the non-standard (for me) lock hierarchy - two locks which can
sometimes be acquired separately, sometimes together, and are always released
separately. Would something like this work for you and would it exhibit the same
problem ?

Func2()
{
if (WaitForSingleObject( mutex1, DEADLOCK_TIMEOUT/2 ) != WAIT_OBJECT_0)
restart Func2;
if (WaitForSingleObject( mutex2, DEADLOCK_TIMEOUT/2 ) != WAIT_OBJECT_0)
{
ReleaseMutex( mutex1 );
restart Func2;
}
// Do something useful (1)
ReleaseMutex( mutex2 );
// Do something useful (2)
ReleaseMutex( mutex1 );
}

“Alexey Pakhunov” wrote in message news:xxxxx@ntdev…
> I have never used WaitFormMultipleObjects to acquire two mutexes at the same
time
> (bWaitAll = TRUE) and it bothers me a little - is there a possibility that the
> mutexes could be acquired in different order by different threads causing
deadlocks ?

Well, I guess it should not influence somehow. Func2 is the only place where I
use mutex2. Func1 and Func2 are only functions that use mutex1. bWaitAll just
guarantee that either both mutexes or none of them will be acquired.


Best regards,
Alexey.
“Tzvetan Mikov” wrote in message news:…
I can’t think of any reason at all why a ReleaseMutex() should block. It is not
a comforting thought.

I have never used WaitFormMultipleObjects to acquire two mutexes at the same
time (bWaitAll = TRUE) and it bothers me a little - is there a possibility that
the mutexes could be acquired in different order by different threads causing
deadlocks ?

-tz

Hello.

First of all I found a mistake in my original post. Func2 should look like following:

void Func2()
{
HANDLE handlesToWaitFor = { mutex1, mutex2 };

DWORD waitResult = WaitForMultipleObjects(NUMBER_OF(handlesToWaitFor), handlesToWaitFor, TRUE, DEADLOCK_TIMEOUT);
if (WAIT_OBJECT_0 != waitResult)
{
// Deadlock, restart Func2
}

// Do something useful (1)

ReleaseMutex(mutex1);

// Do something useful (2)

ReleaseMutex(mutex2);
}

In other words mutex1 which is also used by Func1 released first. Otherwise locking of two mutexes would be useless.

So I tried to acquire muexes separately as you offered and got the same problem. Func1 remains the same, the function Func2 looked so:

Func2()
{
if (WaitForSingleObject( mutex2, DEADLOCK_TIMEOUT/2 ) != WAIT_OBJECT_0)
restart Func2;
if (WaitForSingleObject( mutex1, DEADLOCK_TIMEOUT/2 ) != WAIT_OBJECT_0)
{
ReleaseMutex( mutex2 );
restart Func2;
}
// Do something useful (1)
ReleaseMutex( mutex1 );
// Do something useful (2)
ReleaseMutex( mutex2 );
}

In most cases (when the promlem occured of course) call “ReleaseMutex( mutex1 );” blocks for DEADLOCK_TIMEOUT milliseconds (not DEADLOCK_TIMEOUT/2). I’d say it is because WaitForSingleObject in Func1 waits for DEADLOCK_TIMEOUT milliseconds. Sometimes “WaitForSingleObject( mutex1, …” returned WAIT_TIMEOUT.

Then I tried to get rid of two mutexes and use only mutex1:

Func2()
{
if (WaitForSingleObject( mutex1, DEADLOCK_TIMEOUT ) != WAIT_OBJECT_0)
{
restart Func2;
}
// Do something useful (1)
// Do something useful (2)
ReleaseMutex( mutex1 );
}

And the problem appeared again. :frowning: It became 10 times rare definitely. But “ReleaseMutex( mutex1 );” stilll could hang for DEADLOCK_TIMEOUT milliseconds.


Best regards,
Alexey.

“Tzvetan Mikov” wrote in message news:…
> In theory (but in theory ReleaseMutex should not block either :-).
> I am refering to the non-standard (for me) lock hierarchy - two locks which can
> sometimes be acquired separately, sometimes together, and are always released
> separately. Would something like this work for you and would it exhibit the same
> problem ?
>
> Func2()
> {
> if (WaitForSingleObject( mutex1, DEADLOCK_TIMEOUT/2 ) != WAIT_OBJECT_0)
> restart Func2;
> if (WaitForSingleObject( mutex2, DEADLOCK_TIMEOUT/2 ) != WAIT_OBJECT_0)
> {
> ReleaseMutex( mutex1 );
> restart Func2;
> }
> // Do something useful (1)
> ReleaseMutex( mutex2 );
> // Do something useful (2)
> ReleaseMutex( mutex1 );
> }
>
> “Alexey Pakhunov” wrote in message news:xxxxx@ntdev…
> > I have never used WaitFormMultipleObjects to acquire two mutexes at the same
> time
> > (bWaitAll = TRUE) and it bothers me a little - is there a possibility that the
> > mutexes could be acquired in different order by different threads causing
> deadlocks ?
>
> Well, I guess it should not influence somehow. Func2 is the only place where I
> use mutex2. Func1 and Func2 are only functions that use mutex1. bWaitAll just
> guarantee that either both mutexes or none of them will be acquired.
>
> –
> Best regards,
> Alexey.
> “Tzvetan Mikov” wrote in message news:…
> I can’t think of any reason at all why a ReleaseMutex() should block. It is not
> a comforting thought.
>
> I have never used WaitFormMultipleObjects to acquire two mutexes at the same
> time (bWaitAll = TRUE) and it bothers me a little - is there a possibility that
> the mutexes could be acquired in different order by different threads causing
> deadlocks ?
>
> -tz

This is very interesting indeed. After you got rid of mutex2, you basically ended up with two equivalent functions doing:

AcquireMutex( mutex1 )
do something
ReleaseMutex( mutex1 )

There is definitely nothing wrong with that. I can see three possible avenues for investigation:

  1. Since ReleaseMutex() blocked for TIMEOUT_DEADLOCK and not TIMEOUT_DEADLOCK/2 (in the modified case with two mutexes), the problem must be related to Func1. The only difference between Func1 and Func2 is that in Func1 the wait is alertable. Did you try making it non-alertable ?
  2. Some other problem that is not apperant from the snippets you provide. For example the completion ports. It is worth a try simplifying this application to the maximum to determine which exactly causes the problem.
  3. Windows bug ??

Sorry that I can’t be of more help. If you find anything, please post the results - I would sure like to know (or you can e-mail me directly).

regards,
Tzvetan

“Alexey Pakhunov” wrote in message news:xxxxx@ntdev…
Hello.

First of all I found a mistake in my original post. Func2 should look like following:

void Func2()
{
HANDLE handlesToWaitFor = { mutex1, mutex2 };

DWORD waitResult = WaitForMultipleObjects(NUMBER_OF(handlesToWaitFor), handlesToWaitFor, TRUE, DEADLOCK_TIMEOUT);
if (WAIT_OBJECT_0 != waitResult)
{
// Deadlock, restart Func2
}

// Do something useful (1)

ReleaseMutex(mutex1);

// Do something useful (2)

ReleaseMutex(mutex2);
}

In other words mutex1 which is also used by Func1 released first. Otherwise locking of two mutexes would be useless.

So I tried to acquire muexes separately as you offered and got the same problem. Func1 remains the same, the function Func2 looked so:

Func2()
{
if (WaitForSingleObject( mutex2, DEADLOCK_TIMEOUT/2 ) != WAIT_OBJECT_0)
restart Func2;
if (WaitForSingleObject( mutex1, DEADLOCK_TIMEOUT/2 ) != WAIT_OBJECT_0)
{
ReleaseMutex( mutex2 );
restart Func2;
}
// Do something useful (1)
ReleaseMutex( mutex1 );
// Do something useful (2)
ReleaseMutex( mutex2 );
}

In most cases (when the promlem occured of course) call “ReleaseMutex( mutex1 );” blocks for DEADLOCK_TIMEOUT milliseconds (not DEADLOCK_TIMEOUT/2). I’d say it is because WaitForSingleObject in Func1 waits for DEADLOCK_TIMEOUT milliseconds. Sometimes “WaitForSingleObject( mutex1, …” returned WAIT_TIMEOUT.

Then I tried to get rid of two mutexes and use only mutex1:

Func2()
{
if (WaitForSingleObject( mutex1, DEADLOCK_TIMEOUT ) != WAIT_OBJECT_0)
{
restart Func2;
}
// Do something useful (1)
// Do something useful (2)
ReleaseMutex( mutex1 );
}

And the problem appeared again. :frowning: It became 10 times rare definitely. But “ReleaseMutex( mutex1 );” stilll could hang for DEADLOCK_TIMEOUT milliseconds.


Best regards,
Alexey.

“Tzvetan Mikov” wrote in message news:…
> In theory (but in theory ReleaseMutex should not block either :-).
> I am refering to the non-standard (for me) lock hierarchy - two locks which can
> sometimes be acquired separately, sometimes together, and are always released
> separately. Would something like this work for you and would it exhibit the same
> problem ?
>
> Func2()
> {
> if (WaitForSingleObject( mutex1, DEADLOCK_TIMEOUT/2 ) != WAIT_OBJECT_0)
> restart Func2;
> if (WaitForSingleObject( mutex2, DEADLOCK_TIMEOUT/2 ) != WAIT_OBJECT_0)
> {
> ReleaseMutex( mutex1 );
> restart Func2;
> }
> // Do something useful (1)
> ReleaseMutex( mutex2 );
> // Do something useful (2)
> ReleaseMutex( mutex1 );
> }
>
> “Alexey Pakhunov” wrote in message news:xxxxx@ntdev…
> > I have never used WaitFormMultipleObjects to acquire two mutexes at the same
> time
> > (bWaitAll = TRUE) and it bothers me a little - is there a possibility that the
> > mutexes could be acquired in different order by different threads causing
> deadlocks ?
>
> Well, I guess it should not influence somehow. Func2 is the only place where I
> use mutex2. Func1 and Func2 are only functions that use mutex1. bWaitAll just
> guarantee that either both mutexes or none of them will be acquired.
>
> –
> Best regards,
> Alexey.
> “Tzvetan Mikov” wrote in message news:…
> I can’t think of any reason at all why a ReleaseMutex() should block. It is not
> a comforting thought.
>
> I have never used WaitFormMultipleObjects to acquire two mutexes at the same
> time (bWaitAll = TRUE) and it bothers me a little - is there a possibility that
> the mutexes could be acquired in different order by different threads causing
> deadlocks ?
>
> -tz