Q:

Using QMutex::tryLock and QMutexLocker

I have a background function that currently has something like follows:
void SomeClass::someFunction()
{
    if (!_mutex.tryLock())
    {
        // i want to know the mutex is locked, and then exit the function
        return;
    }
    else
    {
        _mutex.unlock();
    }

    QMutexLocker locker(_mutext);

    // do some stuff that **could** throw an exception
}

My dilemma concerns the _mutex.unlock() and QMutextLocker statement. 
If the _mutex is locked, then I want to know about it. If it's not, then I want lock it. The problem is that I want to use QMutexLocker to lock _mutex for the bulk of the function. It's possible that the function could throw an exception, so manually unlocking _mutex could be difficult and error prone. 
The above solution works but what concerns me is that sometime between the _mutex.unlock() and the deceleration of QMutexLocker something else could come along and lock the mutex.
Does anyone have any suggestions of a better way to do this?
Thank you.

A:

QMutexLocker clearly doesn't do quite what you need here, but you can write your own RAII wrapper easily enough:
class MutexTryLocker {
  QMutex &m_;
  bool locked_;
public:
  MutexTryLocker(QMutex &m) : m_(m), locked_(m.tryLock()) {}
  ~MutexTryLocker() { if (locked_) m_.unlock(); }
  bool isLocked() const { return locked_; }
}

and use it like so:
void SomeClass::someFunction() {
    MutexTryLocked locker(_mutex);

    if (!locker.isLocked()) {
        // we didn't get the lock, so return
        return;
    }

    // do some stuff that **could** throw an exception
}

Note this locker is just sample code: a production version should probably be explicitly noncopyable.

Historical note: JBL's comment referred to a paragraph addressing a sentence no longer in the question. I'll paraphrase it as:

... something else could come along and lock the mutex

If it's possible, it will happen. If it's unlikely, it will happen only after you deploy it/scale it up/sell it to a customer.

