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: |
29 | 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 | |
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 | |
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> |
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 | |
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 | |
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 | |
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 |
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 | |
137 | 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 | |