Timer thread deleted, and shutdownJuce_GUI() asserts


#1

Hi !

I’m encountering a little problem and cannot understand what happen. Here is basically what I do ; I have 2 classes (that I think you need to know about…) The first one is publicly inheriting Timer, and the second has got one object of the type of the first class… i.e. :

[code]class CustomizedTimer
: public Timer
{
~CustomizedTimer() {stopTimer();} // don’t forget to stop Timer before being deleted.

... // can do lots of other interesting stuff.

};

class ClassLayeredOnTopOfCustomizedTimer
{
… // can do lots of also interesting stuff.

private :
CustomizedTimer memberCustomizedTimer; // has got one CustomizedTimer object (not a pointer!!)
}[/code]

Now what my code does is roughly the following :

[code]int main()
{
… // Create loads of things (not using juce)

initialiseJuce_GUI();

... // Create another lot of things, not only juce-related, in particular creating
    // many different thread. At some point, some thread will do following.
{
    ClassLayeredOnTopOfCustomizedTimer* p = new ClassLayeredOnTopOfCustomizedTimer();

    ... // do some more things with p, involving that CustomizedTimer::startTimer() ends up being called at some point

    delete p; // because I don't want my app to leak !
}


... // Then finally, in my main thread again, when I am done using juce.
    // Note that at this point, my app has one single thread again the
    // the main one. (and my debugger is fairly certain about it!)
shutdownJuce_GUI(); // PROBLEM -> will trig jassert, see below !

...

return 0;

}[/code]

The jassert triggs in juce_Thread.cpp, line 198, as it somehow thinks a juce thread (the one privately inherited by the InternalTimerThread created by the Timer part of my CustomizedTimer class.) is still running, and attemps to stop it, which fails and cause the assert to trig. (and the thread visibly doesn’t exist anymore, otherwise the debugger would see it)
What is unclear to me here is that I’d expect this thread to have been deleted already by the time I reach shutdownJuce_GUI. Indeed, I’ve called “delete p;” in the pseudo code above because :
: 1 “delete p;” calls ClassLayeredOnTopOfCustomizedTimer’s destructor
: 2 which calls CustomizedTimer’s destructor
: 3 which calls juce::Timer’s destructor
: 4 and I’d expect class Timer to manage its instance of InternalTimerThread on its own, without me to take any extra care…

Btw, my debugger confirms that step 1, 2 and 3 above actually happen in the expected order, and the thread is actually gone, but somehow, shutdownJuce_GUI seems not to be aware of this fact.

Thanks in advance for anybody coming up with explanations or hints… In the meantime, I’ll try to reproduce the problem in a smaller app’…

Val


#2

You can’t just stick all that GUI code inside a main() function and expect it to work! Use the JUCEApplication class to run everything in the way it was designed to work, and it might stand a chance!


#3

Hi!

Sorry for not answering sooner ; I’ve been busy. Well this is just to let you know that I figured out what happened, and it wasn’t JUCE’s fault. Some dll was unloaded without calling the destructor in the expected order… Anyway, it’s fixed now, so not really an issue.

Thanks for your help !

Val