# One-shot threads (lambdas on their own thread that auto-delete)

**URL:** <https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773>\
**Category:** General JUCE discussion\
**Created:** [April 11, 2017, 7:49pm UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773 "2017-04-11T19:49:34Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![matkatmusic](https://avatars.discourse-cdn.com/v4/letter/m/dfb087/32.png) [@matkatmusic](https://forum.juce.com/u/matkatmusic)\
**Post date:** [April 11, 2017, 7:49pm UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773/1 "2017-04-11T19:49:34Z")

</div>

I’m experimenting with setting up one-shot threads (threads that only execute something once then quit) and am having trouble getting it to work. the threads run correctly, but i’m not sure how to shut them down after they complete. The idea was that I could run lambdas on their own threads (great for client-server messaging) without needing to write classes for each type of thread. Perhaps this is a noob approach but i’m curious how to do it properly.

```
class Receiver {
public:
    Receiver() {}
    ~Receiver() {}
    void callback(String result) { DBG( "Receiver::callback() result: \n" + result ); }
};

class AutoDeleteThread : public Thread {
public:
    AutoDeleteThread(std::function<bool()> task ) :Thread("AutoDeleteThread") {
        m_task = task;
        startThread();
    }
    ~AutoDeleteThread() {
        DBG("Shutting down AutoDeleteThread");
        stopThread(500);
    }
    void run() override {
        if( m_task() ) { DBG("OK"); } 
        else { DBG("failed"); }
        delete this; //throws JUCE assertion, because you can't call stopThread() on yourself
    }
private:
    std::function<bool()> m_task;
};

```

//usage:

```
    Receiver r;
    AutoDeleteThread* adt
        = new AutoDeleteThread( [&r]()
    {
        int statusCode = 0;
        URL serverRequestURL = URL("http://chordieapp.dev/AuthV2").withPOSTData("cmd=initialConnect");
        juce::ScopedPointer<juce::InputStream> stream(serverRequestURL.createInputStream(true, //bool usePostCommand
                                                                                         nullptr, //progressCallback
                                                                                         nullptr, //progressCallbackContext
                                                                                         juce::String(), //headers
                                                                                         10000, //timeoutMS
                                                                                         nullptr, //respondHeaders
                                                                                         &statusCode)//statusCode
                                                      );
        if (stream != nullptr) {
            auto reply = stream->readEntireStreamAsString();
            r.callback(reply);
            return true;
        }
        return false;
    }
                                                 );
    DBG( "done with autoDeleteTest" );
```

---

<div class="post-metadata">

**Author:** ![matkatmusic](https://avatars.discourse-cdn.com/v4/letter/m/dfb087/32.png) [@matkatmusic](https://forum.juce.com/u/matkatmusic)\
**Post date:** [April 11, 2017, 7:54pm UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773/2 "2017-04-11T19:54:37Z")

</div>

edit:

it seems that it works (deletes itself) if I do the following for the AutoDeleteThread:

```
~AutoDeleteThread() {
        DBG("Shutting down AutoDeleteThread");
        delete this;
    }
    void run() override {
        if( m_task() ) {
            DBG("OK");
        } else {
            DBG("failed");
        }
        //delete this; //throws JUCE assertion, because you can't call stopThread() on yourself
        signalThreadShouldExit();
    }
```

---

<div class="post-metadata">

**Author:** ![railjonrogut](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/railjonrogut/32/505_2.png) [@railjonrogut](https://forum.juce.com/u/railjonrogut)\
**Post date:** [April 11, 2017, 7:56pm UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773/3 "2017-04-11T19:56:17Z")

</div>

You probably need to have a ChangeListener in the class which creates AutoDeleteThread then have AutoDeleteThread sendMessage() when it’s done and in the changeListenerCallback() delete the thread…

Rail

---

<div class="post-metadata">

**Author:** ![matkatmusic](https://avatars.discourse-cdn.com/v4/letter/m/dfb087/32.png) [@matkatmusic](https://forum.juce.com/u/matkatmusic)\
**Post date:** [April 11, 2017, 7:57pm UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773/4 "2017-04-11T19:57:44Z")

</div>

when I stepped thru the code in the xcode debugger, the AutoDeleteThread was deleted without doing that. I’m wondering about using that ‘new’ operator like that, and if there’s a way to do it without it. The whole idea is to not have to even worry about using threads as class members if they’re only executing one time, but I need it to not execute on the Message Thread.

edit. spoke too soon. leaks when I shut down the test. The thread stops running, but it isn’t deleted. hmm…

---

<div class="post-metadata">

**Author:** ![railjonrogut](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/railjonrogut/32/505_2.png) [@railjonrogut](https://forum.juce.com/u/railjonrogut)\
**Post date:** [April 11, 2017, 8:46pm UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773/5 "2017-04-11T20:46:11Z")

</div>

This works with a quick test:

Header:

```
class AutoDeleteThread;

 class AutoDeleteThreadActual : public Thread,
                                public ChangeBroadcaster
{
 public:

    AutoDeleteThreadActual (AutoDeleteThread* pParent);
    ~AutoDeleteThreadActual();

    void run();

 private:

    AutoDeleteThread* m_pParent;

    bool m_bRunning;

    void doSomething() noexcept;

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AutoDeleteThreadActual)
};

 class AutoDeleteThread : public ChangeListener
{
 public:

    AutoDeleteThread()
    {
        m_pAutoDeleteThread = new AutoDeleteThreadActual (this);
        m_pAutoDeleteThread->startThread();
    }

    void changeListenerCallback (ChangeBroadcaster* source) override
    {
        if (source == m_pAutoDeleteThread)
            delete this;
    }

 private:

    ScopedPointer<AutoDeleteThreadActual> m_pAutoDeleteThread;

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AutoDeleteThread)
};

```

Implementation:

```
 AutoDeleteThreadActual::AutoDeleteThreadActual (AutoDeleteThread* pParent) : Thread ("Auto delete thread"),
                                                                              m_pParent (pParent),
                                                                              m_bRunning (false)
{
    addChangeListener (m_pParent);
}

 AutoDeleteThreadActual::~AutoDeleteThreadActual()
{
    stopThread (2000);
}

 void AutoDeleteThreadActual::run()
{
    while (! threadShouldExit())
        {
        if (! m_bRunning)
            doSomething();
        }

    sendChangeMessage();
}

 void AutoDeleteThreadActual::doSomething() noexcept
{
    m_bRunning = true;

    wait (1000);

    signalThreadShouldExit();
}

```

In the calling component constructor as a test I did

```
 new AutoDeleteThread();

```

and I ran the app in debug without any errors.

EDIT: I’ve change the code to self delete.

Rail

---

<div class="post-metadata">

**Author:** ![matkatmusic](https://avatars.discourse-cdn.com/v4/letter/m/dfb087/32.png) [@matkatmusic](https://forum.juce.com/u/matkatmusic)\
**Post date:** [April 11, 2017, 8:51pm UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773/6 "2017-04-11T20:51:55Z")

</div>

ok, this works without leaking

```
class AutoDeleteThread;
class Receiver {
public:
    Receiver() {}
    ~Receiver() {}
    void callback(String result);
private:
};

class AutoDeleteThread : public Thread {
public:
    AutoDeleteThread(std::function<bool()> task ) :Thread("AutoDeleteThread") {
        m_task = task;
        startThread();
    }
    AutoDeleteThread() : Thread("AutoDeleteThread") {}
    ~AutoDeleteThread() {
        DBG("Shutting down AutoDeleteThread");
        //delete this;
    }
    void run() override {
        if( m_task() ) {
            DBG("AutoDeleteThread::run() result: OK");
        } else {
            DBG("AutoDeleteThread::run() result: failed");
        }
        //delete this; //throws JUCE assertion, because you can't call stopThread() on yourself
        signalThreadShouldExit();
    }
    void changeTask( std::function<bool()> newTask) {
        m_task = newTask;
        if( !isThreadRunning() ) { startThread(); }
    }
private:
    std::function<bool()> m_task;
};

```

usage: Modify the default juce GUI app as follows:

```
class MainContentComponent : public Component, public Timer
{
public:
MainContentComponent() { startTimer(1000); setSize(600,400); }
~MainContentComponent();

void paint (Graphics&) override;
void resized() override;

void timerCallback() override {
Receiver r;
adt.changeTask( [&r]()
                       {
                           int statusCode = 0;
                           URL serverRequestURL = URL("https://www.google.com");
                           juce::ScopedPointer<juce::InputStream> stream(serverRequestURL.createInputStream(true, nullptr, nullptr,juce::String(),10000,nullptr,&statusCode));
                           if (stream != nullptr) {
                               auto reply = stream->readEntireStreamAsString();
                               r.callback(reply);
                               return true;
                           }
                           return false;
                       }
                       );
DBG( "done with autoDeleteTest" );
stopTimer();

}
private:
AutoDeleteThread adt;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};
```

---

<div class="post-metadata">

**Author:** ![railjonrogut](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/railjonrogut/32/505_2.png) [@railjonrogut](https://forum.juce.com/u/railjonrogut)\
**Post date:** [April 11, 2017, 8:54pm UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773/7 "2017-04-11T20:54:10Z")

</div>

I’ve updated my code above also to self delete and it also works without error

Rail

---

<div class="post-metadata">

**Author:** ![matkatmusic](https://avatars.discourse-cdn.com/v4/letter/m/dfb087/32.png) [@matkatmusic](https://forum.juce.com/u/matkatmusic)\
**Post date:** [April 11, 2017, 8:55pm UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773/8 "2017-04-11T20:55:13Z")

</div>

But you can’t run a lambda in your code. that’s where ours differ. I should change the name of my class to be “OneShotThread”

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/daniel/32/790_2.png) [@daniel](https://forum.juce.com/u/daniel)\
**Post date:** [April 11, 2017, 9:07pm UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773/9 "2017-04-11T21:07:03Z")

</div>

Ok, I post my ReferenceCountObject solution as well:

```
class OneShotThread : public Thread, public ReferenceCountedObject {
    // identical except run:
    void run() override
    {
        OneShotThread::Ptr holdMe (this);
        while (! threadShouldExit())
        {
            doSomething();
        }
        sendChangeMessage();
    }

    // and the typedef for the ReferenceCountedObject:
    typedef ReferenceCountedObjectPtr<OneShotThread> Ptr;

```

You have two references, one where you actually create it and the other one inside the execution you want to finish. Only when both references are gone, the object will self destruct. So you are on the safe side, no matter how long the thread runs (could be very short as well?)

No manual delete, no timer or anything needed…

EDIT: sorry, works for matkatmusic’s version as well:

```
void run() override {
    OneShotThread::Ptr holdMe (this);
    if( m_task() ) {
        DBG("OK");
    } else {
        DBG("failed");
    }
}

```

And no point in calling “signalThreadShouldExit();” if you don’t use the while loop, because all it does is to set the threadShouldExit() semaphore to allow a clean exit of the threads loop.  
But you don’t have to loop, you just cannot interrupt then, only killing…

---

<div class="post-metadata">

**Author:** ![railjonrogut](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/railjonrogut/32/505_2.png) [@railjonrogut](https://forum.juce.com/u/railjonrogut)\
**Post date:** [April 11, 2017, 9:07pm UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773/10 "2017-04-11T21:07:23Z")

</div>

I’m not a guru on lambdas… but if you need to pass a task pointer this also works:

```
class AutoDeleteThread;

 class AutoDeleteThreadActual : public Thread,
                                public ChangeBroadcaster
{
 public:

    AutoDeleteThreadActual (AutoDeleteThread* pParent, std::function<bool()> task);
    ~AutoDeleteThreadActual();

    void run();

 private:

    AutoDeleteThread* m_pParent;

    std::function<bool()> m_Task;

     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AutoDeleteThreadActual)
};

 class AutoDeleteThread : public ChangeListener
{
 public:

    AutoDeleteThread (std::function<bool()> task)
    {
        m_pAutoDeleteThread = new AutoDeleteThreadActual (this, task);
        m_pAutoDeleteThread->startThread();
    }

    void changeListenerCallback (ChangeBroadcaster* source) override
    {
        if (source == m_pAutoDeleteThread)
            delete this;
    }

 private:

    ScopedPointer<AutoDeleteThreadActual> m_pAutoDeleteThread;

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AutoDeleteThread)
};

```

Implementation:

```
 AutoDeleteThreadActual::AutoDeleteThreadActual (AutoDeleteThread* pParent, std::function<bool()> task) : Thread ("Auto delete thread"),
                                                                                                          m_pParent (pParent),
                                                                                                          m_Task (task)
{
    addChangeListener (m_pParent);
}

 AutoDeleteThreadActual::~AutoDeleteThreadActual()
{
    stopThread (2000);
}

 void AutoDeleteThreadActual::run()
{
    // Edited to removed some unnecessary boilerplate code

    m_Task();

    sendChangeMessage();
}

```

Cheers,

Rail

---

<div class="post-metadata">

**Author:** ![matkatmusic](https://avatars.discourse-cdn.com/v4/letter/m/dfb087/32.png) [@matkatmusic](https://forum.juce.com/u/matkatmusic)\
**Post date:** [April 11, 2017, 9:09pm UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773/11 "2017-04-11T21:09:45Z")

</div>

Rail, can you explain your need for doSomething()?  
In your code, doSomething() would never be called, because no outside objects change m\_bRunning from false to true;

---

<div class="post-metadata">

**Author:** ![railjonrogut](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/railjonrogut/32/505_2.png) [@railjonrogut](https://forum.juce.com/u/railjonrogut)\
**Post date:** [April 11, 2017, 9:11pm UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773/12 "2017-04-11T21:11:15Z")

</div>

it doesn’t have to exist – I just grabbed an existing Thread code which calls a class method… the main thing is you only want to call the task once.

Rail

---

<div class="post-metadata">

**Author:** ![matkatmusic](https://avatars.discourse-cdn.com/v4/letter/m/dfb087/32.png) [@matkatmusic](https://forum.juce.com/u/matkatmusic)\
**Post date:** [April 11, 2017, 9:12pm UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773/13 "2017-04-11T21:12:22Z")

</div>

right, which is why I want to avoid the whole `"while( !threadShouldExit() )"` line altogether.

So, i’m wondering if there is a way shut down a thread as soon as whatever is in the run() method finishes executing.

---

<div class="post-metadata">

**Author:** ![railjonrogut](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/railjonrogut/32/505_2.png) [@railjonrogut](https://forum.juce.com/u/railjonrogut)\
**Post date:** [April 11, 2017, 9:22pm UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773/14 "2017-04-11T21:22:29Z")

</div>

Well you can just call the task from run() but how will you handle if the thread is asked to quit externally? My code only runs the task once then stops the thread. In a perfect world the task should have a callback to quit prematurely too.

Cheers,

Rail

---

<div class="post-metadata">

**Author:** ![matkatmusic](https://avatars.discourse-cdn.com/v4/letter/m/dfb087/32.png) [@matkatmusic](https://forum.juce.com/u/matkatmusic)\
**Post date:** [April 11, 2017, 9:25pm UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773/15 "2017-04-11T21:25:57Z")

</div>

if you look at my original post, you’ll see that i’m talking to a server with a 10-second timeout as the initial task I’m trying to queue up and run once. AFAIK, there’s no way to shut down URL::createInputStream() once you start it running.

I’m all for making this a generic tool anyone can use, but in my particular use case, I just need it to fire off these server connections one time and if they go thru, pass it to a receiver. if they don’t, then report ‘false’

---

<div class="post-metadata">

**Author:** ![railjonrogut](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/railjonrogut/32/505_2.png) [@railjonrogut](https://forum.juce.com/u/railjonrogut)\
**Post date:** [April 11, 2017, 9:29pm UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773/16 "2017-04-11T21:29:15Z")

</div>

Well this will call the task and quit…

```
void AutoDeleteThreadActual::run()
{
    m_Task();

    sendChangeMessage();
}

```

And you can add Daniel’s suggestion as well.

Cheers,

Rail

---

<div class="post-metadata">

**Author:** ![railjonrogut](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/railjonrogut/32/505_2.png) [@railjonrogut](https://forum.juce.com/u/railjonrogut)\
**Post date:** [April 11, 2017, 10:07pm UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773/17 "2017-04-11T22:07:12Z")

</div>

I’ll leave this on my DropBox

[OneShotThread Code example](https://www.dropbox.com/sh/tyu3hmrcdwyswwh/AAB71o1Dyp9FjWvEN1qdPazEa?dl=0)

Rail

---

<div class="post-metadata">

**Author:** ![matkatmusic](https://avatars.discourse-cdn.com/v4/letter/m/dfb087/32.png) [@matkatmusic](https://forum.juce.com/u/matkatmusic)\
**Post date:** [April 11, 2017, 10:17pm UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773/18 "2017-04-11T22:17:55Z")

</div>

Thanks, @Rail_Jon_Rogut and @daniel

Super helpful and insightful solutions!

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [April 12, 2017, 7:57am UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773/19 "2017-04-12T07:57:13Z")

</div>

Good call on asking for this - it’s something I’d been meaning to add to the Thread class, and is really easy to do, I’ll have a shot at it soon…

---

<div class="post-metadata">

**Author:** ![matkatmusic](https://avatars.discourse-cdn.com/v4/letter/m/dfb087/32.png) [@matkatmusic](https://forum.juce.com/u/matkatmusic)\
**Post date:** [April 12, 2017, 8:12am UTC](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773/20 "2017-04-12T08:12:34Z")

</div>

I’m curious what your solution will be, but @Rail_Jon_Rogut pretty much nailed it.

[Next page](https://forum.juce.com/t/one-shot-threads-lambdas-on-their-own-thread-that-auto-delete/21773.md?page=2)
