Alexandru Antochi
Alexandru Antochi

Reputation: 1465

CreateMutex with initialOwner set to TRUE makes the creator process keep the mutex till it's done

I have two processes, one writes in a memory mapped file - the producer - while the other reads from the memory file - the consumer.

The first process creates the mutex using the CreateMutex() function with the initialOwner parameter set to TRUE

The code is as follows:

producer:

mutexHandle = CreateMutex(NULL, TRUE, TEXT("producerMutex"));
while (condition)
{
    WaitForSingleObject(mutexHandle, INFINITE);
    // write a random number in the memory mapped file;
    // pause the program and prompt the user to open consumer process; do this only one time 
    ReleaseMutex(mutexHandle);
}

consumer:

mutexHandle = OpenMutex(SYNCRONIZE , FALSE, TEXT("producerMutex"));
while (condition)
{
    WaitForSingleObject(mutexHandle, INFINITE);
    // read from the file, print it in terminal
    ReleaseMutex(mutexHandle);
}

The problem is that if the initialOwner is set to TRUE the consumer will not get access to the mutex until the producer is done. Why is that? The application works if the initialOwner is set to FALSE, but shouldn't it work with it set on TRUE as well?

Upvotes: 0

Views: 1031

Answers (2)

lsalamon
lsalamon

Reputation: 8174

Look at the description of the initialOwner parameter:

CreateMutex function:

If this value is TRUE and the caller created the mutex, the calling thread obtains initial ownership of the mutex object. Otherwise, the calling thread does not obtain ownership of the mutex. To determine if the caller created the mutex, see the Return Values section.

You need to call ReleaseMutex() on the mutex after information is ready to be consumed.

Upvotes: -1

RbMm
RbMm

Reputation: 33754

From the ReleaseMutex documentation:

to release its ownership, the thread must call ReleaseMutex one time for each time that it obtained ownership (either through CreateMutex or a wait function).

In this code:

mutexHandle = CreateMutex(NULL, TRUE, TEXT("producerMutex"));
while (condition)
{
    WaitForSingleObject(mutexHandle, INFINITE);
    // write a random number in the memory mapped file;
    // pause the program and prompt the user to open consumer process; do this only one time 
    ReleaseMutex(mutexHandle);
}

You obtaining the mutex lock N+1 times - 1 time via CreateMutex() with bInitialOwner=TRUE, and N times in the loop via WaitForSingleObject(). But you release it only N times in the loop. As a result, you still hold the mutex lock after the loop, until the thread exits.

To resolve this, you need to skip the first call to WaitForSingleObject in the loop - really, you are already the owner of the mutex and this call is not needed. You can write code like this:

if (mutexHandle = CreateMutex(0, TRUE, L"producerMutex"))
{
    goto __firstTime;
    do 
    {
        WaitForSingleObject(mutexHandle, INFINITE);
__firstTime:
        // write a random number in the memory mapped file;
        ReleaseMutex(mutexHandle);
        // pause the program and prompt the user to open consumer process; do this only one time 
    } while (condition);

    CloseHandle(mutexHandle);
}

You need to call ReleaseMutex() just after you finish accessing the shared resource. Never "pause" the program while you hold the mutex lock. First release it, then pause.

Upvotes: 2

Related Questions