diff --git a/include/boost/thread/thread.hpp b/include/boost/thread/thread.hpp index 88e56cb1..7be8a475 100644 --- a/include/boost/thread/thread.hpp +++ b/include/boost/thread/thread.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -119,10 +120,14 @@ public: thread(); explicit thread(const function0& threadfunc, attributes attr=attributes()); + thread(const thread& other); ~thread(); + thread& operator=(const thread& other); + bool operator==(const thread& other) const; bool operator!=(const thread& other) const; + bool operator<(const thread& other) const; void join(); void cancel(); @@ -145,9 +150,31 @@ public: class data; private: + template + friend std::basic_ostream& operator<<(std::basic_ostream&, const thread&); + +#if defined(BOOST_HAS_WINTHREADS) + long id() const; +#else + const void* id() const; +#endif + data* m_handle; }; +template +std::basic_ostream& operator<<(std::basic_ostream& os, const thread& thrd) +{ + if (!os.good()) return os; + + typename std::basic_ostream::sentry opfx(os); + + if (opfx) + os << thrd.id(); + + return os; +} + class BOOST_THREAD_DECL thread_group : private noncopyable { public: diff --git a/src/thread.cpp b/src/thread.cpp index 8c73ac73..fa9c6df7 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -13,9 +13,11 @@ #include #include #include +#include #include #include #include +#include #include #if defined(BOOST_HAS_WINTHREADS) @@ -52,6 +54,11 @@ public: void cancel(); void test_cancel(); void run(); +#if defined(BOOST_HAS_WINTHREADS) + long id() const; +#else + const void* id() const; +#endif #if defined(BOOST_THREAD_PRIORITY_SCHEDULING) void set_scheduling_parameter(int policy, const sched_param& param); @@ -66,6 +73,7 @@ private: int m_state; #if defined(BOOST_HAS_WINTHREADS) HANDLE m_thread; + DWORD m_id; #elif defined(BOOST_HAS_PTHREADS) pthread_t m_thread; #elif defined(BOOST_HAS_MPTASKS) @@ -141,6 +149,7 @@ thread::data::data() #if defined(BOOST_HAS_WINTHREADS) DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &m_thread, 0, FALSE, DUPLICATE_SAME_ACCESS); + m_id = GetCurrentThreadId(); #elif defined(BOOST_HAS_PTHREADS) m_thread = pthread_self(); #endif @@ -236,6 +245,7 @@ void thread::data::run() #if defined(BOOST_HAS_WINTHREADS) DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &m_thread, 0, FALSE, DUPLICATE_SAME_ACCESS); + m_id = GetCurrentThreadId(); #elif defined(BOOST_HAS_PTHREADS) m_thread = pthread_self(); #endif @@ -245,6 +255,28 @@ void thread::data::run() m_threadfunc(); } +#if defined(BOOST_HAS_WINTHREADS) +long thread::data::id() const +{ + boost::mutex::scoped_lock lock(m_mutex); + if (m_state != joined) + return m_id; + return 0; // throw instead? +} +#else +const void* thread::data::id() const +{ + boost::mutex::scoped_lock lock(m_mutex); + if (m_state != joined) + { + if (boost::is_pointer::value) + return m_thread; + return this; + } + return 0; // throw instead? +} +#endif + #if defined(BOOST_THREAD_PRIORITY_SCHEDULING) void thread::data::set_scheduling_parameter(int policy, const sched_param& param) @@ -547,12 +579,27 @@ thread::thread(const function0& threadfunc, attributes attr) m_handle = param.release(); } +thread::thread(const thread& other) + : m_handle(other.m_handle) +{ + m_handle->addref(); +} + thread::~thread() { if (m_handle && m_handle->release()) delete m_handle; } +thread& thread::operator=(const thread& other) +{ + if (m_handle->release()) + delete m_handle; + m_handle = other.m_handle; + m_handle->addref(); + return *this; +} + bool thread::operator==(const thread& other) const { return m_handle == other.m_handle; @@ -563,6 +610,11 @@ bool thread::operator!=(const thread& other) const return !operator==(other); } +bool thread::operator<(const thread& other) const +{ + return std::less()(m_handle, m_handle); +} + void thread::join() { m_handle->join(); @@ -683,6 +735,16 @@ void thread::yield() thread::test_cancel(); } +#if defined(BOOST_HAS_WINTHREADS) +long thread::id() const +#else +const void* thread::id() const +#endif +{ + std::cout << *this; + return m_handle->id(); +} + thread_group::thread_group() { }