Std::unique_ptr from ChangeBroadcaster Thread (vs. ScopedPointer)


#1

So if I use a std::unique_ptr for my Thread class which is derived from ChangeBroadcaster and I addChangeListener() – when I get the changeListenerCallback() the std::unique_ptr is nullptr, so:


std::unique_ptr<CReloadThread>      m_pReloadThread;

CReloadThread::~CReloadThread()
{
    if (MessageManager::getInstance()->isThisTheMessageThread())
        {
        removeChangeListener (m_pSynthProc);
        }
    else
        {
        MessageManagerLock mml;
        
        if (mml.lockWasGained())
            removeChangeListener (m_pSynthProc);
        }
    
    stopThread (2000);
}

void CReloadThread::run()
{
    // Do some stuff....
    
    if (! m_pProcessor->isPluginShuttingDown())        
        sendChangeMessage();
}

void CSynthProcessor::changeListenerCallback (ChangeBroadcaster* source)
{
    if (source == m_pReloadThread.get())
        {
        // Do some post thread stuff...

        // Never gets here with std::unique_ptr but does with ScopedPointer
        }
}

I get the changeListenerCallback() but m_pReloadThread is nullptr if it’s a std::unique_ptr.

If m_pReloadThread is a ScopedPointer however, m_pReloadThread is not nullptr in changeListenerCallback().

 ScopedPointer <CReloadThread>      m_pReloadThread;

Thoughts?

Cheers,

Rail


#2

You must be moving out of that unique_ptr somewhere, but I can’t see anything in this code that does so. An easy way to spot the culprit might be to declare the unique_ptr as const and see where it fails to build :slight_smile:


#3

Brilliant idea! I found a stupid reset() in the wrong place

void CSynthProcessor::stopReloadThread()
{
    if (m_pReloadThread != nullptr)
        {
        if (m_pReloadThread->isThreadRunning())
            {
            m_pReloadThread->signalThreadShouldExit();
            
            while (m_pReloadThread != nullptr && m_pReloadThread->isThreadRunning())
                ;  // This shouldn't take long
            
            Logger::writeToLog ("SRC Reload Thread stopped.");
            
            m_pReloadThread.reset();  // This was after the closing brace
            }
        }
}

Interesting that ScopedPointer behaved differently.

Thanks,

Rail


#4

Yeah, that’s really odd, the two classes should have exactly the same semantics for a move/reset operation.