|
Boost : |
From: delfjk (jukka.katajaharju_at_[hidden])
Date: 2002-03-03 18:11:27
Why is it that thread_group do not have a remove_all method?
It would make the thread_group usage as a class variable much more
easier.
Here is a proposal for a implementation (which includes also some
other minor changes):
class thread_group : private noncopyable
{
public:
thread_group(bool join_threads_on_destroy = false);
~thread_group();
thread* create_thread(const function0<void>& threadfunc);
void add_thread(thread* thrd);
void remove_thread(thread* thrd);
void join_all();
void remove_all(bool join_threads = true);
private:
std::list<thread*> m_threads;
mutex m_mutex;
bool m_join_threads_on_destroy;
};
thread_group::thread_group(bool join_threads_on_destroy)
: m_threads(),
m_mutex(),
m_join_threads_on_destroy(join_threads_on_destroy)
{
}
thread_group::~thread_group()
{
if(m_threads.size())
remove_all(m_join_threads_on_destroy);
}
thread* thread_group::create_thread(const function0<void>& threadfunc)
{
// No scoped_lock required here since the only "shared data"
that's modified here occurs
// inside add_thread which does scoped_lock.
std::auto_ptr<thread> thrd(new thread(threadfunc));
add_thread(thrd.get());
return thrd.release();
}
void thread_group::add_thread(thread* thrd)
{
mutex::scoped_lock scoped_lock(m_mutex);
// For now we'll simply ignore requests to add a thread object
multiple times.
// Should we consider this an error and either throw or return an
error value?
std::list<thread*>::iterator it = std::find(m_threads.begin(),
m_threads.end(), thrd);
assert(it == m_threads.end());
if (it == m_threads.end())
m_threads.push_back(thrd);
}
void thread_group::remove_thread(thread* thrd)
{
mutex::scoped_lock scoped_lock(m_mutex);
// For now we'll simply ignore requests to remove a thread object
that's not in the group.
// Should we consider this an error and either throw or return an
error value?
std::list<thread*>::iterator it = std::find(m_threads.begin(),
m_threads.end(), thrd);
assert(it != m_threads.end());
if (it != m_threads.end())
m_threads.erase(it);
}
void thread_group::join_all()
{
mutex::scoped_lock scoped_lock(m_mutex);
for (std::list<thread*>::iterator it = m_threads.begin(), end_it
= m_threads.end(); it != end_it; ++it)
(*it)->join();
}
void thread_group::remove_all(bool join_threads)
{
mutex::scoped_lock scoped_lock(m_mutex);
for (std::list<thread*>::iterator it = m_threads.begin(), end_it
= m_threads.end(); it != end_it; ++it)
{
if(join_threads)
(*it)->join();
delete (*it);
}
m_threads.clear();
}
...it should be backwards compatible. Any comments?
-J.Katajaharju
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk