MessageManagerLock equivalent with a timeout?


#1

Hi,

Currently, I’ve some code that does this:

if (!isShuttingDown())
{
     MessageManagerLock lock;
     mainCommandManager->invokeDirectly(Commands::Refresh, false);
}

There is a race / deadlock in this code, because at the time the juce::isShuttingDown() call is made, the application might not be shutdown yet.
Ideally, there should be a way to check if the thread can lock the message manager, and follow another code path if it can’t.
To avoid breaking existing code, we could add a MessageManagerTryLock lock instead, and force testing if the lock was taken, something like this pseudo code:

struct MessageManagerTryLock
{
    MessageManagerTryLock(const int timeoutMillisecond = -1);
    ~MessageManagerTryLock()
    {
         // If you use this object, you must check if the locking succeeded at least once!
         jassert(wasChecked);
         [...] // Unlock MM
    } 

    operator bool() { wasChecked = true; return isLocked; }
};

// So usage would be:
if (!isShuttingDown())
{
     MessageManagerTryLock lock(40);
     if (lock)
     {
          // Lock gained
     } 
     // else lock not gained, good idea to check isShuttingDown() again, or act accordingly.
}

What do you think ?


#2

Well, the MessageManagerLock constructor already some thread stuff to check, it should probably just have a timeout in there too…


#3

Sure. But if it can’t get the lock, what should it do ?
We need to figure out a way to know if the lock has been taken or not (in case of timed out).


#4

It already has a lockWasGained() method for exactly this - it’d just need a timeout adding to the constructor.