1 #ifndef BOOST_THREAD_DETAIL_THREAD_GROUP_HPP 2 #define BOOST_THREAD_DETAIL_THREAD_GROUP_HPP 3 // Distributed under the Boost Software License, Version 1.0. (See 4 // accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 // (C) Copyright 2007-9 Anthony Williams 7 8 #include <list> 9 #include <boost/thread/csbl/memory/unique_ptr.hpp> 10 #include <boost/thread/shared_mutex.hpp> 11 #include <boost/thread/mutex.hpp> 12 #include <boost/thread/lock_guard.hpp> 13 14 #include <boost/config/abi_prefix.hpp> 15 16 #ifdef BOOST_MSVC 17 #pragma warning(push) 18 #pragma warning(disable:4251) 19 #endif 20 21 namespace boost 22 { 23 class thread_group 24 { 25 private: 26 thread_group(thread_group const&); 27 thread_group& operator=(thread_group const&); 28 public: thread_group()29 thread_group() {} ~thread_group()30 ~thread_group() 31 { 32 for(std::list<thread*>::iterator it=threads.begin(),end=threads.end(); 33 it!=end; 34 ++it) 35 { 36 delete *it; 37 } 38 } 39 is_this_thread_in()40 bool is_this_thread_in() 41 { 42 thread::id id = this_thread::get_id(); 43 boost::shared_lock<shared_mutex> guard(m); 44 for(std::list<thread*>::iterator it=threads.begin(),end=threads.end(); 45 it!=end; 46 ++it) 47 { 48 if ((*it)->get_id() == id) 49 return true; 50 } 51 return false; 52 } 53 is_thread_in(thread * thrd)54 bool is_thread_in(thread* thrd) 55 { 56 if(thrd) 57 { 58 thread::id id = thrd->get_id(); 59 boost::shared_lock<shared_mutex> guard(m); 60 for(std::list<thread*>::iterator it=threads.begin(),end=threads.end(); 61 it!=end; 62 ++it) 63 { 64 if ((*it)->get_id() == id) 65 return true; 66 } 67 return false; 68 } 69 else 70 { 71 return false; 72 } 73 } 74 75 template<typename F> create_thread(F threadfunc)76 thread* create_thread(F threadfunc) 77 { 78 boost::lock_guard<shared_mutex> guard(m); 79 boost::csbl::unique_ptr<thread> new_thread(new thread(threadfunc)); 80 threads.push_back(new_thread.get()); 81 return new_thread.release(); 82 } 83 add_thread(thread * thrd)84 void add_thread(thread* thrd) 85 { 86 if(thrd) 87 { 88 BOOST_THREAD_ASSERT_PRECONDITION( ! is_thread_in(thrd) , 89 thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost::thread_group: trying to add a duplicated thread") 90 ); 91 92 boost::lock_guard<shared_mutex> guard(m); 93 threads.push_back(thrd); 94 } 95 } 96 remove_thread(thread * thrd)97 void remove_thread(thread* thrd) 98 { 99 boost::lock_guard<shared_mutex> guard(m); 100 std::list<thread*>::iterator const it=std::find(threads.begin(),threads.end(),thrd); 101 if(it!=threads.end()) 102 { 103 threads.erase(it); 104 } 105 } 106 join_all()107 void join_all() 108 { 109 BOOST_THREAD_ASSERT_PRECONDITION( ! is_this_thread_in() , 110 thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost::thread_group: trying joining itself") 111 ); 112 boost::shared_lock<shared_mutex> guard(m); 113 114 for(std::list<thread*>::iterator it=threads.begin(),end=threads.end(); 115 it!=end; 116 ++it) 117 { 118 if ((*it)->joinable()) 119 (*it)->join(); 120 } 121 } 122 123 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS interrupt_all()124 void interrupt_all() 125 { 126 boost::shared_lock<shared_mutex> guard(m); 127 128 for(std::list<thread*>::iterator it=threads.begin(),end=threads.end(); 129 it!=end; 130 ++it) 131 { 132 (*it)->interrupt(); 133 } 134 } 135 #endif 136 size() const137 size_t size() const 138 { 139 boost::shared_lock<shared_mutex> guard(m); 140 return threads.size(); 141 } 142 143 private: 144 std::list<thread*> threads; 145 mutable shared_mutex m; 146 }; 147 } 148 149 #ifdef BOOST_MSVC 150 #pragma warning(pop) 151 #endif 152 153 #include <boost/config/abi_suffix.hpp> 154 155 #endif 156