Flow 1.0.1
Flow project: Full implementation reference.
sched_task_handle_state.hpp
Go to the documentation of this file.
1/* Flow
2 * Copyright 2023 Akamai Technologies, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the
5 * "License"); you may not use this file except in
6 * compliance with the License. You may obtain a copy
7 * of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in
12 * writing, software distributed under the License is
13 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
14 * CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing
16 * permissions and limitations under the License. */
17
18/// @file
19#pragma once
20
24#include <boost/move/unique_ptr.hpp>
25#include <boost/utility.hpp>
26
27namespace flow::util
28{
29
30// Types.
31
32/**
33 * Internal-use data store used by `schedule[d]_task_*()`, each object containing the state
34 * relevant to a single call to either schedule_task_from_now() or schedule_task_at(). The user accesses these
35 * via the opaque type util::Scheduled_task_handle which is just `shared_ptr<>` around this `struct`.
36 *
37 * Internally, it's (1) storage for the underlying util::Timer itself, the task body, etc.; (2) a simple state machine
38 * with 3 possible states: `!(m_canceled || m_fired)` (initial); `m_canceled && (!m_fired)` (final state 1);
39 * `m_fired && (!m_canceled)` (final state 2). Obviously the state machine can only move from the initial state to
40 * exactly one of the final states. Less obviously these members must be synchronized in any multi-threaded situation.
41 */
43 private boost::noncopyable
44{
45 /// Unique ID for logging.
47
48 /**
49 * The function to execute when (and if) the timer fires, or short-fires. Note that successful cancellation will
50 * prevent this from being executed. Reminder that the function takes one argument, `bool short_fire`, explained
51 * elsewhere. This will execute either 0 times or 1 time.
52 */
54
55 /**
56 * Pointer to the task-executing engine (`Task_engine`) onto which to post tasks, including (if applicable) #m_body.
57 */
59
60 /**
61 * Mutex protecting #m_fired, #m_canceled, and #m_timer from the moment `m_timer.async_wait()` is called.
62 * Those members are safe to touch before that, as no other threads have knowledge of `this` until then.
63 * However, in `single_threaded` mode this pointer is left null, and no mutex is necessary or used (perf measure).
64 */
65 mutable boost::movelib::unique_ptr<Mutex_non_recursive> m_mutex_unless_single_threaded;
66
67 /**
68 * The underlying timer object -- paired with #m_task_engine -- used to actually wait in the background and
69 * ultimately execute (if applicable) a wrapper around #m_body.
70 */
72
73 /**
74 * Flag indicating whether or not the following is true: A wrapper task around #m_body is about to fire very soon
75 * or has already been fired. This starts `false` and, at most, can change once to `true`; in the latter case
76 * #m_canceled is then guaranteed to remain `false`.
77 *
78 * It (and #m_canceled) is used as a barrier: once #m_body is on track to be immediately executed, it cannot be
79 * canceled or rescheduled; hence attempts to do so are ignored once either flag reaches `true`.
80 */
81 bool m_fired;
82
83 /**
84 * Flag indicating whether or not the following is true: From this point on, #m_body will absolutely not be executed.
85 * This starts `false` and, at most, can change once to `true`; in the latter case
86 * #m_fired is then guaranteed to remain `false`.
87 *
88 * It (and #m_fired) is used as a barrier: once #m_body is marked as canceled, it cannot be
89 * re-canceled or rescheduled; hence attempts to do so are ignored once either flag reaches `true`.
90 */
92
93 /**
94 * Constructs it to the initial state, wherein it has neither fired nor been canceled.
95 *
96 * @param id
97 * See #m_id.
98 * @param single_threaded
99 * See schedule_task_from_now().
100 * @param task_engine
101 * See schedule_task_from_now().
102 * @param body_moved
103 * See schedule_task_from_now().
104 */
106 bool single_threaded, Task_engine* task_engine, Scheduled_task&& body_moved);
107}; // struct Scheduled_task_handle_state
108
109} // namespace flow::util
uint64_t id_t
Raw integer type to uniquely identify a thing. 64-bit width should make overflow extremely hard to re...
Flow module containing miscellaneous general-use facilities that don't fit into any other Flow module...
Definition: basic_blob.hpp:29
boost::asio::io_service Task_engine
Short-hand for boost.asio event service, the central class of boost.asio.
Definition: util_fwd.hpp:135
boost::asio::basic_waitable_timer< Fine_clock > Timer
boost.asio timer.
Definition: util_fwd.hpp:202
Internal-use data store used by schedule[d]_task_*(), each object containing the state relevant to a ...
bool m_canceled
Flag indicating whether or not the following is true: From this point on, m_body will absolutely not ...
boost::movelib::unique_ptr< Mutex_non_recursive > m_mutex_unless_single_threaded
Mutex protecting m_fired, m_canceled, and m_timer from the moment m_timer.async_wait() is called.
Timer m_timer
The underlying timer object – paired with m_task_engine – used to actually wait in the background and...
bool m_fired
Flag indicating whether or not the following is true: A wrapper task around m_body is about to fire v...
const Scheduled_task m_body
The function to execute when (and if) the timer fires, or short-fires.
Task_engine *const m_task_engine
Pointer to the task-executing engine (Task_engine) onto which to post tasks, including (if applicable...
Scheduled_task_handle_state(Unique_id_holder::id_t id, bool single_threaded, Task_engine *task_engine, Scheduled_task &&body_moved)
Constructs it to the initial state, wherein it has neither fired nor been canceled.
const Unique_id_holder::id_t m_id
Unique ID for logging.