In the other forum thread about the newly added static void callAsync (std::function<void(void)>) method in MessageManager, I posted an alternative way to do it and speculated it should work OK on OS-X too, because it does seem to do so on Windows. However, now that I tested it on OS-X, it does not work. There happens a hang when Juce GUI objects are manipulated. I suspected that perhaps my wrapper function causes something bad to happen. But callFunctionOnMessageThread does not seem to be working on OS-X when called directly either, similar to :
(std::async is a way to run a callable in another thread)
The code I have tested with is not exactly like above. The mywindow:foo() is actually a method that opens up a Juce Popupmenu and async stuff is launched when choosing a menu item. I wonder if the menu still being open while the async/MessageManager stuff is happening causes some havoc...?
Please read the disclaimer about callFunctionOnMessageThread - it's inherently very dangerous because it blocks, and you should avoid it where possible. In the code above, it doesn't even look like it's necessary.
Well, I would be willing to live with the blocking behavior...(As long as it wouldn't permanently freeze the software on OS-X!)
And using callFunctionOnMessageThread would be necessary in the above code example because calling Label::setText from another thread (from inside the lambda given for std::async(*)) would be a complete disaster, right? (I've assumed Juce works like other GUI toolkits where GUI objects shall not be manipulated from other threads but only from the GUI thread...)
(*) In the real code, there would of course be a time consuming operation in the thread lambda before changing the label text.
It will definitely cause deadlocks if you use it in a thread and try to shutdown while it's being called. Honestly, it's a horrible method to use safely, I never use it myself.
The best way to do some UI stuff from a thread is to do it in a non-blocking way with async function calls. Or as a last-resort, use a MessageManagerLock in its safe mode where you give it a thread to check and allow it to fail to take the lock, and then abort the operation somehow.
OK, I will investigate other ways to do it, or just use your recently added static void callAsync (std::function<void(void)>) in the MessageManager. The void(void) function signature is slightly limiting but will probably work for 99% of use cases...
void(void) should work for 100% of cases, because a lambda can take any parameters you need implicitly. And being async, it's impossible to return a value anyway.