fogbit
fogbit

Reputation: 2063

How to wait until mutex unlocked?

There is an array of mutexes. My function:

  1. Checks is a mutex is locked

2a. If not, then locks it

2b. If locked, wait for unlocking and locks it

Another function unlocks it.

The problem is that I got crash in the waiting section:

HANDLE mutexes[N];

void func(int i)
{
  // (*) wait until unlocked or create if unlocked
  while ((mutexes[i] = CreateMutex(NULL, TRUE/*same with FALSE*/, NULL)) != NULL);
  /*or WaitForSingleObject(mutexes[i], INFINITE)*/

  mutexes[i] = CreateMutex(NULL, TRUE, NULL);
}

At (*) point i got crash - access violation. Crash occurs when it's trying to create mutexes[i] which is already have been created previously. I can't use WaitForSingleObject because at first time mutexes[i] isn't created and docs says WaitForSingleObject is undefined. Also if i use this function i get the same crash.

All i need is the analog of such simple pseudocode

if (mutex_has_been_created[mutexes[i]])
  WaitUntilRelease()
CreateMutex();

I tried to wrap it in a critical section and got same result. I'm sure that i is within correct range. I can't use Boost/pThreads/etc.

I know that my problem is quite easy, but i can't find the solution. In all examples i've seen a mutex is created before WaitForSingleObject, this doesn't work for me.

Thank you.

Upvotes: 3

Views: 21195

Answers (4)

Ian Thompson
Ian Thompson

Reputation: 654

HANDLE mutexes[N]

void InitMutexes(int N)
{
    for (int i =0; i < N ; i++)
    {           
        mutexes[i] = CreateMutex( NULL, FALSE, NULL);
    }
}
void WaitForMutex(int n)
{
    WaitForSingleObject(mutexes[n], INFINITE);
}
void ReleaseMutex(int n)
{
    ReleaseMutex(mutexes[n]);
}
void CleanUpMutexes(int N)
{
    for (int i=0; i < N; i++)
    {
          ReleaseMutex(mutexes[i]); CloseHandle(mutexes[i]);
    }
}

Hope that helps.

Upvotes: 1

NPE
NPE

Reputation: 500853

You really need to sort out the logic of your code: the creation of mutexes and the locking/unlocking are distinct operations and should be treated as such. Frankly, all this business of "trying to create mutexes which already have been created" does not make a whole lot of sense.

Briefly:

  1. CreateMutex initializes ("creates") the mutex.
  2. WaitForSingleObject et al lock the mutex (or time out).
  3. ReleaseMutex unlocks it.
  4. CloseHandle destroys it.

You create/destroy the mutex once and in between lock/unlock it as many times as you want.

When you try to lock a mutex that's already locked by someone else, your thread automatically blocks until the mutex becomes available.

Upvotes: 15

R. Martinho Fernandes
R. Martinho Fernandes

Reputation: 234644

If you want to wait until it is unlocked, only to lock it, then you can just lock it. That's exactly what happens when you do so. When you attempt a lock the code blocks until the mutex becomes available, and then locks it.

Upvotes: 5

With posix threads you probably would use condition variables; I have no idea if WinAPI offer similar things.

Upvotes: 1

Related Questions