You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
1.9 KiB
C++

#pragma once
#include <thread>
#include <atomic>
#include <memory>
#include <queue>
#include <mutex>
#include <functional>
#include <stdexcept>
#include <iostream>
#include "DllDefines.h"
/*
* @link : https://www.cppstories.com/2019/12/threading-loopers-cpp17/
*/
using Runnable = std::function<void()>;
class UTILITYDLL CRunnerTask
{
// dispatch class
public:
using Runnable = std::function<void()>;
class CDispatcher
{
friend class CRunnerTask; // Allow the looper to access the private constructor.
public:
// Yet to be defined method, which will post the runnable
// into the looper-queue.
bool post(CRunnerTask::Runnable&& aRunnable)
{
return mAssignedRunner.post(std::move(aRunnable));
}
private: // construction, since we want the looper to expose it's dispatcher exclusively!
CDispatcher(CRunnerTask& aLooper)
: mAssignedRunner(aLooper)
{}
private:
// Store a reference to the attached looper in order to
// emplace tasks into the queue.
CRunnerTask& mAssignedRunner;
};
// ctor
CRunnerTask();
// Copy denied, Move to be implemented
~CRunnerTask();
// To be called, once the runner should start looping.
bool run();
void stop();
bool running() const;
Runnable next();
std::shared_ptr<CDispatcher> getDispatcher()
{
return mDispatcher;
}
private:
// Conditionally-infinite loop doing sth. iteratively
void runFunc();
// Shared implementation of exiting the loop-function and joining
// to the main thread.
void abortAndJoin();
bool post(Runnable&& aRunnable);
// attributes
std::thread mThread;
std::atomic_bool mRunning;
std::atomic_bool mAbortRequested;
//
std::recursive_mutex mRunnablesMutex;
std::queue<Runnable> mRunnables;
std::shared_ptr<CDispatcher> mDispatcher;
};