Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r80236 - in trunk: boost/thread/detail boost/thread/win32 libs/thread/build libs/thread/src/win32 libs/thread/test libs/thread/test/threads/thread/members
From: vicente.botet_at_[hidden]
Date: 2012-08-26 11:17:40


Author: viboes
Date: 2012-08-26 11:17:39 EDT (Sun, 26 Aug 2012)
New Revision: 80236
URL: http://svn.boost.org/trac/boost/changeset/80236

Log:
Thread: 7045: make boost_thread don't depend on boost_chrono for win and 2797: armonize win behavior with posix one.
Text files modified:
   trunk/boost/thread/detail/thread.hpp | 30 +++-------
   trunk/boost/thread/win32/thread_data.hpp | 17 ++++-
   trunk/libs/thread/build/Jamfile.v2 | 5 -
   trunk/libs/thread/src/win32/thread.cpp | 114 +++++++++++++++++----------------------
   trunk/libs/thread/test/Jamfile.v2 | 12 ++--
   trunk/libs/thread/test/threads/thread/members/join_pass.cpp | 48 ++++++++++-----
   6 files changed, 112 insertions(+), 114 deletions(-)

Modified: trunk/boost/thread/detail/thread.hpp
==============================================================================
--- trunk/boost/thread/detail/thread.hpp (original)
+++ trunk/boost/thread/detail/thread.hpp 2012-08-26 11:17:39 EDT (Sun, 26 Aug 2012)
@@ -364,29 +364,17 @@
 #endif
 #if defined(BOOST_THREAD_PLATFORM_WIN32)
         bool timed_join(const system_time& abs_time);
-
+ private:
+ bool do_try_join_until(uintmax_t milli);
+ public:
 #ifdef BOOST_THREAD_USES_CHRONO
- bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp);
-// bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
-// {
-// if (this_thread::get_id() == get_id())
-// {
-// boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself"));
-// }
-// detail::thread_data_ptr local_thread_info=(get_thread_info)();
-// if(local_thread_info)
-// {
-// chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
-// if(!this_thread::interruptible_wait(local_thread_info->thread_handle,rel_time.count()))
-// {
-// return false;
-// }
-// release_handle();
-// }
-// return true;
-// }
+ bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
+ {
+ chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
+ return do_try_join_until(rel_time.count());
+ }
 #endif
- public:
+
 
 #else
         bool timed_join(const system_time& abs_time)

Modified: trunk/boost/thread/win32/thread_data.hpp
==============================================================================
--- trunk/boost/thread/win32/thread_data.hpp (original)
+++ trunk/boost/thread/win32/thread_data.hpp 2012-08-26 11:17:39 EDT (Sun, 26 Aug 2012)
@@ -11,6 +11,7 @@
 #include <boost/thread/thread_time.hpp>
 #include <boost/thread/win32/thread_primitives.hpp>
 #include <boost/thread/win32/thread_heap_alloc.hpp>
+#include <map>
 #ifdef BOOST_THREAD_USES_CHRONO
 #include <boost/chrono/system_clocks.hpp>
 #endif
@@ -58,8 +59,18 @@
 
     namespace detail
     {
+ struct tss_cleanup_function;
         struct thread_exit_callback_node;
- struct tss_data_node;
+ struct tss_data_node
+ {
+ boost::shared_ptr<boost::detail::tss_cleanup_function> func;
+ void* value;
+
+ tss_data_node(boost::shared_ptr<boost::detail::tss_cleanup_function> func_,
+ void* value_):
+ func(func_),value(value_)
+ {}
+ };
 
         struct thread_data_base;
         void intrusive_ptr_add_ref(thread_data_base * p);
@@ -71,14 +82,14 @@
             detail::win32::handle_manager thread_handle;
             detail::win32::handle_manager interruption_handle;
             boost::detail::thread_exit_callback_node* thread_exit_callbacks;
- boost::detail::tss_data_node* tss_data;
+ std::map<void const*,boost::detail::tss_data_node> tss_data;
             bool interruption_enabled;
             unsigned id;
 
             thread_data_base():
                 count(0),thread_handle(detail::win32::invalid_handle_value),
                 interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset)),
- thread_exit_callbacks(0),tss_data(0),
+ thread_exit_callbacks(0),tss_data(),
                 interruption_enabled(true),
                 id(0)
             {}

Modified: trunk/libs/thread/build/Jamfile.v2
==============================================================================
--- trunk/libs/thread/build/Jamfile.v2 (original)
+++ trunk/libs/thread/build/Jamfile.v2 2012-08-26 11:17:39 EDT (Sun, 26 Aug 2012)
@@ -236,10 +236,7 @@
             }
         }
     }
- if ! <toolset>vacpp in $(properties) || <toolset-vacpp:version>11.1 in $(properties)
- {
- result += <library>/boost/chrono//boost_chrono ;
- }
+ result += <define>BOOST_THREAD_DONT_USE_CHRONO ;
 
     return $(result) ;
 }

Modified: trunk/libs/thread/src/win32/thread.cpp
==============================================================================
--- trunk/libs/thread/src/win32/thread.cpp (original)
+++ trunk/libs/thread/src/win32/thread.cpp 2012-08-26 11:17:39 EDT (Sun, 26 Aug 2012)
@@ -128,19 +128,6 @@
             {}
         };
 
- struct tss_data_node
- {
- void const* key;
- boost::shared_ptr<boost::detail::tss_cleanup_function> func;
- void* value;
- tss_data_node* next;
-
- tss_data_node(void const* key_,boost::shared_ptr<boost::detail::tss_cleanup_function> func_,void* value_,
- tss_data_node* next_):
- key(key_),func(func_),value(value_),next(next_)
- {}
- };
-
     }
 
     namespace
@@ -150,7 +137,7 @@
             detail::thread_data_ptr current_thread_data(get_current_thread_data(),false);
             if(current_thread_data)
             {
- while(current_thread_data->tss_data || current_thread_data->thread_exit_callbacks)
+ while(! current_thread_data->tss_data.empty() || current_thread_data->thread_exit_callbacks)
                 {
                     while(current_thread_data->thread_exit_callbacks)
                     {
@@ -163,15 +150,18 @@
                         }
                         boost::detail::heap_delete(current_node);
                     }
- while(current_thread_data->tss_data)
+ for(std::map<void const*,detail::tss_data_node>::iterator next=current_thread_data->tss_data.begin(),
+ current,
+ end=current_thread_data->tss_data.end();
+ next!=end;)
                     {
- detail::tss_data_node* const current_node=current_thread_data->tss_data;
- current_thread_data->tss_data=current_node->next;
- if(current_node->func)
+ current=next;
+ ++next;
+ if(current->second.func && (current->second.value!=0))
                         {
- (*current_node->func)(current_node->value);
+ (*current->second.func)(current->second.value);
                         }
- boost::detail::heap_delete(current_node);
+ current_thread_data->tss_data.erase(current);
                     }
                 }
 
@@ -301,7 +291,6 @@
     {
         return (get_thread_info)();
     }
-
     void thread::join()
     {
         if (this_thread::get_id() == get_id())
@@ -318,45 +307,27 @@
 
     bool thread::timed_join(boost::system_time const& wait_until)
     {
- if (this_thread::get_id() == get_id())
- {
- boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself"));
- }
- detail::thread_data_ptr local_thread_info=(get_thread_info)();
- if(local_thread_info)
- {
- if(!this_thread::interruptible_wait(local_thread_info->thread_handle,get_milliseconds_until(wait_until)))
- {
- return false;
- }
- release_handle();
- }
- return true;
+ return do_try_join_until(get_milliseconds_until(wait_until));
     }
 
-#ifdef BOOST_THREAD_USES_CHRONO
-
- bool thread::try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
+ bool thread::do_try_join_until(uintmax_t milli)
     {
       if (this_thread::get_id() == get_id())
       {
- boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself"));
+ boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself"));
       }
       detail::thread_data_ptr local_thread_info=(get_thread_info)();
       if(local_thread_info)
       {
- chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
- if(!this_thread::interruptible_wait(local_thread_info->thread_handle,rel_time.count()))
- {
- return false;
- }
- release_handle();
+ if(!this_thread::interruptible_wait(local_thread_info->thread_handle,milli))
+ {
+ return false;
+ }
+ release_handle();
       }
       return true;
     }
 
-#endif
-
     void thread::detach() BOOST_NOEXCEPT
     {
         release_handle();
@@ -636,14 +607,11 @@
             detail::thread_data_base* const current_thread_data(get_current_thread_data());
             if(current_thread_data)
             {
- detail::tss_data_node* current_node=current_thread_data->tss_data;
- while(current_node)
+ std::map<void const*,tss_data_node>::iterator current_node=
+ current_thread_data->tss_data.find(key);
+ if(current_node!=current_thread_data->tss_data.end())
                 {
- if(current_node->key==key)
- {
- return current_node;
- }
- current_node=current_node->next;
+ return &current_node->second;
                 }
             }
             return NULL;
@@ -658,23 +626,43 @@
             return NULL;
         }
 
- void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing)
+ void add_new_tss_node(void const* key,
+ boost::shared_ptr<tss_cleanup_function> func,
+ void* tss_data)
+ {
+ detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
+ current_thread_data->tss_data.insert(std::make_pair(key,tss_data_node(func,tss_data)));
+ }
+
+ void erase_tss_node(void const* key)
+ {
+ detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
+ current_thread_data->tss_data.erase(key);
+ }
+
+ void set_tss_data(void const* key,
+ boost::shared_ptr<tss_cleanup_function> func,
+ void* tss_data,bool cleanup_existing)
         {
             if(tss_data_node* const current_node=find_tss_data(key))
             {
- if(cleanup_existing && current_node->func.get() && current_node->value)
+ if(cleanup_existing && current_node->func && (current_node->value!=0))
                 {
                     (*current_node->func)(current_node->value);
                 }
- current_node->func=func;
- current_node->value=tss_data;
+ if(func || (tss_data!=0))
+ {
+ current_node->func=func;
+ current_node->value=tss_data;
+ }
+ else
+ {
+ erase_tss_node(key);
+ }
             }
- else if(func && tss_data)
+ else
             {
- detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
- tss_data_node* const new_node=
- heap_new<tss_data_node>(key,func,tss_data,current_thread_data->tss_data);
- current_thread_data->tss_data=new_node;
+ add_new_tss_node(key,func,tss_data);
             }
         }
     }

Modified: trunk/libs/thread/test/Jamfile.v2
==============================================================================
--- trunk/libs/thread/test/Jamfile.v2 (original)
+++ trunk/libs/thread/test/Jamfile.v2 2012-08-26 11:17:39 EDT (Sun, 26 Aug 2012)
@@ -44,7 +44,7 @@
         <toolset>clang:<cxxflags>-pedantic
         <toolset>clang:<cxxflags>-Wno-long-long
         <toolset>clang:<cxxflags>-ansi
- #<toolset>clang:<cxxflags>-fpermissive # doesn't work
+ #<toolset>clang:<cxxflags>-fpermissive # doesn't work
 
         <toolset>gcc-mingw-4.4.0:<cxxflags>-fdiagnostics-show-option
         <toolset>gcc-mingw-4.5.0:<cxxflags>-fdiagnostics-show-option
@@ -80,13 +80,13 @@
 rule thread-test ( sources )
 {
     return
- [ run $(sources) ../build//boost_thread : : :
- <library>/boost/test//boost_unit_test_framework/<link>static
+ [ run $(sources) ../build//boost_thread : : :
+ <library>/boost/test//boost_unit_test_framework/<link>static
     ]
     [ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
- : : :
- <library>/boost/test//boost_unit_test_framework/<link>static
- : $(sources[1]:B)_lib
+ : : :
+ <library>/boost/test//boost_unit_test_framework/<link>static
+ : $(sources[1]:B)_lib
     ]
     ;
 }

Modified: trunk/libs/thread/test/threads/thread/members/join_pass.cpp
==============================================================================
--- trunk/libs/thread/test/threads/thread/members/join_pass.cpp (original)
+++ trunk/libs/thread/test/threads/thread/members/join_pass.cpp 2012-08-26 11:17:39 EDT (Sun, 26 Aug 2012)
@@ -53,7 +53,6 @@
   void operator()()
   {
     BOOST_TEST(alive_ == 1);
- std::cout << __FILE__ << ":" << __LINE__ <<" " << n_alive << std::endl;
     BOOST_TEST(n_alive == 1);
     op_run = true;
   }
@@ -62,58 +61,73 @@
 int G::n_alive = 0;
 bool G::op_run = false;
 
-boost::thread* resource_deadlock_would_occur_th;
+boost::thread* resource_deadlock_would_occur_th=0;
 boost::mutex resource_deadlock_would_occur_mtx;
 void resource_deadlock_would_occur_tester()
 {
   try
   {
- std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
     boost::unique_lock<boost::mutex> lk(resource_deadlock_would_occur_mtx);
- std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
+
 
     resource_deadlock_would_occur_th->join();
- std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
     BOOST_TEST(false);
- std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
   }
   catch (boost::system::system_error& e)
   {
- std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
     BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
   }
   catch (...)
   {
- std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
     BOOST_TEST(false&&"exception thrown");
   }
 }
 
+void throws_thread_resource_error_tester()
+{
+ {
+ try {
+ boost::throw_exception(
+ boost::thread_resource_error(
+ boost::system::errc::resource_deadlock_would_occur,
+ "boost thread: trying joining itself"
+ ));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false&&"exception thrown");
+ }
+ }
+}
+
 int main()
 {
   {
- std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
     boost::thread t0( (G()));
     BOOST_TEST(t0.joinable());
     t0.join();
     BOOST_TEST(!t0.joinable());
   }
+
+ {
+ boost::thread t0( throws_thread_resource_error_tester );
+ t0.join();
+ }
   {
- std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
     boost::unique_lock<boost::mutex> lk(resource_deadlock_would_occur_mtx);
- std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
     boost::thread t0( resource_deadlock_would_occur_tester );
- std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
     resource_deadlock_would_occur_th = &t0;
- std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
     BOOST_TEST(t0.joinable());
- std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
     lk.unlock();
- std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
+ boost::unique_lock<boost::mutex> lk2(resource_deadlock_would_occur_mtx);
     t0.join();
- std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
     BOOST_TEST(!t0.joinable());
- std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
   }
 
 // {


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