views:

167

answers:

3

I have a function which is part of a class and in this function there is a mutex.lock at the beginning of the function and a mutex.unlock just before its return. Now I have encountered a situation where the mutex is stuck in the locked state. What could be doing this if this function is the only place where I use that mutex to lock and unlock. The function is called from the main thread and from 1 or 2 other QThreads.

UPDATE: the problem was due to the thread not sleeping in between function calls. Maybe the lack of a sleep relocked the mutex really fast? You could also call yieldCurrentThread();

A: 

My guess is that one of the other threads that calls this function is still holding the lock, and has not released it, so the next thread that tries to enter that section of code, has to wait until the lock is releasd.

Are there any blocking calls inside the lock/unlock code?

From the Qt QMutex Documentation:

When you call lock() in a thread, other threads that try to call lock() in the same place will block until the thread that got the lock calls unlock()

Miguel Sevilla
actually if the thread keeps lock and unlocking the mutex there is a chance other threads wont have time to unlock it like my case:while(1){mutex.lock(); code-code-code; mutex.unlock();}
yan bellavance
+5  A: 

If an exception is thrown in the function the unlock() at the end might not get executed. To make sure the QMutex gets unlocked in such cases you can do the locking with a QMutexLocker object. This object will automatically unlock the mutex when it get's destroyed, even if that happens during stack unwinding after an exception.

sth
ok thanks I will add that and see if it never happens. Is there a way I can detect this unhandled exception?
yan bellavance
I'm having this problem too using QMutexLocker so I don't think this is it.
Joe Soul-bringer
+1  A: 

The mutex was relocking right after unlocking from the same QThread so fast that the main thread didn't have time to lock it back. Adding a sleep or yieldCurrentThread() fixed the problem

yan bellavance