Protools setStateInfo + MML deadlock

Hey guys -

I am getting a strange deadlock in ProTools. Other hosts are fine, just AAX related it seems.

If I try to lock the MM thread at any point in setStateInformation() it will just hang. What other thread has the lock is unclear.

Since I need to add some change listeners during load, I really should lock the MM (or I hit an assertion in ChangeBroadcaster).

If I use openGL for my UI (which I usually do) then I notice the openGL thread is also waiting to lock the MM thread.

I don’t see what thread has the lock … perhaps one of the other processes that ProTools is running locks the MM until after the plugin is fully loaded? Including the setStateInfo part?

For now I’m just adding the change listeners and disregarding the assertion, though I know that there is a slight risk there.

I suspect you could reproduce this by just adding
MessageManagerLock mml (Thread::getCurrentThread())

To any AAX plugin in the setStateInfo routine.

The fact that they both are stuck at the entry means a third thread is actually holding the lock. This would be your problem.

Two threads fighting over a lock should never create a deadlock.

EDIT ::: hey Mayae, I edited this post after your comment. I think this is a valid issue now, let me know

SetStateInformation could very well be called asynchronously, even though it’s ridiculous. Hosts do it to speed up loading times.

The only way I see an deadlock occuring is if setStateInformation stack has a lock on the processor state. That may very well happen. You could just use an AsyncUpdater instead - it’s allow to broadcast without locks? In the callback, you could then broadcast normally using the change broadcaster.

It’s not the broadcasting that’s causing the issue, its the addChangeListener().

When loading (a synth for example), I create a bunch of voices and set the voices up as changeBroadcasters, and set the synth up as a listener.

There is an assertion in AddChangeListener() however which says you should lock the MM.
That’s fine in other hosts, but ProTools seems to be holding the MM locked already.

So I can’t run addChangeListener() in the load routines.

Why do you have listeners on voices, and why do these depend on the state information - wouldn’t you just have a set amount of voices?

Anyway, it’s an unsolvable problem doing it this way, so you will need to update/add the listeners asynchronously.

Yeah, I guess so. A shame that one DAW is always doing it differently, but I can move stuff around.

And no, I have a synth that has both mono and poly voice modes, so the voice array is often cleared and rebuilt with new presets. Hence the issue.

Thanks

You’ll find in AAX that Thread::getCurrentThread() returns NULL which is why it hangs… you probably need to use an AsyncUpdater. I have a separate Thread for loading my preset and I do something like that… but whatever you end up doing check it exhaustively on all platforms.

Your other option may be to set the AAX flag in the wrapper to load the chunk on the Message Thread.

Rail

2 Likes

Woah!! Indeed it does.

So I guess I had better not use Thread::getCurrentThread() anywhere within plugins if they will be AAX then eh?

I see it gets a thread fine if it happens to be run from the message thread, but not from the others apparently?

Well if you can create your own preset loading thread… getCurrentThread() should be able to get a valid result from that.

Rail

Yeah, working on that now. Thanks :slight_smile:

FYI: In some non-realtime host (I can’t remember which one the report was about, maybe Adobe Audition) using an AsyncUpdate to finish loading the state caused the preset not to be loaded when audio playback started!

For success we found that before setStateInformation returns you want to be in a position that starting playback will work, and you cannot rely on any messsage thread events happening before then. Awkward eh :slight_smile: