|
VLink 2.0.0
A high-performance communication middleware
|
Single-threaded serial task dispatcher with integrated timer support. More...
#include <message_loop.h>
Public Types | |
| enum | Type : uint8_t { kNormalType = 0 , kLockfreeType = 1 , kPriorityType = 2 } |
| Queue implementation type. More... | |
| enum | Strategy : uint8_t { kOptimizationStrategy = 0 , kPopStrategy = 1 , kBlockStrategy = 2 } |
| Idle strategy controlling CPU and latency trade-offs. More... | |
| enum | Priority : uint16_t { kNoPriority = 0 , kLowestPriority = 1 , kTimerPriority = 50 , kNormalPriority = 100 , kHighestPriority = std::numeric_limits<uint16_t>::max() } |
Pre-defined task priority levels for kPriorityType loops. More... | |
| using | Callback = std::function<void()> |
| Callback type for tasks and event handlers. | |
Public Member Functions | |
| MessageLoop () | |
Constructs a MessageLoop with kNormalType queue. | |
| MessageLoop (Type type) | |
Constructs a MessageLoop with the specified queue type. | |
| virtual | ~MessageLoop () |
Destructor. Calls quit(true) and waits for the background thread (if any). | |
| void | set_name (const std::string &name) |
| Sets a human-readable name for this loop (visible in profiling tools). | |
| const std::string & | get_name () const |
Returns the name set via set_name(). | |
| Type | get_type () const |
| Returns the queue type this loop was constructed with. | |
| Strategy | get_strategy () const |
| Returns the current idle dispatch strategy. | |
| void | set_strategy (Strategy strategy) |
| Changes the idle dispatch strategy. | |
| void | register_begin_handler (Callback &&callback) |
| Registers a callback invoked once when the loop thread starts. | |
| void | register_end_handler (Callback &&callback) |
| Registers a callback invoked once when the loop thread exits. | |
| void | register_idle_handler (Callback &&callback) |
| Registers a callback invoked each time the task queue becomes empty. | |
| bool | run () |
| Runs the message loop on the calling thread (blocking). | |
| bool | async_run () |
| Starts the message loop on a new background thread (non-blocking). | |
| bool | spin () |
| Runs the loop continuously in a spin mode (blocking; no background thread). | |
| bool | spin_once (bool block=true) |
| Processes one batch of pending tasks and timers. | |
| bool | quit (bool force=false) |
| Requests the loop to exit cleanly. | |
| bool | wait_for_idle (int ms=Timer::kInfinite, bool check=true) |
| Waits until the task queue is drained. | |
| bool | wait_for_quit (int ms=Timer::kInfinite, bool check=true) |
Waits until the loop has fully exited (after quit() was called). | |
| bool | post_task (Callback &&callback) |
| Posts a task to the queue for execution on the loop thread. | |
| bool | post_task_with_priority (Callback &&callback, uint16_t priority) |
Posts a task with an explicit priority (requires kPriorityType loop). | |
| template<typename CallbackT, typename = std::enable_if_t<!std::is_convertible_v<CallbackT, Schedule::RetCallback>>> | |
| Schedule::Status | exec_task (const Schedule::Config &config, CallbackT &&callback) |
Posts a scheduled task and returns a Schedule::Status for chaining callbacks. | |
| template<typename CallbackT, typename = std::enable_if_t<std::is_convertible_v<CallbackT, Schedule::RetCallback>>> | |
| Schedule::RetStatus | exec_task (const Schedule::Config &config, CallbackT &&callback) |
Posts a scheduled task and returns a Schedule::RetStatus for chaining callbacks. | |
| bool | wakeup () |
Wakes the loop thread if it is sleeping (e.g., in kBlockStrategy). | |
| void | reset_lockfree_capacity () |
| Resets the lock-free queue to its initial capacity. | |
| bool | is_running () const |
Returns true if the loop is currently running (started and not quit). | |
| bool | is_ready_to_quit () const |
Returns true if quit() has been called and the loop is winding down. | |
| bool | is_busy () const |
Returns true if the loop is currently executing a task. | |
| size_t | get_task_count () const |
| Returns the number of tasks currently in the queue. | |
| virtual size_t | get_max_task_count () const |
| Returns the maximum queue depth. | |
| virtual size_t | get_max_timer_count () const |
| Returns the maximum number of timers that can be attached to this loop. | |
| virtual uint32_t | get_max_elapsed_time () const |
| Returns the maximum allowed task execution time in milliseconds. | |
| virtual bool | is_in_same_thread () const |
Returns true if the calling thread is the same as the loop thread. | |
| template<class FunctionT, class... ArgsT, typename ResultT = std::invoke_result_t<FunctionT, ArgsT...>> | |
| std::future< ResultT > | invoke_task (FunctionT &&function, ArgsT &&... args) |
Dispatches a callable to the loop thread and returns a std::future for the result. | |
| template<class FunctionT, class... ArgsT, typename ResultT = std::invoke_result_t<FunctionT, ArgsT...>> | |
| std::future< ResultT > | invoke_task_with_priority (FunctionT &&function, uint16_t priority, ArgsT &&... args) |
Dispatches a callable with an explicit priority and returns a std::future. | |
Protected Member Functions | |
| virtual void | on_begin () |
| Called from the loop thread just before the first task is processed. | |
| virtual void | on_end () |
| Called from the loop thread just after the last task has been processed. | |
| virtual void | on_idle () |
| Called from the loop thread each time the queue becomes empty. | |
| virtual void | on_task_changed (Callback &&callback, uint32_t start_time) |
| Called before each task is executed. | |
| virtual void | on_task_timeout (Callback &&callback, uint32_t elapsed_time) |
Called when a task's execution time exceeds get_max_elapsed_time(). | |
Single-threaded serial task dispatcher with integrated timer support.
All tasks and timer callbacks run on a single thread. Thread-safe posting of tasks is allowed from any thread via post_task().
| using vlink::MessageLoop::Callback = std::function<void()> |
Callback type for tasks and event handlers.
| enum vlink::MessageLoop::Priority : uint16_t |
Pre-defined task priority levels for kPriorityType loops.
Higher numeric values are dispatched first. Custom priority values may be used between kLowestPriority and kHighestPriority.
| enum vlink::MessageLoop::Strategy : uint8_t |
| enum vlink::MessageLoop::Type : uint8_t |
| vlink::MessageLoop::MessageLoop | ( | ) |
|
explicit |
Constructs a MessageLoop with the specified queue type.
| type | Queue implementation to use. |
|
virtual |
Destructor. Calls quit(true) and waits for the background thread (if any).
| bool vlink::MessageLoop::async_run | ( | ) |
Starts the message loop on a new background thread (non-blocking).
Returns immediately. The background thread runs until quit() is called.
true if the thread was started; false if already running. | Schedule::RetStatus vlink::MessageLoop::exec_task | ( | const Schedule::Config & | config, |
| CallbackT && | callback ) |
Posts a scheduled task and returns a Schedule::RetStatus for chaining callbacks.
This overload is for callbacks returning bool. Chain on_then (fires if true) and on_else (fires if false) on the returned status.
| CallbackT | Callable type returning bool. |
| config | Scheduling configuration. |
| callback | Callable to execute. |
Schedule::RetStatus for chaining. | Schedule::Status vlink::MessageLoop::exec_task | ( | const Schedule::Config & | config, |
| CallbackT && | callback ) |
Posts a scheduled task and returns a Schedule::Status for chaining callbacks.
Details.
This overload is for callbacks returning void. The Schedule::Config can specify a delay, priority, schedule timeout and execution timeout. Chain on_schedule_timeout, on_execution_timeout or on_catch on the returned status.
| CallbackT | Callable type returning void. |
| config | Scheduling configuration. |
| callback | Callable to execute. |
Schedule::Status for chaining.
|
nodiscardvirtual |
Returns the maximum allowed task execution time in milliseconds.
When a task exceeds this duration, on_task_timeout() is called. Returns 0 to disable timeout checking.
Reimplemented in vlink::DiscoveryReporter, vlink::DiscoveryViewer, vlink::ProxyAPI, and vlink::ProxyServer.
|
nodiscardvirtual |
Returns the maximum queue depth.
kMaxTaskSize (10000) by default. Reimplemented in vlink::DatabaseReader, vlink::DatabaseWriter, vlink::DiscoveryReporter, vlink::DiscoveryViewer, vlink::McapReader, vlink::McapWriter, vlink::ProxyAPI, and vlink::ProxyServer.
|
nodiscardvirtual |
Returns the maximum number of timers that can be attached to this loop.
kMaxTimerSize (100) by default.
|
nodiscard |
Returns the name set via set_name().
|
nodiscard |
Returns the current idle dispatch strategy.
|
nodiscard |
Returns the number of tasks currently in the queue.
|
nodiscard |
Returns the queue type this loop was constructed with.
|
inlinenodiscard |
Dispatches a callable to the loop thread and returns a std::future for the result.
Thread-safe. The future becomes ready after the callable is executed on the loop thread.
.get() on the future from the same thread as the loop; doing so will deadlock.| FunctionT | Callable type. |
| ArgsT | Argument types. |
| ResultT | Return type (deduced). |
| function | Callable to dispatch. |
| args | Arguments forwarded to the callable. |
std::future<ResultT> that becomes ready when the task completes.
|
inlinenodiscard |
Dispatches a callable with an explicit priority and returns a std::future.
Same as invoke_task() but the task is enqueued at priority level. Requires a kPriorityType loop for priority to take effect.
| FunctionT | Callable type. |
| ArgsT | Argument types. |
| ResultT | Return type (deduced). |
| function | Callable to dispatch. |
| priority | Dispatch priority. |
| args | Arguments forwarded to the callable. |
std::future<ResultT>.
|
nodiscard |
Returns true if the loop is currently executing a task.
true if a task callback is in progress on the loop thread.
|
nodiscardvirtual |
Returns true if the calling thread is the same as the loop thread.
Used internally to detect if a task is calling back into the loop synchronously. For MultiLoop, returns true if the caller is any of the worker threads.
true if called from the loop's own thread. Reimplemented in vlink::MultiLoop.
|
nodiscard |
Returns true if quit() has been called and the loop is winding down.
true if the loop is in the process of quitting.
|
nodiscard |
Returns true if the loop is currently running (started and not quit).
true if the loop is active.
|
protectedvirtual |
Called from the loop thread just before the first task is processed.
Override in subclasses to perform per-thread initialisation.
Reimplemented in vlink::DatabaseReader, vlink::DatabaseWriter, vlink::DiscoveryReporter, vlink::DiscoveryViewer, vlink::McapReader, vlink::McapWriter, vlink::MultiLoop, vlink::ProxyAPI, and vlink::ProxyServer.
|
protectedvirtual |
Called from the loop thread just after the last task has been processed.
Override in subclasses to perform per-thread cleanup.
Reimplemented in vlink::DatabaseReader, vlink::DatabaseWriter, vlink::DiscoveryReporter, vlink::DiscoveryViewer, vlink::McapReader, vlink::McapWriter, vlink::MultiLoop, vlink::ProxyAPI, and vlink::ProxyServer.
|
protectedvirtual |
Called from the loop thread each time the queue becomes empty.
Override in subclasses to perform idle work (e.g., statistics updates).
|
protectedvirtual |
Called before each task is executed.
Provides the task callback and the monotonic start timestamp (in milliseconds). Override to implement per-task tracing or accounting.
| callback | The task about to be executed. |
| start_time | Millisecond timestamp at which the task was dequeued. |
Reimplemented in vlink::MultiLoop.
|
protectedvirtual |
Called when a task's execution time exceeds get_max_elapsed_time().
Override to log or handle slow tasks.
| callback | The task that timed out. |
| elapsed_time | Actual execution time in milliseconds. |
| bool vlink::MessageLoop::post_task | ( | Callback && | callback | ) |
Posts a task to the queue for execution on the loop thread.
Thread-safe. Returns false if the loop is shutting down or the queue is full (kMaxTaskSize).
| callback | Task to execute. |
true if the task was successfully enqueued. | bool vlink::MessageLoop::post_task_with_priority | ( | Callback && | callback, |
| uint16_t | priority ) |
Posts a task with an explicit priority (requires kPriorityType loop).
Tasks with higher priority values are dispatched before lower-priority tasks. For kNormalType and kLockfreeType loops, priority is ignored and the task is enqueued in FIFO order.
| callback | Task to execute. |
| priority | Dispatch priority. |
true if enqueued successfully. | bool vlink::MessageLoop::quit | ( | bool | force = false | ) |
Requests the loop to exit cleanly.
Signals the loop to stop after finishing the current task. If force is true, remaining queued tasks are discarded.
| force | If true, discard pending tasks. Default: false. |
true on success. | void vlink::MessageLoop::register_begin_handler | ( | Callback && | callback | ) |
Registers a callback invoked once when the loop thread starts.
| callback | Called from the loop thread before the first task is processed. |
| void vlink::MessageLoop::register_end_handler | ( | Callback && | callback | ) |
Registers a callback invoked once when the loop thread exits.
| callback | Called from the loop thread after the last task has been processed. |
| void vlink::MessageLoop::register_idle_handler | ( | Callback && | callback | ) |
Registers a callback invoked each time the task queue becomes empty.
| callback | Called from the loop thread on each idle cycle. |
| void vlink::MessageLoop::reset_lockfree_capacity | ( | ) |
Resets the lock-free queue to its initial capacity.
Only applicable to kLockfreeType loops. Useful after a large burst of tasks to reclaim internal capacity bookkeeping.
| bool vlink::MessageLoop::run | ( | ) |
Runs the message loop on the calling thread (blocking).
Processes tasks and fires timers until quit() is called.
true if the loop ran and exited normally; false if already running. | void vlink::MessageLoop::set_name | ( | const std::string & | name | ) |
Sets a human-readable name for this loop (visible in profiling tools).
| name | Name string. |
| void vlink::MessageLoop::set_strategy | ( | Strategy | strategy | ) |
Changes the idle dispatch strategy.
| strategy | New strategy. Takes effect on the next idle cycle. |
| bool vlink::MessageLoop::spin | ( | ) |
Runs the loop continuously in a spin mode (blocking; no background thread).
Calls spin_once() repeatedly until quit() is called.
true on normal exit. | bool vlink::MessageLoop::spin_once | ( | bool | block = true | ) |
Processes one batch of pending tasks and timers.
Intended for integration into an existing event loop.
| block | If true and the queue is empty, blocks until a task arrives. If false, returns immediately if the queue is empty. Default: true. |
true if at least one task was processed; false if the loop should quit. | bool vlink::MessageLoop::wait_for_idle | ( | int | ms = Timer::kInfinite, |
| bool | check = true ) |
Waits until the task queue is drained.
| ms | Maximum wait time in milliseconds. Timer::kInfinite for unlimited. Default: kInfinite. |
| check | If true, also verify the loop is in the idle state. Default: true. |
true if the queue drained within the timeout. | bool vlink::MessageLoop::wait_for_quit | ( | int | ms = Timer::kInfinite, |
| bool | check = true ) |
Waits until the loop has fully exited (after quit() was called).
| ms | Maximum wait time in milliseconds. Timer::kInfinite for unlimited. Default: kInfinite. |
| check | If true, also verify the loop thread has joined. Default: true. |
true if the loop exited within the timeout. | bool vlink::MessageLoop::wakeup | ( | ) |
Wakes the loop thread if it is sleeping (e.g., in kBlockStrategy).
true if the wakeup signal was sent.