|
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 ¤t_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