Boost logo

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