MessageManager::runDispatchLoopUntil() + 1ms timeout


MessageManager::runDispatchLoopUntil() does not work reliably when given a timeout value of 1ms.

a) Passing -1 runs the loop forever.
b) Passing 0 never enters the loop.
c) Passing 1 may or may not enter the loop.
d) Passing 2 or higher always enters the loop.

The reason for c) is that Time::currentTimeMillis() is called twice, once to initialize endTime and a second time in the condition. The system’s milliseconds counter may well flip between the two calls, and the loop will not be entered if it does. To fix this problem, I suggest to introduce a currentTime variable, allowing initialization and condition to use the same time value:

bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor)
    jassert (isThisTheMessageThread()); // must only be called by the message thread

    int64 currentTime = Time::currentTimeMillis();
    const int64 endTime = currentTime + millisecondsToRunFor;

    while ((millisecondsToRunFor < 0 || endTime > currentTime) && ! quitMessageReceived)
            if (! dispatchNextMessageOnSystemQueue (millisecondsToRunFor >= 0))
                const int msToWait = (int) (endTime - Time::currentTimeMillis());

                if (msToWait > 0)
                    Thread::sleep (jmin (5, msToWait));

        currentTime = Time::currentTimeMillis();

    return ! quitMessageReceived;


Good catch! Thanks, I’ll sort that out!