Realtime to user-thread communication


#1

What it’s the best way to notify the user thread from the realtime thread ?

Using MessageListener::postMessage() seems problematic, since the messaged passed must be created with new Message().
It’s not a good idea to make “new Something()” call from the realtime thread, because this may take a long time to run (BTW Digidesign warns plugin developer against this)

And since MessageListener is used to implement some services, then these services also are disqualified as good RT->GUI communication tool.
For instance, I won’t use AsyncUpdater::triggerAsyncUpdate(). This propagate to a lot of GUI functions, like ComboBox::setSelectedItemIndex()


#2

I tried thread->notify, but got pretty bad spikes. If you look at the mac specific code in JUCE, this calls pthread_mutex_lock (!?!) before calling pthread_cond_signal–and is therefore totally unsafe to call from audio callback.

So, no definitive answer but a little info on what doesn’t work. I’m considering patching my local JUCE to use bsd semaphore stuff–there’s an example of this in the Digidesign document you cite in your post.


#3

In the same vein, the class ChangeBroadcaster that looks great on paper suffers from the very same problem.
It ultimately calls ChangeListenerList::sendChangeMessage, where you have the dreaded “new Message()”:

if ((! messagePending) && (listeners.size() > 0)) { lastChangedObject = objectThatHasChanged; postMessage (new Message (0, 0, 0, objectThatHasChanged)); messagePending = true; }


#4

Also in the MIDI code there is at least one new. Very bad to use new() in realtime. The only solution I see would be to create a new Pool class that contains preallocated objects and then the realtime stuff would get the objects (well pointers to them) from the pool instead of using new().
One would also have to call the pool’s free() function to give the objects back to the pool.


#5

I was also thinking to code a custom malloc, using polls for small objects. We could have a pool for objects from 1 to 8 byte, another for objects from 9 to 16 bytes, etc.
I have heard a long time ago about such a malloc replacement, but I can’t remember where.
Could very well be here : http://www.ddj.com/cpp/184406243


#6

I have used the Doug Lea allocator before, which I believe does the size based pool thing…