Problem with timers on program shutdown


#1

I am having huge problems with my mac juce-program these days… The latest is a problem with timers upon program shutdown. In the JuceInternalTimerThread:: the following function goes wrong (at ‘->’):

 void decrementAllCounters (const int numMillisecs) const
    {
        Timer* t = firstTimer;

        while (t != 0)
        {
->        t->countdownMs -= numMillisecs;
            t = t->next;
        }
    }

Superficialy, the problem is that ‘t’ points to the adress 0x258, that holds absolutely nothing of relevance. I am certain that all my destructors stop timers that may be running by

while(isTimerRunning())
     stopTimer()
  • probably a bit redundant, but just to make sure. What could be going wrong here?

EDIT: Oh I forgot… I haven’t experienced this in Juce 1.21, but switching to 1.38…

-Thanks in advance :slight_smile:

-A


#2

You’ve almost certainly got some kind of dangling pointer involved there. Most likely is you’ve tried to start a timer object after deleting it. Or are you trying to stop/delete the timers from a different thread, perhaps?


#3

I am quite careful only to stop timers in destructors… Besides, I never explitly delete a Timer object, only by calling deleteAllChildren and deletaChildComponent(…).

I am wondering why I didn’t experience this in earlier Juce?

-A


#4

Different builds of juce will have different structure layouts, so you might have just been lucky before that nothing went wrong. I use timers all over the place and they’re really robust, even thread-safe, unless you start using dangling objects.

No need to worry about stopping them in destructors, as that happens in the base class anyway. Most likely is that you’ve deleted one and then tried to start it again.


#5

No need to worry about stopping them in destructors, as that happens in the base class anyway

I know - I just like to be explicit for debugging reasons.

I use timers all over the place and they’re really robust, even thread-safe, unless you start using dangling objects

I thought as much. But the error occurs in a place that suggest that the timer (from my code’s point of view) is still actually there. Unless - in the code above, what does ‘t’ point to? It gets created in decrementAllCounters, and at once points to 0x256 - so what is this ‘firstTimer’ thing anyway? Do you mean that some timer references ‘firstTimer’ which is another one of my timers, that has been deleted…? Cryptic formulation, but it’s the best I can do :slight_smile:

-A


#6

If the objects are valid, those pointers should never go wrong. Try this quick trick for checking whether you’re using dangling pointers:

[code]//==============================================================================
static SortedSet <Timer*> activeTimers;

Timer::Timer() throw()
: countdownMs (0),
periodMs (0),
previous (0),
next (0)
{
activeTimers.add (this);
}

Timer::Timer (const Timer&) throw()
: countdownMs (0),
periodMs (0),
previous (0),
next (0)
{
activeTimers.add (this);
}

Timer::~Timer()
{
stopTimer();

activeTimers.removeValue (this);

}

void Timer::startTimer (const int interval) throw()
{
jassert (activeTimers.contains (this));

if (periodMs == 0)
{
    countdownMs = interval;
    periodMs = interval;
    InternalTimerThread::add (this);
}
else
{
    InternalTimerThread::resetCounter (this, interval);
}

}

void Timer::stopTimer() throw()
{
jassert (activeTimers.contains (this));

if (periodMs > 0)
{
    InternalTimerThread::remove (this);
    periodMs = 0;
}

}
[/code]


#7

After I have gone through all my Timer-using code, my problems have vanished. I have checked the Juce timers and you were (of course) right… They are stopped in destructors. Maybe I do some other stuff in my own destructors, that needs the timers to be stopped before ~Timer() is called - could be… Anyway, I’ll try your suggestion if (and I am afraid “when”) other problems come up. Thanks!

-A


#8