Threaded Download


#1

Hello,

I’m exploring using a background thread for downloading audio data. So far all the downloading is working, and I’ve created an object which handles the download which inherits from the Thread class and implements the run() method. I then have a button on my UI which calls ->startThread(); on the object. However, it doesn’t seem to be doing the downloading on a separate thread as the UI still hangs until the download completes.

Here is my run method:

void ThreadStream::run()
{
    while (! threadShouldExit())
    {
        // because this is a background thread, we mustn't do any UI work without
        // first grabbing a MessageManagerLock..
        const MessageManagerLock mml (Thread::getCurrentThread());
        
        if (! mml.lockWasGained())  // if something is trying to kill this job, the lock
            return;                 // will fail, in which case we'd better return..
        
        URL theURL("https://jakemumu.github.io/HH.wav");
        
        audioInputStream = theURL.createInputStream(false);
        AudioFormatReader *reader = formatManager.createReaderFor(audioInputStream);
        
        if (reader != nullptr)
        {
            fileLoaded = true;
            downloadBuffer.setSize(reader->numChannels, reader->lengthInSamples);
            reader->read(&downloadBuffer, 0, reader->lengthInSamples, 0, true, true);
        }
        signalThreadShouldExit();
    }
}

Sorry if this is a bit naive as i’ve not got a lot of experience with threads nor MessageManagerLocks

Thanks for any replies!


#2

Actually, It appears to work as expected with the message manager lock removed.

Is the MM lock needed for threading? Am I doing something dangerous by removing it?


#3

You are right that locking the message manager is the cause of your problem: if the message manager is locked your GUI cannot respond to anything and will simply freeze.

You don’t need to lock the message manager in the sample code you provided. It really depends on what you will be doing with the data and from what threads you will be accessing it. You need to make sure that you don’t access the downloadBuffer from two threads at the same time. If you are accessing the downloadBuffer on the message thread, it’s better to call a completion function on the message thread once reading is finished - for example with MessageManager::callAsync