Exiting a thread


#1

I need to trigger some code at the end of a timerCallback() and it needs to be on its own thread, so I had the following idea and maybe it’s a terrible idea. The thread does some network operations which are set up to time out after 10 seconds.

class FileTransferThread : public Thread
{
public:
    FileTransferThread()
    :   Thread("FileTransfer Thread")
    {
    }
    ~FileTransferThread() {
        stopThread(12000); //you got 12 seconds to finish doing what you need to do
    }
    void run() override {
        while( !threadShouldExit() ) {
            //do some server stuff that has a timeout set to < 12 seconds
            return;
        }
    }
private:
    SharedResourcePointer<ServerAppInterface> serverAppInterface;
};

void MidiRecorder::timerCallback() {
    FileTransferThread ftf();
    ftf.startThread();
}

My idea was that as soon as the timerCallback() finishes executing, the thread destructor is called, which gives the thread 12 seconds to do what it needs to do. I’d love some feedback on this idea.


#2

That code seems to block the execution of the thread that makes the timerCallback, so what is the point of the additional thread? (Your Filetransferthread is a local variable in that code, so its destructor is called at the end of timerCallback, thus causing the wait for the thread to happen in the context of the thread doing the timerCallback.)


#3

I don’t understand how it blocks it, but it definitely calls the destructor before the run() can be called.
I guess I need to figure out how to call stopThread() from inside the run() so it shuts down after running once.

I just want that network stuff to be triggered from the timerCallback() but not affect any other code.


#4

your ftf instance goes out of scope, so the destructor is called, where stopThread is called, which blocks for timeout msecs.
Your thread should have a lifetime as long as possible, because the most expensive step is to start it up. A better approach would be using TimeSliceClient together with TimeSliceThread.
Think of a thread as a program running independent from your code. You stand outside and you can only set some signals and turnouts, but the thread does everything alone. One of these turnouts is “threadShouldExit()”, which is the minimal interface to stop your thread without killing it.
Other methods are e.g. WaitableEvents.

So in your case, have a WaitableEvent in useTimeSlice():

int useTimeSlice() {
    waitable.wait();
    // do your independent processing

    return 100;
}

void timeCallback() {
    // whenever something ready to be processed
    waitable.signal();
}

TimeSliceThread thread ("My thread");
thread.startThread();
thread.addTimeSliceClient (ftf);