77#ifndef NETWORK_UTILS_THREAD_POOL_IPP_20111021
88#define NETWORK_UTILS_THREAD_POOL_IPP_20111021
99
10+ #include < vector>
11+ #include < thread>
1012#include < network/utils/thread_pool.hpp>
1113
1214namespace network {namespace utils {
1315
1416struct thread_pool_pimpl {
15- thread_pool_pimpl (
16- std::size_t threads =1 ,
17+ thread_pool_pimpl (std::size_t threads =1 ,
1718 io_service_ptr io_service = io_service_ptr(),
18- worker_threads_ptr worker_threads = worker_threads_ptr()
19- )
19+ std::vector<std::thread> worker_threads = {})
2020 : threads_(threads)
2121 , io_service_(io_service)
22- , worker_threads_(worker_threads)
22+ , worker_threads_(std::move( worker_threads) )
2323 , sentinel_()
2424 {
2525bool commit =false ;
2626BOOST_SCOPE_EXIT ((&commit)(&io_service_)(&worker_threads_)(&sentinel_)) {
2727if (!commit) {
2828 sentinel_.reset ();
2929 io_service_.reset ();
30- if (worker_threads_.get ()) {
31- worker_threads_->interrupt_all ();
32- worker_threads_->join_all ();
33- }
34- worker_threads_.reset ();
30+ for (auto & thread : worker_threads_)
31+ if (thread.joinable ()) thread.join ();
32+ worker_threads_.clear ();
3533 }
3634 } BOOST_SCOPE_EXIT_END
3735
38- if (!io_service_.get ()) {
39- io_service_.reset (new boost::asio::io_service);
40- }
41-
42- if (!worker_threads_.get ()) {
43- worker_threads_.reset (new boost::thread_group);
44- }
45-
46- if (!sentinel_.get ()) {
36+ if (!io_service_.get ()) io_service_.reset (new boost::asio::io_service);
37+ if (!sentinel_.get ())
4738 sentinel_.reset (new boost::asio::io_service::work (*io_service_));
48- }
49-
39+ auto local_io_service = io_service_;
5040for (std::size_t counter =0 ; counter < threads_; ++counter)
51- worker_threads_->create_thread (
52- boost::bind (
53- &boost::asio::io_service::run,
54- io_service_
55- )
56- );
41+ worker_threads_.emplace_back ([local_io_service](){
42+ local_io_service->run ();});
5743
5844 commit =true ;
5945 }
6046
47+ thread_pool_pimpl (thread_pool_pimplconst &) =delete ;
48+ thread_pool_pimpl &operator =(thread_pool_pimplconst &) =delete ;
49+
50+ thread_pool_pimpl (thread_pool_pimpl&& other) {
51+ other.swap (*this );
52+ }
53+
6154 std::size_t const thread_count ()const {
6255return threads_;
6356 }
@@ -69,34 +62,32 @@ namespace network { namespace utils {
6962~thread_pool_pimpl () {
7063 sentinel_.reset ();
7164try {
72- worker_threads_-> join_all ();
65+ for ( auto & thread : worker_threads_) thread. join ();
7366 }catch (...) {
7467BOOST_ASSERT (false &&" A handler was not supposed to throw, but one did." );
7568std::abort ();
7669 }
7770 }
7871
7972void swap (thread_pool_pimpl & other) {
80- std::swap (other.threads_ , threads_);
81- std::swap (other.io_service_ , io_service_);
82- std::swap (other.worker_threads_ , worker_threads_);
83- std::swap (other.sentinel_ , sentinel_);
73+ using std::swap;
74+ swap (other.threads_ , threads_);
75+ swap (other.io_service_ , io_service_);
76+ swap (other.worker_threads_ , worker_threads_);
77+ swap (other.sentinel_ , sentinel_);
8478 }
79+
8580protected:
8681 std::size_t threads_;
8782 io_service_ptr io_service_;
88- worker_threads_ptr worker_threads_;
83+ std::vector<std::thread> worker_threads_;
8984 sentinel_ptr sentinel_;
90-
91- private:
92- thread_pool_pimpl (thread_pool_pimplconst &);// no copies please
93- thread_pool_pimpl &operator =(thread_pool_pimpl);// no assignment please
9485 };
9586
9687thread_pool::thread_pool (std::size_t threads,
9788 io_service_ptr io_service,
98- worker_threads_ptr worker_threads)
99- : pimpl(new (std::nothrow) thread_pool_pimpl(threads, io_service, worker_threads))
89+ std::vector<std::thread> worker_threads)
90+ : pimpl(new (std::nothrow) thread_pool_pimpl(threads, io_service,std::move( worker_threads) ))
10091 {}
10192
10293 std::size_t const thread_pool::thread_count ()const {
@@ -110,11 +101,11 @@ namespace network { namespace utils {
110101void thread_pool::swap (thread_pool & other) {
111102std::swap (other.pimpl ,this ->pimpl );
112103 }
113-
104+
114105thread_pool::~thread_pool () {
115106delete pimpl;
116107 }
117-
108+
118109}// namespace utils
119110}// namespace network
120111