diff --git a/include/boost/thread/executors/basic_thread_pool.hpp b/include/boost/thread/executors/basic_thread_pool.hpp index 4a052648..f8d50791 100644 --- a/include/boost/thread/executors/basic_thread_pool.hpp +++ b/include/boost/thread/executors/basic_thread_pool.hpp @@ -48,9 +48,9 @@ namespace executors */ bool try_executing_one() { - work task; try { + work task; if (work_queue.try_pull_front(task) == queue_op_status::success) { task(); @@ -58,12 +58,9 @@ namespace executors } return false; } - catch (std::exception& ) - { - return false; - } catch (...) { + std::terminate(); return false; } } @@ -95,12 +92,9 @@ namespace executors task(); } } - catch (std::exception& ) - { - return; - } catch (...) { + std::terminate(); return; } } diff --git a/include/boost/thread/executors/inline_executor.hpp b/include/boost/thread/executors/inline_executor.hpp index bc6bd9fe..83d008c0 100644 --- a/include/boost/thread/executors/inline_executor.hpp +++ b/include/boost/thread/executors/inline_executor.hpp @@ -26,6 +26,7 @@ namespace executors /// type-erasure to store the works to do typedef executors::work work; bool closed_; + mutable mutex mtx_; /** * Effects: try to execute one task. * Returns: whether a task has been executed. @@ -66,16 +67,22 @@ namespace executors */ void close() { + lock_guard lk(mtx_); closed_ = true; } /** * \b Returns: whether the pool is closed for submissions. */ - bool closed() + bool closed(lock_guard& ) { return closed_; } + bool closed() + { + lock_guard lk(mtx_); + return closed(lk); + } /** * \b Requires: \c Closure is a model of \c Callable(void()) and a model of \c CopyConstructible/MoveConstructible. @@ -93,21 +100,48 @@ namespace executors template void submit(Closure & closure) { - if (closed()) return; - closure(); + lock_guard lk(mtx_); + if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() ); + try + { + closure(); + } + catch (...) + { + std::terminate(); + return; + } } #endif void submit(void (*closure)()) { - if (closed()) return; - closure(); + lock_guard lk(mtx_); + if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() ); + try + { + closure(); + } + catch (...) + { + std::terminate(); + return; + } } template void submit(BOOST_THREAD_FWD_REF(Closure) closure) { - if (closed()) return; - closure(); + lock_guard lk(mtx_); + if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() ); + try + { + closure(); + } + catch (...) + { + std::terminate(); + return; + } } /** diff --git a/include/boost/thread/executors/loop_executor.hpp b/include/boost/thread/executors/loop_executor.hpp index 2e36dc18..d3f704de 100644 --- a/include/boost/thread/executors/loop_executor.hpp +++ b/include/boost/thread/executors/loop_executor.hpp @@ -51,12 +51,9 @@ namespace executors } return false; } - catch (std::exception& ) - { - return false; - } catch (...) { + std::terminate(); return false; } } diff --git a/include/boost/thread/executors/serial_executor.hpp b/include/boost/thread/executors/serial_executor.hpp index 4800a1e2..90cfc6e8 100644 --- a/include/boost/thread/executors/serial_executor.hpp +++ b/include/boost/thread/executors/serial_executor.hpp @@ -43,7 +43,15 @@ namespace executors try_executing_one_task(work& task, boost::promise &p) : task(task), p(p) {} void operator()() { - task(); // if task() throws promise is not set but as the the program terminates and should terminate there is no need to use try-catch here. + try + { + task(); + } + catch (...) + { + std::terminate(); + return; + } p.set_value(); } }; @@ -52,7 +60,7 @@ namespace executors * \par Returns * The underlying executor wrapped on a generic executor reference. */ - generic_executor_ref underlying_executor() BOOST_NOEXCEPT { return ex; } + generic_executor_ref& underlying_executor() BOOST_NOEXCEPT { return ex; } /** * Effects: try to execute one task. @@ -79,12 +87,9 @@ namespace executors } return false; } - catch (std::exception& ) - { - return false; - } catch (...) { + std::terminate(); return false; } } diff --git a/include/boost/thread/executors/thread_executor.hpp b/include/boost/thread/executors/thread_executor.hpp index 9fc3362f..9a7d3d01 100644 --- a/include/boost/thread/executors/thread_executor.hpp +++ b/include/boost/thread/executors/thread_executor.hpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include @@ -28,6 +30,11 @@ namespace executors /// type-erasure to store the works to do typedef executors::work work; bool closed_; + typedef scoped_thread<> thread_t; + typedef csbl::vector threads_type; + threads_type threads_; + mutable mutex mtx_; + /** * Effects: try to execute one task. * Returns: whether a task has been executed. @@ -52,7 +59,7 @@ namespace executors { } /** - * \b Effects: Destroys the inline executor. + * \b Effects: Waits for closures (if any) to complete, then joins and destroys the threads. * * \b Synchronization: The completion of all the closures happen before the completion of the \c thread_executor destructor. */ @@ -60,6 +67,7 @@ namespace executors { // signal to all the worker thread that there will be no more submissions. close(); + // all the scoped threads will join before destroying } /** @@ -68,16 +76,22 @@ namespace executors */ void close() { + lock_guard lk(mtx_); closed_ = true; } /** * \b Returns: whether the pool is closed for submissions. */ - bool closed() + bool closed(lock_guard& ) { return closed_; } + bool closed() + { + lock_guard lk(mtx_); + return closed(lk); + } /** * \b Requires: \c Closure is a model of \c Callable(void()) and a model of \c CopyConstructible/MoveConstructible. @@ -95,24 +109,27 @@ namespace executors template void submit(Closure & closure) { - if (closed()) return; + lock_guard lk(mtx_); + if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() ); thread th(closure); - th.detach(); + threads_.push_back(thread_t(boost::move(th))); } #endif void submit(void (*closure)()) { - if (closed()) return; + lock_guard lk(mtx_); + if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() ); thread th(closure); - th.detach(); + threads_.push_back(thread_t(boost::move(th))); } template void submit(BOOST_THREAD_FWD_REF(Closure) closure) { - if (closed()) return; + lock_guard lk(mtx_); + if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() ); thread th(boost::forward(closure)); - th.detach(); + threads_.push_back(thread_t(boost::move(th))); } /**