Asyncupdater crash

Where am I being an idiot here.

I’ve got a class which is supposed to let me call any number of functions on the message thread safely, only it crashes. Here’s the class:

class MultiAsyncUpdater  AsyncUpdater
{
public:
	void callOnMessageThread(std::function<void()> callback)
	{
		ScopedLock l(lock);
		queue.push_back(std::move(callback));
		triggerAsyncUpdate();
	}

private:
	void handleAsyncUpdate() override
	{
		lock.enter();
		auto queueCopy = queue;
		queue.clear();
		lock.exit();

		for (auto & func : queueCopy)
			func();
	}

	CriticalSection lock;
	std::vector<std::function<void()>> queue;
};

I’m using it like this:

class X 
{
  void backgroundThread()
  {
      asyncUpdater.callOnMessageThread([this](){ /* some lambda stuff that crashes */ });

      //...
  }

 ~X()
  {
    LC_ASSERT_THIS_IS_THE_MESSAGE_THREAD;
    JCF_LOG_DESTRUCTOR;
  }

  MultiAsyncUpdater asyncUpdater;

};

Sometimes the AsyncUpdater inside MultiAsyncUpdater inside X is triggered after the deletion of X. How is this possible? What am I missing?

Looking inside AsyncUpdater::AsyncUpdaterMessage when it crashes I’ve got:
owner = 0x13a05408 {activeMessage={referencedObject=0xdddddddd

The Asyncupdater appears to have been deleted.

Ah hang on, unless the AsyncUpdater was deleting DURING the callback…

Ah yeah, that’s the secret. Found it with SystemStats::getStackBacktrace() :slight_smile:

Turns out the AsyncUpdater was being deleted during the callback…

i believe you should call asyncUpdater.cancelPendingUpdate() in your destructor.

I think it cancels in the destructor of AsyncUpdater, so as long as the destructor is called on the main thread things are good…