33#include <unordered_map>
69template <
typename TParams>
73 using id_t = std::thread::id;
74 using Lock = std::lock_guard<std::mutex>;
112 std::unordered_map<std::type_index, std::unique_ptr<Slot>> slots_;
113 std::mutex mtx_slots_;
119 std::atomic_bool flag_running_;
120 std::atomic_bool flag_exited_;
121 std::mutex mtx_thread_proc_;
136 , flag_running_{false}
137 , flag_exited_{false}
146 if (thread_.joinable()) {
219 template <
typename Derived,
typename T>
226 static_assert(std::is_base_of_v<Worker<Params>, Derived>,
227 "Derived must inherit from tec::Worker");
228 std::type_index ndx = std::type_index(
typeid(T));
232 if (
auto slot = slots_.find(ndx); slot != slots_.end()) {
238 slots_[ndx] = std::make_unique<Slot>(
242 auto derived =
dynamic_cast<Derived*
>(worker);
243 (derived->*callback)(msg);
257 auto ndx = std::type_index(msg.type());
258 if (
auto slot = slots_.find(ndx); slot != slots_.end()) {
259 slot->second->callback(slot->second->worker, std::cref(msg));
272 template <
typename Params>
288 wt.thread_id_ = std::this_thread::get_id();
290 wt.sig_running_.
wait();
295 if (wt.flag_exited_) {
303 TEC_TRACE(
"on_init() returned {}.", wt.status_);
307 wt.sig_inited_.
set();
321 wt.flag_exited_ =
true;
326 TEC_TRACE(
"leaving message loop, {} message(s) left in queue...", wt.mq_.
size());
334 TEC_TRACE(
"on_exit() returned {}.", wt.status_);
360 thread_ = std::thread(details<Params>::thread_proc, std::ref(*
this));
373 Lock lk{mtx_thread_proc_};
383 flag_running_ =
true;
389 TEC_TRACE(
"waiting for `sig_inited' signalled ...");
404 Lock lk{mtx_thread_proc_};
406 if (!thread_.joinable()) {
410 if (!flag_running_) {
411 TEC_TRACE(
"Exiting the suspended thread...");
418 if (status_ && !flag_exited_) {
425 TEC_TRACE(
"waiting for thread {} to finish ...",
id());
427 TEC_TRACE(
"thread {} finished OK.",
id());
Abstract interface for a daemon that runs in a separate thread.
Definition tec_daemon.hpp:47
A thread-safe queue implementation for storing and retrieving elements of type T.
Definition tec_queue.hpp:52
void enqueue(T &&t)
Adds an element to the back of the queue.
Definition tec_queue.hpp:83
T dequeue(void)
Retrieves and removes the front element from the queue.
Definition tec_queue.hpp:95
std::size_t size() const
Returns the current number of elements in the queue.
Definition tec_queue.hpp:111
A thread-safe signal mechanism for inter-thread synchronization.
Definition tec_signal.hpp:44
void set()
Sets the signal to the signaled state and notifies all waiting threads.
Definition tec_signal.hpp:72
void wait() const
Waits indefinitely until the signal is set.
Definition tec_signal.hpp:85
A class implementing message processing as a daemon.
Definition tec_worker.hpp:70
constexpr const Params & params() const
Retrieves the worker's configuration parameters.
Definition tec_worker.hpp:161
id_t id() const
Retrieves the worker thread's ID.
Definition tec_worker.hpp:155
TParams Params
Type alias for worker parameters.
Definition tec_worker.hpp:72
virtual void dispatch(const Message &msg)
Dispatches a message to its registered callback.
Definition tec_worker.hpp:256
std::lock_guard< std::mutex > Lock
Type alias for mutex lock guard.
Definition tec_worker.hpp:74
std::thread::id id_t
Type alias for thread ID.
Definition tec_worker.hpp:73
virtual Status on_init()
Default callback invoked during worker thread initialization.
Definition tec_worker.hpp:346
const Signal & sig_terminated() const override
Retrieves the signal indicating the worker has terminated.
Definition tec_worker.hpp:168
Status terminate() override
Terminates the worker thread.
Definition tec_worker.hpp:403
Status run() override
Starts the worker thread's message polling.
Definition tec_worker.hpp:372
std::function< void(Worker< Params > *, const Message &)> CallbackFunc
Type alias for a callback function to process messages.
Definition tec_worker.hpp:80
virtual ~Worker()
Destructor that ensures proper thread termination.
Definition tec_worker.hpp:145
Params params_
Configuration parameters for the worker.
Definition tec_worker.hpp:83
void send(Message &&msg) override
Sends a message to the worker's queue.
Definition tec_worker.hpp:177
Worker(const Params ¶ms)
Constructs a worker.
Definition tec_worker.hpp:133
virtual Status create_thread()
Create the Daemon's thread in suspended state.
Definition tec_worker.hpp:359
void register_callback(Derived *worker, void(Derived::*callback)(const Message &msg))
Registers a callback for a specific message type.
Definition tec_worker.hpp:220
virtual Status on_exit()
Default callback invoked when exiting the worker thread.
Definition tec_worker.hpp:353
Status make_request(Request &&req, Reply &&rep) override
Sends a request and waits for a reply in a daemon thread.
Definition tec_worker.hpp:195
#define TEC_ENTER(name)
Logs an entry message for a named context (e.g., function).
Definition tec_trace.hpp:211
#define TEC_TRACE(...)
Logs a formatted trace message.
Definition tec_trace.hpp:222
A message used for RPC-style calls.
Definition tec_message.hpp:89
Helper struct to signal termination on exit.
Definition tec_signal.hpp:110
Defines the minimal contract for any long-lived service or processing component.
Common definitions and utilities for the tec namespace.
Defines a flexible message type and helper functions for the tec namespace.
Message nullmsg() noexcept
Creates a null message.
Definition tec_message.hpp:67
bool is_null(const Message &msg) noexcept
Checks if a message is null.
Definition tec_message.hpp:75
std::any Reply
Type alias for a reply object that can hold any object.
Definition tec_message.hpp:55
std::any Message
Type alias for a message that can hold any object.
Definition tec_message.hpp:43
std::any Request
Type alias for a request object that can hold any object.
Definition tec_message.hpp:49
auto name(const Message &msg) noexcept
Retrieves the type name of a message's content for registering the corresponding message handler.
Definition tec_message.hpp:84
Thread-safe queue implementation.
Defines error handling types and utilities for the tec namespace.
Provides a thread-safe tracing utility for debugging in the tec namespace.