|
VLink
2.0.0
A high-performance communication middleware
|
Serial task dispatcher with selectable queue backend and bounded timer registry. More...
#include <message_loop.h>
Classes | |
| struct | AliveState |
| Lifetime gate shared with cross-thread observers. More... | |
Public Types | |
| enum | Type : uint8_t { kNormalType = 0 , kLockfreeType = 1 , kPriorityType = 2 } |
| Internal queue implementation type. More... | |
| enum | Strategy : uint8_t { kOptimizationStrategy = 0 , kPopStrategy = 1 , kBlockStrategy = 2 } |
| Back-pressure strategy applied when the bounded queue is at capacity. More... | |
| enum | Priority : uint16_t { kNoPriority = 0 , kLowestPriority = 1 , kTimerPriority = 50 , kNormalPriority = 100 , kHighestPriority = std::numeric_limits<uint16_t>::max() } |
Built-in priority levels for kPriorityType loops; higher values dispatch first. More... | |
| using | Callback = MoveFunction< void()> |
| Callback type for tasks and event handlers. More... | |
Public Member Functions | |
| MessageLoop () | |
Constructs a loop with the default kNormalType queue. More... | |
| MessageLoop (Type type) | |
| Constructs a loop with the given queue type. More... | |
| virtual | ~MessageLoop () |
| Destructor; requests quit and joins the dispatcher thread if needed. More... | |
| void | set_name (const std::string &name) |
| Sets a human-readable name visible to profiling tools. More... | |
| const std::string & | get_name () const |
Returns the loop name set via set_name. More... | |
| Type | get_type () const |
| Returns the queue type this loop was constructed with. More... | |
| Strategy | get_strategy () const |
| Returns the active back-pressure strategy. More... | |
| void | set_strategy (Strategy strategy) |
| Replaces the back-pressure strategy. More... | |
| void | register_begin_handler (Callback &&callback) |
| Registers a callback fired once at loop thread startup. More... | |
| void | register_end_handler (Callback &&callback) |
| Registers a callback fired once when the loop thread exits. More... | |
| void | register_idle_handler (Callback &&callback) |
| Registers a callback fired every time the queue becomes empty. More... | |
| bool | run () |
Runs the loop on the calling thread until quit is requested. More... | |
| bool | async_run () |
| Starts the loop on a new background thread. More... | |
| bool | spin () |
Alias of run blocking the calling thread. More... | |
| bool | spin_once (bool block=true) |
| Processes one batch of pending tasks and timers on the calling thread. More... | |
| bool | quit (bool force=false) |
| Requests the loop to exit. More... | |
| bool | wait_for_quit (int ms=Timer::kInfinite, bool check=true) |
| Waits until the loop has fully exited. More... | |
| bool | post_task (Callback &&callback) |
| Posts a task for execution on the loop thread. More... | |
| TaskHandle | post_task_handle (Callback &&callback, const PostTaskOptions &options={}) |
Tracked variant of post_task returning a TaskHandle. More... | |
| bool | post_task_with_priority (Callback &&callback, uint16_t priority) |
Posts a task with an explicit priority on a kPriorityType loop. More... | |
| TaskHandle | post_task_with_priority_handle (Callback &&callback, uint16_t priority, const PostTaskOptions &options={}) |
Tracked variant of post_task_with_priority returning a TaskHandle. More... | |
| 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) |
Schedules a void-returning callable and returns a chainable Schedule::Status. More... | |
| 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) |
Schedules a bool-returning callable and returns a chainable Schedule::RetStatus. More... | |
| bool | wakeup () |
| Wakes the loop thread if it is suspended in its idle wait. More... | |
| void | reset_lockfree_capacity () |
| Recreates the lock-free queue, clearing all queued tasks and counters. More... | |
| bool | is_running () const |
| Reports whether the loop is currently running. More... | |
| bool | is_ready_to_quit () const |
Reports whether quit has been requested and the loop is winding down. More... | |
| bool | is_busy () const |
| Reports whether the loop is currently executing a task. More... | |
| size_t | get_task_count () const |
| Returns the current pending task count. More... | |
| virtual bool | wait_for_idle (int ms=Timer::kInfinite, bool check=true) |
| Waits until the loop has drained its queue and is not executing a task. More... | |
| virtual size_t | get_max_task_count () const |
| Returns the maximum queue depth. More... | |
| virtual size_t | get_max_timer_count () const |
| Returns the maximum number of timers that can be attached. More... | |
| virtual uint32_t | get_max_elapsed_time () const |
| Returns the maximum allowed task execution time in milliseconds. More... | |
| virtual bool | is_in_same_thread () const |
| Reports whether the calling thread is owned by this loop. More... | |
| std::shared_ptr< AliveState > | get_alive_state () const |
| Returns the shared lifetime flag used by cross-thread bridges. More... | |
| 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. More... | |
| 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) |
Priority variant of invoke_task; requires a kPriorityType loop. More... | |
Protected Member Functions | |
| virtual void | on_begin () |
| Hook invoked once on the loop thread before the first task runs. More... | |
| virtual void | on_end () |
| Hook invoked once on the loop thread after the last task runs. More... | |
| virtual void | on_idle () |
| Hook invoked on the loop thread each time the queue becomes empty. More... | |
| virtual void | on_task_changed (Callback &&callback, uint32_t start_time) |
| Dispatches a ready task on the loop thread. More... | |
| virtual void | on_task_timeout (Callback &&callback, uint32_t elapsed_time) |
Hook invoked when a task exceeds get_max_elapsed_time(). More... | |
Serial task dispatcher with selectable queue backend and bounded timer registry.
Owns a thread that pulls tasks from a bounded queue and fires timer callbacks. Other threads may post via post_task, post_task_with_priority, invoke_task or exec_task from any context. The class is the building block of MultiLoop and the engine target of GraphTask::execute.
| using vlink::MessageLoop::Callback = MoveFunction<void()> |
Callback type for tasks and event handlers.
Move-only so move-only targets such as std::packaged_task or lambdas holding std::unique_ptr can be posted directly without a shared trampoline.
| enum vlink::MessageLoop::Priority : uint16_t |
| enum vlink::MessageLoop::Strategy : uint8_t |
Back-pressure strategy applied when the bounded queue is at capacity.
Idle dispatch is unconditionally cv-driven; this enum only affects the push side.
| enum vlink::MessageLoop::Type : uint8_t |
| vlink::MessageLoop::MessageLoop | ( | ) |
Constructs a loop with the default kNormalType queue.
|
explicit |
Constructs a loop with the given queue type.
| type | Queue implementation. |
|
virtual |
Destructor; requests quit and joins the dispatcher thread if needed.
| bool vlink::MessageLoop::async_run | ( | ) |
Starts the loop on a new background thread.
true when the thread was started; false when the loop is already running. | Schedule::Status vlink::MessageLoop::exec_task | ( | const Schedule::Config & | config, |
| CallbackT && | callback | ||
| ) |
Schedules a void-returning callable and returns a chainable Schedule::Status.
Schedule::Config carries the delay, priority and timeout fields. The returned status supports on_catch / on_schedule_timeout / on_execution_timeout chaining. Posting is deferred until the handle is committed (when the temporary handle is destroyed at the end of the fluent expression), so every continuation is registered before the task runs. A caller that stores the handle instead of consuming it inline must call Schedule::Status::dispatch() to post the task and learn whether it was accepted.
| CallbackT | Callable returning void. |
| config | Scheduling envelope. |
| callback | Callable to schedule. |
| Schedule::RetStatus vlink::MessageLoop::exec_task | ( | const Schedule::Config & | config, |
| CallbackT && | callback | ||
| ) |
Schedules a bool-returning callable and returns a chainable Schedule::RetStatus.
on_then fires when the callable returns true; on_else fires when it returns false. Posting is deferred until the handle is committed (destroyed at the end of the fluent expression), guaranteeing every continuation is registered first; a stored handle must call Schedule::Status::dispatch() to post it.
| CallbackT | Callable returning bool. |
| config | Scheduling envelope. |
| callback | Callable to schedule. |
| std::shared_ptr<AliveState> vlink::MessageLoop::get_alive_state | ( | ) | const |
Returns the shared lifetime flag used by cross-thread bridges.
The returned AliveState outlives this loop. Adapters that need to post continuations back to this loop should lock mtx, re-check alive, and only call back while still holding the lock.
|
virtual |
Returns the maximum allowed task execution time in milliseconds.
Tasks exceeding this duration trigger on_task_timeout. Zero disables the check.
Reimplemented in vlink::ProxyServer, vlink::ProxyAPI, vlink::DiscoveryViewer, and vlink::DiscoveryReporter.
|
virtual |
Returns the maximum queue depth.
kMaxTaskSize (10000) by default. Reimplemented in vlink::ProxyServer, vlink::ProxyAPI, vlink::VDBWriter, vlink::VDBReader, vlink::VCAPWriter, vlink::VCAPReader, vlink::DiscoveryViewer, and vlink::DiscoveryReporter.
|
virtual |
Returns the maximum number of timers that can be attached.
kMaxTimerSize (100) by default. | const std::string& vlink::MessageLoop::get_name | ( | ) | const |
Returns the loop name set via set_name.
| Strategy vlink::MessageLoop::get_strategy | ( | ) | const |
Returns the active back-pressure strategy.
| size_t vlink::MessageLoop::get_task_count | ( | ) | const |
Returns the current pending task count.
| Type vlink::MessageLoop::get_type | ( | ) | const |
Returns the queue type this loop was constructed with.
|
inline |
Dispatches a callable to the loop thread and returns a std::future for the result.
Thread-safe. When posting fails the returned future becomes ready with std::future_error / broken_promise.
.get() on the future from the loop's own thread; doing so deadlocks.| FunctionT | Callable type. |
| ArgsT | Argument types. |
| ResultT | Return type (deduced). |
| function | Callable to dispatch. |
| args | Arguments forwarded to function. |
|
inline |
Priority variant of invoke_task; requires a kPriorityType loop.
| FunctionT | Callable type. |
| ArgsT | Argument types. |
| ResultT | Return type (deduced). |
| function | Callable to dispatch. |
| priority | Dispatch priority. |
| args | Arguments forwarded to function. |
| bool vlink::MessageLoop::is_busy | ( | ) | const |
Reports whether the loop is currently executing a task.
true while a callback is on the call stack inside the loop.
|
virtual |
Reports whether the calling thread is owned by this loop.
Detects callbacks that re-enter the loop synchronously. For MultiLoop this also covers worker threads of the underlying pool.
true when called from a thread belonging to this loop. Reimplemented in vlink::MultiLoop.
| bool vlink::MessageLoop::is_ready_to_quit | ( | ) | const |
Reports whether quit has been requested and the loop is winding down.
true once quit has been observed. | bool vlink::MessageLoop::is_running | ( | ) | const |
Reports whether the loop is currently running.
true between a successful start and the corresponding quit.
|
protectedvirtual |
Hook invoked once on the loop thread before the first task runs.
Subclasses override to perform per-thread initialisation.
Reimplemented in vlink::ProxyServer, vlink::ProxyAPI, vlink::VDBWriter, vlink::VDBReader, vlink::VCAPWriter, vlink::VCAPReader, vlink::DiscoveryViewer, vlink::DiscoveryReporter, and vlink::MultiLoop.
|
protectedvirtual |
Hook invoked once on the loop thread after the last task runs.
Subclasses override to perform per-thread cleanup.
Reimplemented in vlink::ProxyServer, vlink::ProxyAPI, vlink::VDBWriter, vlink::VDBReader, vlink::VCAPWriter, vlink::VCAPReader, vlink::DiscoveryViewer, vlink::DiscoveryReporter, and vlink::MultiLoop.
|
protectedvirtual |
Hook invoked on the loop thread each time the queue becomes empty.
Subclasses override to perform idle bookkeeping.
|
protectedvirtual |
Dispatches a ready task on the loop thread.
The default implementation invokes callback inline. Subclasses such as MultiLoop override to redirect the call to a worker pool; overrides that do not forward must invoke callback themselves or the task is silently dropped.
| callback | Task to dispatch. |
| start_time | Millisecond steady_clock timestamp captured at enqueue time, or 0 when elapsed tracking is disabled. |
Reimplemented in vlink::MultiLoop.
|
protectedvirtual |
Hook invoked when a task exceeds get_max_elapsed_time().
| callback | Task that timed out. |
| elapsed_time | Actual execution time in milliseconds. |
| bool vlink::MessageLoop::post_task | ( | Callback && | callback | ) |
Posts a task for execution on the loop thread.
Thread-safe. Returns false when the loop is quitting or the configured Strategy cannot make room for the new task.
| callback | Task to post. |
true when the task was enqueued. | TaskHandle vlink::MessageLoop::post_task_handle | ( | Callback && | callback, |
| const PostTaskOptions & | options = {} |
||
| ) |
Tracked variant of post_task returning a TaskHandle.
| callback | Task to post. |
| options | Optional overflow / drop / cancellation policy. |
| bool vlink::MessageLoop::post_task_with_priority | ( | Callback && | callback, |
| uint16_t | priority | ||
| ) |
Posts a task with an explicit priority on a kPriorityType loop.
Higher priority values dispatch first. Non-priority loops reject the call and return false.
| callback | Task to post. |
| priority | Dispatch priority in [kLowestPriority, kHighestPriority]. |
true when the task was enqueued. | TaskHandle vlink::MessageLoop::post_task_with_priority_handle | ( | Callback && | callback, |
| uint16_t | priority, | ||
| const PostTaskOptions & | options = {} |
||
| ) |
Tracked variant of post_task_with_priority returning a TaskHandle.
| callback | Task to post. |
| priority | Dispatch priority. |
| options | Optional overflow / drop / cancellation policy. |
| bool vlink::MessageLoop::quit | ( | bool | force = false | ) |
Requests the loop to exit.
With force == false the current batch finishes and the loop exits afterwards. With force == true the in-flight batch is also aborted. Tasks queued after the request are rejected. Returns false when quit had already been called (only meaningful when force is false).
| force | When true, also discards the in-flight batch. Default: false. |
true when the quit signal was accepted. | void vlink::MessageLoop::register_begin_handler | ( | Callback && | callback | ) |
Registers a callback fired once at loop thread startup.
Must be registered before run / async_run; later calls are ignored.
| callback | Startup handler. |
| void vlink::MessageLoop::register_end_handler | ( | Callback && | callback | ) |
Registers a callback fired once when the loop thread exits.
Must be registered before run / async_run; later calls are ignored.
| callback | Shutdown handler. |
| void vlink::MessageLoop::register_idle_handler | ( | Callback && | callback | ) |
Registers a callback fired every time the queue becomes empty.
Must be registered before run / async_run; later calls are ignored.
| callback | Idle handler. |
| void vlink::MessageLoop::reset_lockfree_capacity | ( | ) |
Recreates the lock-free queue, clearing all queued tasks and counters.
Applies only to kLockfreeType loops; on other types the call is a no-op. Must be invoked while the loop is stopped; calls made while it is running are logged and skipped.
| bool vlink::MessageLoop::run | ( | ) |
Runs the loop on the calling thread until quit is requested.
true after a normal exit; false when the loop is already running. | void vlink::MessageLoop::set_name | ( | const std::string & | name | ) |
Sets a human-readable name visible to profiling tools.
| name | Loop name. |
| void vlink::MessageLoop::set_strategy | ( | Strategy | strategy | ) |
Replaces the back-pressure strategy.
| strategy | New strategy; takes effect on the next full-queue push. |
| bool vlink::MessageLoop::spin | ( | ) |
Alias of run blocking the calling thread.
run. | bool vlink::MessageLoop::spin_once | ( | bool | block = true | ) |
Processes one batch of pending tasks and timers on the calling thread.
| block | When true (default) blocks if the queue is empty; when false returns immediately. |
true after a normal processing cycle; false when quitting or the call came from a thread that does not own the loop and is unrelated to run / async_run.
|
virtual |
Waits until the loop has drained its queue and is not executing a task.
| ms | Maximum wait in milliseconds; Timer::kInfinite means no limit. |
| check | When true (default) rejects calls from the loop's own thread. |
true when the idle condition was reached within ms. Reimplemented in vlink::MultiLoop.
| bool vlink::MessageLoop::wait_for_quit | ( | int | ms = Timer::kInfinite, |
| bool | check = true |
||
| ) |
Waits until the loop has fully exited.
| ms | Maximum wait in milliseconds; Timer::kInfinite means no limit. |
| check | When true (default) rejects calls from the loop's own thread. |
true if the loop exited before the timeout. | bool vlink::MessageLoop::wakeup | ( | ) |
Wakes the loop thread if it is suspended in its idle wait.
Concurrent calls coalesce; only the first one after the previous wakeup actually signals.
true when a wakeup is pending (newly issued or already in flight).