WaitableEvent broke

After merging latest JUCE changes, my program started getting stuck.

If I revert a recent JUCE commit which rewrote WaitableEvent’s internals, my program works again.

The behaviour where “wait” shouldn’t wait indefinitely if the signal was already triggered part doesn’t seem to always work anymore.

1 Like

Can you post some example code which reproduces the problem?

Not easily, no. It happened in a large proprietary project.

Ok, example code:

for (int i = 0; i < 1000000; ++i)
{
    WaitableEvent event;
    std::thread ([&event, i]() {
        printf ("%d Signal!\n", i);
        event.signal();
    }).detach();
    printf ("%d Waiting\n", i);
    event.wait();
    printf ("%d Done\n", i);
}

Over here it got stuck in one of the iterations, inside WaitableEvent::wait at the line

condition.wait (lock, [this] { return triggered == true; });

Tested on macOS 10.14.6 XCode 11.3 JUCE at c8fffa9044874

3 Likes

I guess the example is telling on an assumption on WaitableEvent's API which no longer holds - the magic apparently happens because event.signal() may be doing stuff to the event that no longer exists because wait()'s already finished and it’s scope ends there. Previously I guess the signal had the guarantee that as long as the object stays alive for the wait then it’ll be good.

1 Like

Thanks for the example code, I was able to reproduce the hang and it seems that moving the notify_all() call inside the scope of the mutex fixes things. I’ve pushed this in f402a3f - can you see if it fixes the issue for you?

3 Likes

Yeah seems to work properly now, thanks