Ok, I’ve just seen this happen in tracktion, and it seems that for some reason threads just don’t start correctly while a plugin scan is taking place, presumably because there’s no message loop active. As a fix, here are some changes to the start of juce_Timer.cpp which start the thread asynchronously…
[code]#include “juce_Timer.h”
#include “juce_MessageManager.h”
#include “juce_AsyncUpdater.h”
#include “…/application/juce_Application.h”
#include “…/application/juce_DeletedAtShutdown.h”
#include “…/…/juce_core/basics/juce_Time.h”
#include “…/…/juce_core/threads/juce_Thread.h”
#include “…/…/juce_core/threads/juce_ScopedLock.h”
#include “…/…/juce_core/containers/juce_VoidArray.h”
//==============================================================================
class InternalTimerThread : private Thread,
private MessageListener,
private DeletedAtShutdown,
private AsyncUpdater
{
private:
static InternalTimerThread* instance;
static CriticalSection lock;
Timer* firstTimer;
bool volatile callbackNeeded;
InternalTimerThread (const InternalTimerThread&);
const InternalTimerThread& operator= (const InternalTimerThread&);
void addTimer (Timer* const t) throw()
{
#ifdef JUCE_DEBUG
Timer* tt = firstTimer;
while (tt != 0)
{
// trying to add a timer that's already here - shouldn't get to this point,
// so if you get this assertion, let me know!
jassert (tt != t);
tt = tt->next;
}
jassert (t->previous == 0 && t->next == 0);
#endif
Timer* i = firstTimer;
if (i == 0 || i->countdownMs > t->countdownMs)
{
t->next = firstTimer;
firstTimer = t;
}
else
{
while (i->next != 0 && i->next->countdownMs <= t->countdownMs)
i = i->next;
jassert (i != 0);
t->next = i->next;
t->previous = i;
i->next = t;
}
if (t->next != 0)
t->next->previous = t;
jassert ((t->next == 0 || t->next->countdownMs >= t->countdownMs)
&& (t->previous == 0 || t->previous->countdownMs <= t->countdownMs));
notify();
}
void removeTimer (Timer* const t) throw()
{
#ifdef JUCE_DEBUG
Timer* tt = firstTimer;
bool found = false;
while (tt != 0)
{
if (tt == t)
{
found = true;
break;
}
tt = tt->next;
}
// trying to remove a timer that's not here - shouldn't get to this point,
// so if you get this assertion, let me know!
jassert (found);
#endif
if (t->previous != 0)
{
jassert (firstTimer != t);
t->previous->next = t->next;
}
else
{
jassert (firstTimer == t);
firstTimer = t->next;
}
if (t->next != 0)
t->next->previous = t->previous;
t->next = 0;
t->previous = 0;
}
void decrementAllCounters (const int numMillisecs) const
{
Timer* t = firstTimer;
while (t != 0)
{
t->countdownMs -= numMillisecs;
t = t->next;
}
}
void handleAsyncUpdate()
{
startThread (7);
}
public:
InternalTimerThread()
: Thread (T(“Juce Timer”)),
firstTimer (0),
callbackNeeded (false)
{
triggerAsyncUpdate();
}
[/code]