Multithread problems with Wavelab 5


#1

Hi guys,
I’m testing JuceAudioFilter Demo Win32 VST with Wavelab 5 and I’m experiencing some problems.

Debug build
Right after I select the Demo plugin in Wavelab (the GUI gets opened contextually) a checkMessageManagerIsLocked check fails in Component::toFront(). Ignoring the assertion other identical ones pop up.
My opinion is that Wavelab makes use of more than one thread to load and then manage the plugin GUI. Is there a solution for that?

Release build
The Demo plugin gets loaded regularly (no assertions in Release builds), but after I play for a while on the midi keyboard with the mouse, the whole (host also) GUI gets frozen (the audio thread keeps running), so I suppose a deadlock occurs in the GUI thread.

Also note that with Cubase SX 3 the plugin seems to work good in Debug and Release.

Since I’m evaluating Juce to do a commercial plugin I strongly would like not to exclude Wavelab from the supported VST host list…

Anybody has had this kind of problems?
Any idea about how to solve this problem?

Thanks in advance
toot


#2

Just sounds like they’re using a different thread to call something that’s normally done on the message thread - that could cause locking problems… What’s going on in the stack trace when you get the messagemanager lock assertion?


#3

Yes, actually this is the situation.

I put a breakpoint in juce_VstWrapper.cpp in DllMain() when called with DLL_PROCESS_ATTACH; where Juce gets initialised (and the thread ID is stored inside the framework, I suppose).

At the breakpoint, the current thread ID was 5056 and the thread stacked function name was _DllMainCRTStartup.

Then, at assertion break, the current thread ID was 5224, function AudioEffect::dispatchEffectClass()-

This means that Wavelab is actually driving the VST plugin from two distinct threads: one for the loading stage and another next.

With Cubase the situation is quite different: at DllMain() thread ID is 3536, function _DllMainCRTStartup and at Component::toFront() the thread ID is unchanged (I had to put a breakpoint because I had no assertion…).

Strange that this problem with Wavelab didn’t come out before…


#4

Yeah, I had to change tracktion to make sure the same thread was always used, because it broke so many plugins. I thought all hosts did it that way.

When the message manager is created, it assumes that it’s being created by the message thread. What you’d probably need to do is to use MessageManager::setCurrentMessageThread() to tell it which is the real message thread, but I don’t have wavelab to try it here…


#5

So should I call MessageManager::setCurrentMessageThread() at every VST dispatcher() call?

And what thread ID should I pass there? The main thread one?
Is it ok then if I set a message thread to be the current one, even if I’m not calling that function from that particular thread?

Sorry for asking all these questions but I’m puzzling on this problem since weeks…

If you want I can send you Wavelab 5 Demo. The setup file was publicly downloadable from the Steinberg website until Wavelab 6 has been released.


#6

No, no - I mean just call that method once. If you can find some kind of initialisation call that is definitely called on the real message thread, you could call setCurrentMessageThread (Thread::getCurrentThreadId()) there.


#7

Well it seems that I’m not able to do the job.
The checkMessageManagerIsLocked check verifies that the member currentLockingThreadId equals the current thread id, and it asserts if this is not verified. And it’s very difficult for me as a framework client to access that member after it is initially assigned while Juce is loading.

Anyway, the fact that has to be noted here is that if I run the Release version (all those checks removed) the Demo plugin works (or looks to work) good in Wavelab.

So I suppose that JAP users just are ignoring these problems with Wavelab unless they had a chance to run their VST plugin while debugging…

~

I noticed that while quitting Cubase after loading the Demo VST plugin, it asserts just before killing a thread not getting terminated normally. This also is not visible in Release builds but should deserve some attention…

One InternalTimerThread destructor times out (4 seconds) while calling stopThread().

Here’s the comment at the jassertfalse point (just before killing the thread by force):

// very bad karma if this point is reached, as
// there are bound to be locks and events left in
// silly states when a thread is killed by force…


#8

[quote]// very bad karma if this point is reached, as
// there are bound to be locks and events left in
// silly states when a thread is killed by force…[/quote]

jesus, how many times have i seen that?! lol

sprinkle run() generously with threadShouldExit()

lol


#9