MessageQueue recursive callback

Hi Jules, I've found a situation where the message queue's runLoopSource gets called back recursively.  It occurs due to a plugin invoking the runloop when it's state information is loaded (the plugin is the NI Kontakt player).  I've attached an image of the stack trace.

Due to this I have a handleAsyncUpdate that appears to get invoked twice in the same effective pass of the run loop, which I don't think should be expected?  I dug through apple's run loop docs looking for a way to deal with it but wasn't able to sort anything much out of it.  I tested out just using an "in progress" flag in runLoopCallback to stop the recursion which appears to work ok.  I can also do this directly in my handleAsyncUpdate easily enough but it's kinda hacky I think.




Jeez... This is why plugins should NEVER RUN MODAL LOOPS!!

Unfortunately, if the stupid thing decides to run a loop in the middle of a call to setStateInformation() then there's nothing you can really do about that other than hacks to avoid problems when it happens.

Trying to stop runLoopCallback() being called recursively isn't a good plan though, since there are times when you actually do want that to happen. It'd be better to stop the async event getting re-triggered, so maybe find out when triggerAsyncCallback gets called, and stop that somehow.

A trick I find useful for this sort of thing is to create a stack-local dummy Component and put it into a modal state before calling setStateInformation, so that will at least block any input events from reaching your GUI while the plugin is busy. It won't stop your timers or other events from getting called though.

Yeah it looks like it's due to a "loading" popup that it likes to popup repeatedly and quite pointlessly a few microseconds at a time.  Perhaps if someday you decide to put together that juce plugin format you could then enforce no modal loops, and there could be an api to allow the host to monitor a plugin's loading progress so the host could manage the displaying of that sort of thing itself.  That would be nice.  

I'll leave the queue alone and go with my local hack.  Thanks for the tips!

I have another problem with Kontakt 5 player.

When you try to close it's window, it hangs in the following code:

bool WaitableEvent::wait (const int timeOutMs) const noexcept
    return WaitForSingleObject (handle, (DWORD) timeOutMs) == WAIT_OBJECT_0;

This also occurs in the demo host and Tracktion 5.

I believe it is a Kontakt 5 problem, but does anyone have a fix.

Can't you share a more useful stack-trace? That method is obviously called from thousands of places, it tells us nothing without some context..