Boost logo

Boost-Commit :

From: anthony_at_[hidden]
Date: 2007-12-19 05:39:46


Author: anthonyw
Date: 2007-12-19 05:39:45 EST (Wed, 19 Dec 2007)
New Revision: 42166
URL: http://svn.boost.org/trac/boost/changeset/42166

Log:
Updated thread ID, and added tests
Added:
   trunk/libs/thread/test/test_thread_id.cpp (contents, props changed)
Text files modified:
   trunk/boost/thread/pthread/thread.hpp | 59 +++++++++++++++++++++++++--------------
   trunk/boost/thread/pthread/thread_data.hpp | 9 ++++-
   trunk/boost/thread/win32/thread.hpp | 9 +++++
   trunk/libs/thread/src/pthread/thread.cpp | 22 +++++++++-----
   trunk/libs/thread/test/Jamfile.v2 | 1
   5 files changed, 67 insertions(+), 33 deletions(-)

Modified: trunk/boost/thread/pthread/thread.hpp
==============================================================================
--- trunk/boost/thread/pthread/thread.hpp (original)
+++ trunk/boost/thread/pthread/thread.hpp 2007-12-19 05:39:45 EST (Wed, 19 Dec 2007)
@@ -40,44 +40,62 @@
     {
         class thread_id
         {
- boost::optional<pthread_t> id;
-
+ private:
+ detail::thread_data_ptr thread_data;
+
+ thread_id(detail::thread_data_ptr thread_data_):
+ thread_data(thread_data_)
+ {}
             friend class boost::thread;
-
             friend thread_id this_thread::get_id();
-
- thread_id(pthread_t id_):
- id(id_)
- {}
-
         public:
- thread_id()
+ thread_id():
+ thread_data()
             {}
-
+
             bool operator==(const thread_id& y) const
             {
- return (id && y.id) && (pthread_equal(*id,*y.id)!=0);
+ return thread_data==y.thread_data;
             }
         
             bool operator!=(const thread_id& y) const
             {
- return !(*this==y);
+ return thread_data!=y.thread_data;
+ }
+
+ bool operator<(const thread_id& y) const
+ {
+ return thread_data<y.thread_data;
+ }
+
+ bool operator>(const thread_id& y) const
+ {
+ return y.thread_data<thread_data;
+ }
+
+ bool operator<=(const thread_id& y) const
+ {
+ return !(y.thread_data<thread_data);
+ }
+
+ bool operator>=(const thread_id& y) const
+ {
+ return !(thread_data<y.thread_data);
             }
 
             template<class charT, class traits>
             friend std::basic_ostream<charT, traits>&
             operator<<(std::basic_ostream<charT, traits>& os, const thread_id& x)
             {
- if(x.id)
+ if(x.thread_data)
                 {
- return os<<*x.id;
+ return os<<x.thread_data;
                 }
                 else
                 {
                     return os<<"{Not-any-thread}";
                 }
             }
-
         };
     }
 
@@ -108,13 +126,13 @@
         };
         
         mutable boost::mutex thread_info_mutex;
- boost::shared_ptr<detail::thread_data_base> thread_info;
+ detail::thread_data_ptr thread_info;
 
         void start_thread();
         
- explicit thread(boost::shared_ptr<detail::thread_data_base> data);
+ explicit thread(detail::thread_data_ptr data);
 
- boost::shared_ptr<detail::thread_data_base> get_thread_info() const;
+ detail::thread_data_ptr get_thread_info() const;
         
     public:
         thread();
@@ -219,10 +237,7 @@
             ~restore_interruption();
         };
 
- inline thread::id get_id()
- {
- return thread::id(pthread_self());
- }
+ BOOST_THREAD_DECL thread::id get_id();
 
         BOOST_THREAD_DECL void interruption_point();
         BOOST_THREAD_DECL bool interruption_enabled();

Modified: trunk/boost/thread/pthread/thread_data.hpp
==============================================================================
--- trunk/boost/thread/pthread/thread_data.hpp (original)
+++ trunk/boost/thread/pthread/thread_data.hpp 2007-12-19 05:39:45 EST (Wed, 19 Dec 2007)
@@ -7,6 +7,7 @@
 
 #include <boost/thread/detail/config.hpp>
 #include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
 #include <boost/thread/mutex.hpp>
 #include <boost/optional.hpp>
 #include <pthread.h>
@@ -21,10 +22,14 @@
     {
         struct thread_exit_callback_node;
         struct tss_data_node;
+
+ struct thread_data_base;
+ typedef boost::shared_ptr<thread_data_base> thread_data_ptr;
         
- struct thread_data_base
+ struct thread_data_base:
+ enable_shared_from_this<thread_data_base>
         {
- boost::shared_ptr<thread_data_base> self;
+ thread_data_ptr self;
             pthread_t thread_handle;
             boost::mutex data_mutex;
             boost::condition_variable done_condition;

Modified: trunk/boost/thread/win32/thread.hpp
==============================================================================
--- trunk/boost/thread/win32/thread.hpp (original)
+++ trunk/boost/thread/win32/thread.hpp 2007-12-19 05:39:45 EST (Wed, 19 Dec 2007)
@@ -364,7 +364,14 @@
         friend std::basic_ostream<charT, traits>&
         operator<<(std::basic_ostream<charT, traits>& os, const id& x)
         {
- return os<<x.thread_data;
+ if(x.thread_data)
+ {
+ return os<<x.thread_data;
+ }
+ else
+ {
+ return os<<"{Not-any-thread}";
+ }
         }
 
         void interrupt()

Modified: trunk/libs/thread/src/pthread/thread.cpp
==============================================================================
--- trunk/libs/thread/src/pthread/thread.cpp (original)
+++ trunk/libs/thread/src/pthread/thread.cpp 2007-12-19 05:39:45 EST (Wed, 19 Dec 2007)
@@ -229,7 +229,7 @@
         return !operator==(other);
     }
 
- boost::shared_ptr<detail::thread_data_base> thread::get_thread_info() const
+ detail::thread_data_ptr thread::get_thread_info() const
     {
         lock_guard<mutex> l(thread_info_mutex);
         return thread_info;
@@ -237,7 +237,7 @@
 
     void thread::join()
     {
- boost::shared_ptr<detail::thread_data_base> const local_thread_info=get_thread_info();
+ detail::thread_data_ptr const local_thread_info=get_thread_info();
         if(local_thread_info)
         {
             bool do_join=false;
@@ -281,7 +281,7 @@
 
     bool thread::timed_join(system_time const& wait_until)
     {
- boost::shared_ptr<detail::thread_data_base> const local_thread_info=get_thread_info();
+ detail::thread_data_ptr const local_thread_info=get_thread_info();
         if(local_thread_info)
         {
             bool do_join=false;
@@ -335,7 +335,7 @@
 
     void thread::detach()
     {
- boost::shared_ptr<detail::thread_data_base> local_thread_info;
+ detail::thread_data_ptr local_thread_info;
         {
             lock_guard<mutex> l1(thread_info_mutex);
             thread_info.swap(local_thread_info);
@@ -413,10 +413,10 @@
 
     thread::id thread::get_id() const
     {
- boost::shared_ptr<detail::thread_data_base> local_thread_info=get_thread_info();
+ detail::thread_data_ptr const local_thread_info=get_thread_info();
         if(local_thread_info)
         {
- return id(local_thread_info->thread_handle);
+ return id(local_thread_info);
         }
         else
         {
@@ -426,7 +426,7 @@
 
     void thread::interrupt()
     {
- boost::shared_ptr<detail::thread_data_base> local_thread_info=get_thread_info();
+ detail::thread_data_ptr const local_thread_info=get_thread_info();
         if(local_thread_info)
         {
             lock_guard<mutex> lk(local_thread_info->data_mutex);
@@ -440,7 +440,7 @@
 
     bool thread::interruption_requested() const
     {
- boost::shared_ptr<detail::thread_data_base> local_thread_info=get_thread_info();
+ detail::thread_data_ptr const local_thread_info=get_thread_info();
         if(local_thread_info)
         {
             lock_guard<mutex> lk(local_thread_info->data_mutex);
@@ -455,6 +455,12 @@
 
     namespace this_thread
     {
+ thread::id get_id()
+ {
+ boost::detail::thread_data_base* const thread_info=get_or_make_current_thread_data();
+ return thread::id(thread_info?thread_info->shared_from_this():detail::thread_data_ptr());
+ }
+
         void interruption_point()
         {
             boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data();

Modified: trunk/libs/thread/test/Jamfile.v2
==============================================================================
--- trunk/libs/thread/test/Jamfile.v2 (original)
+++ trunk/libs/thread/test/Jamfile.v2 2007-12-19 05:39:45 EST (Wed, 19 Dec 2007)
@@ -35,6 +35,7 @@
 {
     test-suite "threads"
         : [ thread-run test_thread.cpp ]
+ [ thread-run test_thread_id.cpp ]
           [ thread-run test_thread_move.cpp ]
           [ thread-run test_move_function.cpp ]
           [ thread-run test_mutex.cpp ]

Added: trunk/libs/thread/test/test_thread_id.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/test_thread_id.cpp 2007-12-19 05:39:45 EST (Wed, 19 Dec 2007)
@@ -0,0 +1,147 @@
+// Copyright (C) 2007 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/thread/thread.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/bind.hpp>
+
+void do_nothing()
+{}
+
+void test_thread_id_for_default_constructed_thread_is_default_constructed_id()
+{
+ boost::thread t;
+ BOOST_CHECK(t.get_id()==boost::thread::id());
+}
+
+void test_thread_id_for_running_thread_is_not_default_constructed_id()
+{
+ boost::thread t(do_nothing);
+ BOOST_CHECK(t.get_id()!=boost::thread::id());
+ t.join();
+}
+
+void test_different_threads_have_different_ids()
+{
+ boost::thread t(do_nothing);
+ boost::thread t2(do_nothing);
+ BOOST_CHECK(t.get_id()!=t2.get_id());
+ t.join();
+ t2.join();
+}
+
+void test_thread_ids_have_a_total_order()
+{
+ boost::thread t(do_nothing);
+ boost::thread t2(do_nothing);
+ boost::thread t3(do_nothing);
+ BOOST_CHECK(t.get_id()!=t2.get_id());
+ BOOST_CHECK(t.get_id()!=t3.get_id());
+ BOOST_CHECK(t2.get_id()!=t3.get_id());
+
+ BOOST_CHECK((t.get_id()<t2.get_id()) != (t2.get_id()<t.get_id()));
+ BOOST_CHECK((t.get_id()<t3.get_id()) != (t3.get_id()<t.get_id()));
+ BOOST_CHECK((t2.get_id()<t3.get_id()) != (t3.get_id()<t2.get_id()));
+
+ BOOST_CHECK((t.get_id()>t2.get_id()) != (t2.get_id()>t.get_id()));
+ BOOST_CHECK((t.get_id()>t3.get_id()) != (t3.get_id()>t.get_id()));
+ BOOST_CHECK((t2.get_id()>t3.get_id()) != (t3.get_id()>t2.get_id()));
+
+ BOOST_CHECK((t.get_id()<t2.get_id()) == (t2.get_id()>t.get_id()));
+ BOOST_CHECK((t2.get_id()<t.get_id()) == (t.get_id()>t2.get_id()));
+ BOOST_CHECK((t.get_id()<t3.get_id()) == (t3.get_id()>t.get_id()));
+ BOOST_CHECK((t3.get_id()<t.get_id()) == (t.get_id()>t3.get_id()));
+ BOOST_CHECK((t2.get_id()<t3.get_id()) == (t3.get_id()>t2.get_id()));
+ BOOST_CHECK((t3.get_id()<t2.get_id()) == (t2.get_id()>t3.get_id()));
+
+ BOOST_CHECK((t.get_id()<t2.get_id()) == (t2.get_id()>=t.get_id()));
+ BOOST_CHECK((t2.get_id()<t.get_id()) == (t.get_id()>=t2.get_id()));
+ BOOST_CHECK((t.get_id()<t3.get_id()) == (t3.get_id()>=t.get_id()));
+ BOOST_CHECK((t3.get_id()<t.get_id()) == (t.get_id()>=t3.get_id()));
+ BOOST_CHECK((t2.get_id()<t3.get_id()) == (t3.get_id()>=t2.get_id()));
+ BOOST_CHECK((t3.get_id()<t2.get_id()) == (t2.get_id()>=t3.get_id()));
+
+ BOOST_CHECK((t.get_id()<=t2.get_id()) == (t2.get_id()>t.get_id()));
+ BOOST_CHECK((t2.get_id()<=t.get_id()) == (t.get_id()>t2.get_id()));
+ BOOST_CHECK((t.get_id()<=t3.get_id()) == (t3.get_id()>t.get_id()));
+ BOOST_CHECK((t3.get_id()<=t.get_id()) == (t.get_id()>t3.get_id()));
+ BOOST_CHECK((t2.get_id()<=t3.get_id()) == (t3.get_id()>t2.get_id()));
+ BOOST_CHECK((t3.get_id()<=t2.get_id()) == (t2.get_id()>t3.get_id()));
+
+ if((t.get_id()<t2.get_id()) && (t2.get_id()<t3.get_id()))
+ {
+ BOOST_CHECK(t.get_id()<t3.get_id());
+ }
+ else if((t.get_id()<t3.get_id()) && (t3.get_id()<t2.get_id()))
+ {
+ BOOST_CHECK(t.get_id()<t2.get_id());
+ }
+ else if((t2.get_id()<t3.get_id()) && (t3.get_id()<t.get_id()))
+ {
+ BOOST_CHECK(t2.get_id()<t.get_id());
+ }
+ else if((t2.get_id()<t.get_id()) && (t.get_id()<t3.get_id()))
+ {
+ BOOST_CHECK(t2.get_id()<t3.get_id());
+ }
+ else if((t3.get_id()<t.get_id()) && (t.get_id()<t2.get_id()))
+ {
+ BOOST_CHECK(t3.get_id()<t2.get_id());
+ }
+ else if((t3.get_id()<t2.get_id()) && (t2.get_id()<t.get_id()))
+ {
+ BOOST_CHECK(t3.get_id()<t.get_id());
+ }
+ else
+ {
+ BOOST_CHECK(false);
+ }
+
+ BOOST_CHECK(boost::thread::id() < t.get_id());
+ BOOST_CHECK(boost::thread::id() < t2.get_id());
+ BOOST_CHECK(boost::thread::id() < t3.get_id());
+
+ BOOST_CHECK(boost::thread::id() <= t.get_id());
+ BOOST_CHECK(boost::thread::id() <= t2.get_id());
+ BOOST_CHECK(boost::thread::id() <= t3.get_id());
+
+ BOOST_CHECK(!(boost::thread::id() > t.get_id()));
+ BOOST_CHECK(!(boost::thread::id() > t2.get_id()));
+ BOOST_CHECK(!(boost::thread::id() > t2.get_id()));
+
+ BOOST_CHECK(!(boost::thread::id() >= t.get_id()));
+ BOOST_CHECK(!(boost::thread::id() >= t2.get_id()));
+ BOOST_CHECK(!(boost::thread::id() >= t2.get_id()));
+
+ t.join();
+ t2.join();
+ t3.join();
+}
+
+void get_thread_id(boost::thread::id* id)
+{
+ *id=boost::this_thread::get_id();
+}
+
+void test_thread_id_of_running_thread_returned_by_this_thread_get_id()
+{
+ boost::thread::id id;
+ boost::thread t(boost::bind(get_thread_id,&id));
+ boost::thread::id t_id=t.get_id();
+ t.join();
+ BOOST_CHECK(id==t_id);
+}
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+ boost::unit_test_framework::test_suite* test =
+ BOOST_TEST_SUITE("Boost.Threads: thread move test suite");
+
+ test->add(BOOST_TEST_CASE(test_thread_id_for_default_constructed_thread_is_default_constructed_id));
+ test->add(BOOST_TEST_CASE(test_thread_id_for_running_thread_is_not_default_constructed_id));
+ test->add(BOOST_TEST_CASE(test_different_threads_have_different_ids));
+ test->add(BOOST_TEST_CASE(test_thread_ids_have_a_total_order));
+ test->add(BOOST_TEST_CASE(test_thread_id_of_running_thread_returned_by_this_thread_get_id));
+ return test;
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk