#ifndef THREAD_GROUP_H #define THREAD_GROUP_H #include #include #include namespace boost { class Thread_Group : private noncopyable { public: Thread_Group() {} ~Thread_Group() { for(thread_container::iterator it=threads.begin(),end=threads.end(); it!=end; ++it) { delete *it; } } template thread::id create_thread(F threadfunc) { lock_guard guard(m); std::auto_ptr new_thread(new ThreadHandler(threadfunc)); threads.push_back(new_thread.get()); thread::id ret = new_thread.get()->get_id(); new_thread.release(); return ret; } void add_thread(thread* thrd) { if(thrd) { boost::lock_guard guard(m); threads.push_back(new ThreadHandler(thrd)); } } void remove_thread(thread::id thread_id) { boost::lock_guard guard(m); for(thread_container::iterator it=threads.begin(),end=threads.end(); it!=end; ++it) { if ((*it)->get_id() == thread_id) { threads.erase(it); } } } void join_any() { while(true) { boost::shared_lock guard(m); for(thread_container::iterator it=threads.begin(),end=threads.end(); it!=end; ++it) { if ( (*it)->timed_join() ) { return; } } } } void join_all() { while(true) { boost::shared_lock guard(m); const size_t threads_to_wait = threads.size(); size_t threads_joined = 0; for(thread_container::iterator it=threads.begin(),end=threads.end(); it!=end; ++it) { if ( (*it)->timed_join() ) { ++threads_joined; } } if (threads_joined == threads_to_wait) { break; } } } void interrupt_all() { boost::shared_lock guard(m); for(thread_container::iterator it=threads.begin(),end=threads.end(); it!=end; ++it) { (*it)->interrupt(); } } size_t size() const { boost::shared_lock guard(m); return threads.size(); } private: class ThreadHandler : private noncopyable { public: template ThreadHandler(F threadfunc) : m_joined(false), m_interrupted(false), m_thread(new thread(threadfunc)), m_mutex() {} ThreadHandler(thread* thrd) : m_joined(thrd->joinable()), m_interrupted(false), m_thread(thrd), m_mutex() {} thread::id get_id() const { return m_thread->get_id(); } bool timed_join() { boost::lock_guard guard(m_mutex); static posix_time::time_duration join_time = boost::posix_time::millisec(10); if (not m_joined) { m_joined = m_thread->timed_join(join_time); } return m_joined; } void interrupt() { boost::lock_guard guard(m_mutex); if (not m_interrupted and not m_joined) { m_thread->interrupt(); m_interrupted = true; } } private: bool m_joined; bool m_interrupted; scoped_ptr m_thread; mutex m_mutex; }; typedef std::list thread_container; thread_container threads; mutable shared_mutex m; }; } #endif