Imported Upstream version 3.2.2
[debian/gnuradio] / gruel / src / lib / thread_group.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright (C) 2001-2003 William E. Kempf
4  * Copyright (C) 2007 Anthony Williams
5  * Copyright 2008 Free Software Foundation, Inc.
6  *
7  *  Distributed under the Boost Software License, Version 1.0. (See accompanying 
8  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9  */
10
11 /*
12  * This was extracted from Boost 1.35.0 and fixed.
13  */
14
15 #include <gruel/thread_group.h>
16
17 namespace gruel
18 {
19   thread_group::thread_group()
20   {
21   }
22
23   thread_group::~thread_group()
24   {
25     // We shouldn't have to scoped_lock here, since referencing this object
26     // from another thread while we're deleting it in the current thread is
27     // going to lead to undefined behavior any way.
28     for (std::list<boost::thread*>::iterator it = m_threads.begin();
29          it != m_threads.end(); ++it)
30       {
31         delete (*it);
32       }
33   }
34
35   boost::thread* thread_group::create_thread(const boost::function0<void>& threadfunc)
36   {
37     // No scoped_lock required here since the only "shared data" that's
38     // modified here occurs inside add_thread which does scoped_lock.
39     std::auto_ptr<boost::thread> thrd(new boost::thread(threadfunc));
40     add_thread(thrd.get());
41     return thrd.release();
42   }
43
44   void thread_group::add_thread(boost::thread* thrd)
45   {
46     boost::lock_guard<boost::shared_mutex> guard(m_mutex);
47
48     // For now we'll simply ignore requests to add a thread object multiple
49     // times. Should we consider this an error and either throw or return an
50     // error value?
51     std::list<boost::thread*>::iterator it = std::find(m_threads.begin(),
52                                                        m_threads.end(), thrd);
53     BOOST_ASSERT(it == m_threads.end());
54     if (it == m_threads.end())
55       m_threads.push_back(thrd);
56   }
57
58   void thread_group::remove_thread(boost::thread* thrd)
59   {
60     boost::lock_guard<boost::shared_mutex> guard(m_mutex);
61
62     // For now we'll simply ignore requests to remove a thread object that's
63     // not in the group. Should we consider this an error and either throw or
64     // return an error value?
65     std::list<boost::thread*>::iterator it = std::find(m_threads.begin(),
66                                                        m_threads.end(), thrd);
67     BOOST_ASSERT(it != m_threads.end());
68     if (it != m_threads.end())
69       m_threads.erase(it);
70   }
71
72   void thread_group::join_all()
73   {
74     boost::shared_lock<boost::shared_mutex> guard(m_mutex);
75     for (std::list<boost::thread*>::iterator it = m_threads.begin();
76          it != m_threads.end(); ++it)
77       {
78         (*it)->join();
79       }
80   }
81
82   void thread_group::interrupt_all()
83   {
84     boost::shared_lock<boost::shared_mutex> guard(m_mutex);
85     for(std::list<boost::thread*>::iterator it=m_threads.begin(),end=m_threads.end();
86         it!=end;
87         ++it)
88       {
89         (*it)->interrupt();
90       }
91   }
92
93   size_t thread_group::size() const
94   {
95     boost::shared_lock<boost::shared_mutex> guard(m_mutex);
96     return m_threads.size();
97   }
98
99 } // namespace gruel