![]() |
boost::taar::cancellation_signals — A thread-safe pool of asio::cancellation_signal instances.
// In header: <boost/taar/core/cancellation_signals.hpp> class cancellation_signals { public: // member classes/structs/unions struct bound_record { // public data members boost::asio::cancellation_signal signal; boost::asio::any_io_executor executor; }; // Handle to a slot tied to an executor. class bound_slot { public: // public member functions bound_slot() = default; bound_slot(bound_slot &&); bound_slot & operator=(bound_slot &&) noexcept; bound_slot(bound_slot const &) = delete; bound_slot & operator=(bound_slot const &) = delete; ~bound_slot(); boost::asio::cancellation_slot slot() const; void emit(boost::asio::cancellation_type = boost::asio::cancellation_type::all) const; void release(); // private member functions bound_slot(std::shared_ptr< state >, std::shared_ptr< bound_record >); }; struct state { // public data members std::mutex mutex; std::list< boost::asio::cancellation_signal > signals; std::vector< std::shared_ptr< bound_record > > bound; }; // public member functions void emit(boost::asio::cancellation_type = boost::asio::cancellation_type::all); boost::asio::cancellation_slot slot(); bound_slot slot(boost::asio::any_io_executor); std::size_t bound_count() const; };
A cancellation_signals instance hands out cancellation slots to async operations and can emit a cancellation to all of them in one call. This is the primary mechanism Boost.Taar offers for shutting down a server:
Pass the pool to server::tcp / server::tls, which bind a slot to every connection they spawn.
Install a signal handler that calls emit() from a SIGINT / SIGTERM slot.
Asio requires a cancellation signal to be emitted within the same implicit or explicit strand as the operation it cancels. The pool therefore offers two kinds of slot:
slot(boost::asio::any_io_executor): the slot is tied to an executor (a strand when the io_context runs on several threads), and emit dispatches the emission through it. This is what the servers use for every connection, so emit may be called from any thread, including one that is not running the io_context.
slot(): a plain slot emitted inline on the calling thread. Safe only when the bound operation runs on the thread that calls emit (a single-threaded io_context, or a handler posted to it).
cancellation_signals public member functionsvoid emit(boost::asio::cancellation_type ct = boost::asio::cancellation_type::all);Emit cancellation of type ct to every slot in the pool.
Plain slots are emitted inline; executor-bound slots have their emission dispatched through their executor.
boost::asio::cancellation_slot slot();Obtain a plain cancellation slot bound to one of the signals in the pool.
Reuses a signal that does not currently have a handler attached, appending a new signal to the pool if every existing one is already bound. Subsequent calls hand out distinct slots. The emission runs on the thread calling emit.
bound_slot slot(boost::asio::any_io_executor executor);Obtain a slot whose emission is dispatched through executor.
Pass the strand (or other serialising executor) the operation runs on. The slot lives until the returned handle is destroyed.
std::size_t bound_count() const;Number of executor-bound slots currently alive.