diff --git a/examples/executor_example/application.hpp b/examples/executor_example/application.hpp index 24102cc..62759c2 100644 --- a/examples/executor_example/application.hpp +++ b/examples/executor_example/application.hpp @@ -19,13 +19,12 @@ #include #include -#include class my_executor { public: template auto post( int priority, Func&& func ) { - return boost::asio::post(*io_serv, pri_queue.wrap(priority, --order, std::forward(func))); + return boost::asio::post(io_serv, pri_queue.wrap(priority, --order, std::forward(func))); } auto& get_priority_queue() { return pri_queue; } @@ -34,13 +33,11 @@ class my_executor { void clear() { pri_queue.clear(); } - void reset() { io_serv.emplace(); } - - boost::asio::io_service& get_io_service() { return *io_serv; } + boost::asio::io_service& get_io_service() { return io_serv; } private: // members are ordered taking into account that the last one is destructed first - std::optional io_serv{std::in_place}; + boost::asio::io_context io_serv; appbase::execution_priority_queue pri_queue; std::size_t order = std::numeric_limits::max(); // to maintain FIFO ordering in queue within priority }; diff --git a/include/appbase/application_base.hpp b/include/appbase/application_base.hpp index 27e3a4f..1a5ef5d 100644 --- a/include/appbase/application_base.hpp +++ b/include/appbase/application_base.hpp @@ -155,10 +155,17 @@ class application_base { try { // plugins shutdown down at this point, - exec.clear(); // make sure the queue is empty - // Recreate the io_context since it doesn't provide a clear and we want the destructors of all the - // lambdas posted to the io_context to execute before destroying the plugins - exec.reset(); + + // Drain the io_service of anything that could be referencing plugins. + // Note this does not call exec.execute_highest(), so only drains into the priority queue assuming nothing + // has hijacked the io_service for other purposes. + io_serv.restart(); + while (io_serv.poll()) + ; + // clear priority queue of anything pushed by poll() + exec.clear(); + + // destroy the plugins now that all lambda that reference them have been destroyed destroy_plugins(); } catch (...) { if (!eptr) diff --git a/include/appbase/default_executor.hpp b/include/appbase/default_executor.hpp index 42d1f0a..c9d707d 100644 --- a/include/appbase/default_executor.hpp +++ b/include/appbase/default_executor.hpp @@ -4,7 +4,6 @@ #include #include -#include namespace appbase { @@ -12,7 +11,7 @@ class default_executor { public: template auto post(int priority, Func&& func) { - return boost::asio::post(*io_serv, pri_queue.wrap(priority, --order, std::forward(func))); + return boost::asio::post(io_serv, pri_queue.wrap(priority, --order, std::forward(func))); } /** @@ -35,21 +34,17 @@ class default_executor { pri_queue.clear(); } - void reset() { - io_serv.emplace(); - } - /** * Do not run io_service in any other threads, as application assumes single-threaded execution in exec(). * @return io_serivice of application */ boost::asio::io_service& get_io_service() { - return *io_serv; + return io_serv; } private: // members are ordered taking into account that the last one is destructed first - std::optional io_serv{std::in_place}; + boost::asio::io_context io_serv; execution_priority_queue pri_queue; std::size_t order = std::numeric_limits::max(); // to maintain FIFO ordering in queue within priority };