Ticket #5432: thread_group.hpp

File thread_group.hpp, 3.8 KB (added by Jeff Kunkel <JDKunk@…>, 12 years ago)

I revised the solution to the problem. The join all method will copy the current thread list. The join all method will then join all the current threads in the list. All modifications to the list will be ignored until join_all exits and is called again. Other solutions are welcome, but this is a classic reader-writer problem.

Line 
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/shared_mutex.hpp>
10#include <boost/thread/mutex.hpp>
11
12#include <boost/config/abi_prefix.hpp>
13
14#ifdef BOOST_MSVC
15#pragma warning(push)
16#pragma warning(disable:4251)
17#endif
18
19namespace boost
20{
21 class thread_group
22 {
23 private:
24 thread_group(thread_group const&);
25 thread_group& operator=(thread_group const&);
26 public:
27 thread_group() {}
28 ~thread_group()
29 {
30 for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
31 it!=end;
32 ++it)
33 {
34 delete *it;
35 }
36 }
37
38 template<typename F>
39 thread* create_thread(F threadfunc)
40 {
41 boost::lock_guard<shared_mutex> guard(m);
42 std::auto_ptr<thread> new_thread(new thread(threadfunc));
43 threads.push_back(new_thread.get());
44 return new_thread.release();
45 }
46
47 void add_thread(thread* thrd)
48 {
49 if(thrd)
50 {
51 boost::lock_guard<shared_mutex> guard(m);
52 threads.push_back(thrd);
53 }
54 }
55
56 void remove_thread(thread* thrd)
57 {
58 boost::lock_guard<shared_mutex> guard(m);
59 std::list<thread*>::iterator const it=std::find(threads.begin(),threads.end(),thrd);
60 if(it!=threads.end())
61 {
62 threads.erase(it);
63 }
64 }
65
66 template<typename P>
67 void remove_thread_if(P p) {
68 boost::lock_guard<shared_mutex> guard(m);
69 std::list<thread*>::iterator const it=std::find_if(threads.begin(),threads.end(),p);
70 if(it!=threads.end())
71 {
72 boost::lock_guard<shared_mutex> guard(m);
73 threads.erase(it);
74 }
75 }
76
77 template<typename P>
78 thread* find_thread_if(P p) {
79 boost::shared_lock<shared_mutex> guard(m);
80 std::list<thread*>::iterator const it=std::find_if(threads.begin(),threads.end(),p);
81 if(it!=threads.end())
82 {
83 return *it;
84 }
85 return NULL;
86 }
87
88 template<typename P>
89 void for_each_thread(P p) {
90 boost::shared_lock<shared_mutex> guard(m);
91 std::for_each( threads.begin(), threads.end(), p );
92 }
93
94 void join_all()
95 {
96 std::list<thread*> threads;
97 {
98 boost::shared_lock<shared_mutex> guard(m);
99 threads = this->threads;
100 }
101 for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
102 it!=end;
103 ++it)
104 {
105 (*it)->join();
106 }
107 }
108
109 void interrupt_all()
110 {
111 boost::shared_lock<shared_mutex> guard(m);
112
113 for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
114 it!=end;
115 ++it)
116 {
117 (*it)->interrupt();
118 }
119 }
120
121 size_t size() const
122 {
123 boost::shared_lock<shared_mutex> guard(m);
124 return threads.size();
125 }
126
127 private:
128 std::list<thread*> threads;
129 mutable shared_mutex m;
130 };
131}
132
133#ifdef BOOST_MSVC
134#pragma warning(pop)
135#endif
136
137#include <boost/config/abi_suffix.hpp>
138
139#endif