Wes
Wes

Reputation: 5067

How can you tell if a QMutex is locked or not?

Does anyone know how to check and see if a QMutex is locked, without using the function:

bool QMutex::tryLock()

The reason I don't want to use tryLock() is because it does two things:

  1. Check and see if the mutex is locked.
  2. If it's not locked then lock it.

For my purposes, I am not interested in performing this second step (locking the mutex).

I just want to know if it is locked or not.

Upvotes: 15

Views: 7386

Answers (5)

Lord_Naikon
Lord_Naikon

Reputation: 46

static bool isLocked(const QBasicMutex *mut) {
  auto mdata = reinterpret_cast<const QBasicAtomicPointer<QMutexData> *>(mut);
  return mdata->load();
}

This code should work on Qt 5 and doesn't mess with the mutex state.

Every QBasicMutex holds a single (atomic) pointer (called d_ptr) that is NULL if not owned, a special value if it is owned but uncontested or a pointer to a platform dependent structure (on Unix, this is basically a pthread mutex) if the mutex is owned and contested.

We need the reinterpret_cast because d_ptr is private.

More info can be found here: https://woboq.com/blog/internals-of-qmutex-in-qt5.html

A legitimate use case is to verify that a mutex is indeed locked, for example if it is a function precondition. I suggest using Q_ASSERT(isLocked(...)) for this purpose.

Testing for an unlocked mutex is inherently unsafe and should not be done.

Upvotes: 0

Wes
Wes

Reputation: 5067

OK, I'm guessing there is no real way to do what I'm asking without actually using tryLock().

This could be accomplished with the following code:

bool is_locked = true;

if( a_mutex.tryLock() )
{
    a_mutex.unlock();
    is_locked = false;
}

if( is_locked )
{
    ...
}

As you can see, it unlocks the QMutex, "a_mutex", if it was able to lock it.

Of course, this is not a perfect solution, as by the time it hits the 2nd if statement, the mutex's status could have changed.

Upvotes: 10

Luca Carlon
Luca Carlon

Reputation: 9986

Maybe a QSemaphore with one permit? The available() method may give you what you need.

Upvotes: 4

S.M.Mousavi
S.M.Mousavi

Reputation: 5236

QMutex is designed just for locking and unlocking functionality. Gathering statistics may be satisfied with some custom counters.
Try QSemaphore as @Luca Carion mentioned earlier.

Upvotes: 1

Ernest Friedman-Hill
Ernest Friedman-Hill

Reputation: 81724

Trying to lock a mutex is by definition the only way to tell if it's locked; otherwise when this imaginary function returned, how would you know if the mutex was still locked? It may have become unlocked while the function was returning; or more importantly, without performing all the cache-flushing and syncronization necessary to lock it, you couldn't actually be sure if it was locked or not.

Upvotes: 25

Related Questions