24#include "flow/error/error.hpp" 
   33template<
typename Scheduled_task_handler>
 
   37                                             Scheduled_task_handler&& task_body_moved)
 
   39  using boost::chrono::round;
 
   40  using boost::chrono::milliseconds;
 
   42  using boost::asio::bind_executor;
 
   43  using boost::asio::get_associated_executor;
 
   44  using boost::asio::post;
 
  119  auto task = boost::make_shared<Scheduled_task_handle_state>
 
  120                (task_id, single_threaded, task_engine, [task_id, get_logger, get_log_component,
 
  122                                                         task_body = std::move(task_body_moved)]
 
  123                                                          (
bool short_fire) 
mutable 
  126    const auto executor = get_associated_executor(task_body); 
 
  128         bind_executor(executor, [get_logger, get_log_component, task_id,
 
  129                                  task_body = std::move(task_body), short_fire]()
 
  131      FLOW_LOG_TRACE(
"Scheduled task [" << task_id <<
"]: Body starting; short-fired? = [" << short_fire << 
"].");
 
  132      task_body(short_fire); 
 
  133      FLOW_LOG_TRACE(
"Scheduled task [" << task_id <<
"]: Body finished without throwing exception.");
 
  140  auto& timer = task->m_timer;
 
  143                 "to fire in [" << round<milliseconds>(from_now) << 
"]; " 
  144                 "task engine [" << 
static_cast<void*
>(task_engine) << 
"]; " 
  145                 "single-threaded optimizations applicable? = [" << single_threaded << 
"].");
 
  147  timer.expires_after(from_now);
 
  155  timer.async_wait([get_logger, get_log_component, task](
const Error_code& sys_err_code)
 
  157    const bool single_threaded = !task->m_mutex_unless_single_threaded;
 
  171    if (sys_err_code == boost::asio::error::operation_aborted)
 
  175        assert(task->m_fired != task->m_canceled); 
 
  180        assert(task->m_fired != task->m_canceled);
 
  185    if (sys_err_code && (sys_err_code != boost::asio::error::operation_aborted)) 
 
  188      FLOW_LOG_WARNING(
"Timer system error; just logged; totally unexpected; pretending it fired normally.");
 
  196    auto should_fire = [&]() -> 
bool  
  200        FLOW_LOG_TRACE(
"Scheduled task [" << task->m_id << 
"] native timer fired (could be due to cancel() call), " 
  201                       "but user handler already began executing earlier.  Done.");
 
  205      if (task->m_canceled)
 
  207        FLOW_LOG_TRACE(
"Scheduled task [" << task->m_id << 
"] native timer fired (could be due to cancel() call), " 
  208                       "but task was already canceled earlier.  Done.");
 
  213      FLOW_LOG_TRACE(
"Scheduled task [" << task->m_id << 
"] native timer fired (could be due to cancel() call), " 
  214                     "and nothing has fired or canceled task already.  Proceeding with task (through post()).");
 
  216      task->m_fired = 
true;
 
  223      noop = !should_fire();
 
  228      noop = !should_fire();
 
  237    (task->m_body)(
false); 
 
  238    FLOW_LOG_TRACE(
"Scheduled task [" << task->m_id <<
"]: Body-post()ing function finished.");
 
  244template<
typename Scheduled_task_handler>
 
  248                                       Scheduled_task_handler&& task_body_moved)
 
  257  return schedule_task_from_now<Scheduled_task_handler>(logger_ptr,
 
  258                                                        at - Fine_clock::now(),
 
  259                                                        single_threaded, task_engine, std::move(task_body_moved));
 
Interface that the user should implement, passing the implementing Logger into logging classes (Flow'...
static id_t create_unique_id()
Short-hand for Unique_id_holder().unique_id(); useful when all you want is the unique integer itself.
#define FLOW_ERROR_SYS_ERROR_LOG_WARNING()
Logs a warning about the (often errno-based or from a library) error code in sys_err_code.
#define FLOW_LOG_WARNING(ARG_stream_fragment)
Logs a WARNING message into flow::log::Logger *get_logger() with flow::log::Component get_log_compone...
#define FLOW_LOG_SET_CONTEXT(ARG_logger_ptr, ARG_component_payload)
For the rest of the block within which this macro is instantiated, causes all FLOW_LOG_....
#define FLOW_LOG_TRACE(ARG_stream_fragment)
Logs a TRACE message into flow::log::Logger *get_logger() with flow::log::Component get_log_component...
Flow module containing miscellaneous general-use facilities that don't fit into any other Flow module...
boost::unique_lock< Mutex > Lock_guard
Short-hand for advanced-capability RAII lock guard for any mutex, ensuring exclusive ownership of tha...
Scheduled_task_handle schedule_task_from_now(log::Logger *logger_ptr, const Fine_duration &from_now, bool single_threaded, Task_engine *task_engine, Scheduled_task_handler &&task_body_moved)
Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...
boost::shared_ptr< Scheduled_task_handle_state > Scheduled_task_handle
Black-box type that represents a handle to a scheduled task as scheduled by schedule_task_at() or sch...
Scheduled_task_handle schedule_task_at(log::Logger *logger_ptr, const Fine_time_pt &at, bool single_threaded, Task_engine *task_engine, Scheduled_task_handler &&task_body_moved)
Identical to schedule_task_from_now() except the time is specified in absolute terms.
boost::asio::io_context Task_engine
Short-hand for boost.asio event service, the central class of boost.asio.
boost::system::error_code Error_code
Short-hand for a boost.system error code (which basically encapsulates an integer/enum error code and...
Fine_clock::duration Fine_duration
A high-res time duration as computed from two Fine_time_pts.
Fine_clock::time_point Fine_time_pt
A high-res time point as returned by Fine_clock::now() and suitable for precise time math in general.