If the message queue on windows is full, then ActionBroadcaster::sendActionMessage silently fails, and then message is lost. Could we at minimum get an assert, and a return value from ActionBroadcaster::sendActionMessage or best case somehow delay and retry later.
The queue limit is 10,000 which seems like a lot, but one message gets generated per listener, so if you have a bunch of listeners, it gets pretty easy to flood the queue. Wouldn’t it be better to generate one ActionMessage and it iterates the list of actionListeners and calls the callback? The ActionMessage already has to check if the pointer is still in the list.
What about something like this:
bool ActionBroadcaster::sendActionMessage (const String& message) const
{
const ScopedLock sl (actionListenerLock);
bool allOk = true;
for (int i = actionListeners.size(); --i >= 0;)
{
bool ok = (new ActionMessage (this, message, actionListeners.getUnchecked(i)))->post();
jassert (ok);
if (! ok)
allOk = false;
}
return allOk;
}
Ok, here is a very simple but contrived example on how to break the message manager.
Create 2500 sliders. You don’t even need to add them as child components. Now the message manager is not responding and async updates, actions messages and timers are all getting lost. The undelivered message are leaking memory. Change it to 2400 sliders, everything works fine.
Reproduced on Windows 10.
The design on MacOS seems much better. Every time a message is posted, it’s added to a ReferenceCountedArray<MessageManager::MessageBase, CriticalSection> messages; and then the main queue is woken up. When the queue wakes up, it dispatches the messages in the queue. Seems like Windows should adopt a similar design.
Thanks for posting the example. I’ve added an overflow buffer for messages that are posted after the message queue limit is reached in commit ce9bb8b. This should prevent the messages from just being silently dropped but the ordering might get skewed a bit if multiple threads are thrashing the queue. AFAIK it’s not possible to replicate the macOS message queue behaviour on Windows as there’s no way to signal that the queue should “wake up”, so this is the best we can do really.