|
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