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