Add JUCE_DECLARE_WEAK_REFERENCEABLE to TimeSliceThread

Hi there,

would it be possible to add the JUCE_DECLARE_WEAK_REFERENCEABLE to TimeSliceThread?
I want to keep track in the TimeSliceClient, from which TimeSliceThread I need to remove it in the destructor.
The WeakReference is appropriate, since if the thread was deleted, we don’t bother to remove any longer.

Thanks, much appreciated…

Hmm, WeakReference isn’t thread-safe so I don’t think I’d want us to encourage its use in thread-y situations. If this set-up works for your app, can’t you just inherit your own class from TimeSliceThread and enable it there?

Yes, I can do that…
however, to be honest, if deleting the threads happens on one thread, and the deleting of the thread clients on a different thread, I think the user is already in trouble. If you really want to harness against this situation, you could only enforce both to be on the message thread, but that is limiting the use too much I think.

Or you have to invent a thread safe WeakReference, I’m not sure, if that is realistic.

It is only 9 lines of code on my end anyway, I just didn’t see a problem here. For me the TimeSliceThread was a hands-off class, since it has no virtual methods.

class WRTimeSliceThread : public TimeSliceThread
{
public:
    WRTimeSliceThread (const String &threadName) : TimeSliceThread (threadName) {}
    ~WRTimeSliceThread() { masterReference.clear(); }
private:
    JUCE_DECLARE_WEAK_REFERENCEABLE (WRTimeSliceThread)
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WRTimeSliceThread)
};

class MyWorker : public TimeSliceClient
{
public:
    MyWorker() = default;
    virtual ~MyWorker()
    {
        if (workingThread != nullptr)
            workingThread.removeTimeSliceClient (this);
            // this blocks until removing has happened, so it's safe to continue destruction
    }
    void addToTimeSliceThread (WRTimeSliceThread* thread)
    {
        if (workingThread != nullptr)
            workingThread.removeTimeSliceClient (this);

        workingThread = thread;

        if (workingThread != nullptr)
            workingThread.addTimeSliceClient (this);
    }
    // ...

private:
    WeakReference<WRTimeSliceThread> workingThread;
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MyWorker)
};

IMHO this simplifies the workflow a lot, compared to keeping track in an external data structure, which client was added to which thread.

…any chance @jules? :wink:

It would be great to avoid inheriting the Thread, and I don’t see an alternative without a lot of maps introducing maintenance code, that could easily be avoided by just adding the WEAK_REFERENCEABLE macro.