Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r80351 - in trunk: boost/thread/detail boost/thread/pthread boost/thread/win32 libs/thread/build libs/thread/doc libs/thread/src/pthread libs/thread/src/win32 libs/thread/test libs/thread/test/sync/conditions libs/thread/test/threads/thread/assign libs/thread/test/threads/thread/members
From: vicente.botet_at_[hidden]
Date: 2012-09-01 13:10:18


Author: viboes
Date: 2012-09-01 13:10:16 EDT (Sat, 01 Sep 2012)
New Revision: 80351
URL: http://svn.boost.org/trac/boost/changeset/80351

Log:
Thread: Added notify_all_at_thread_exit+join can throw conditionally if not joinable + detach is no more noexcept
Added:
   trunk/libs/thread/test/sync/conditions/notify_all_at_thread_exit_pass.cpp (contents, props changed)
   trunk/libs/thread/test/threads/thread/members/try_join_for_pass.cpp (contents, props changed)
   trunk/libs/thread/test/threads/thread/members/try_join_until_pass.cpp (contents, props changed)
Text files modified:
   trunk/boost/thread/detail/config.hpp | 65 +++++++++++++++--------------
   trunk/boost/thread/detail/thread.hpp | 7 ++
   trunk/boost/thread/pthread/condition_variable_fwd.hpp | 3 +
   trunk/boost/thread/pthread/thread_data.hpp | 28 ++++++++++--
   trunk/boost/thread/win32/condition_variable.hpp | 19 +++++---
   trunk/boost/thread/win32/thread_data.hpp | 31 +++++++++++--
   trunk/libs/thread/build/Jamfile.v2 | 2
   trunk/libs/thread/doc/thread_ref.qbk | 42 ++++++++++++------
   trunk/libs/thread/src/pthread/thread.cpp | 41 ++++++++++++++++-
   trunk/libs/thread/src/win32/thread.cpp | 58 ++++++++++++++++++++++----
   trunk/libs/thread/src/win32/tss_dll.cpp | 1
   trunk/libs/thread/test/Jamfile.v2 | 3 +
   trunk/libs/thread/test/threads/thread/assign/move_pass.cpp | 16 +++---
   trunk/libs/thread/test/threads/thread/members/join_pass.cpp | 88 +++++++++++++--------------------------
   14 files changed, 258 insertions(+), 146 deletions(-)

Modified: trunk/boost/thread/detail/config.hpp
==============================================================================
--- trunk/boost/thread/detail/config.hpp (original)
+++ trunk/boost/thread/detail/config.hpp 2012-09-01 13:10:16 EDT (Sat, 01 Sep 2012)
@@ -12,27 +12,25 @@
 #include <boost/detail/workaround.hpp>
 
 // This compiler doesn't support Boost.Chrono
-#if defined __IBMCPP__ && (__IBMCPP__ < 1100)
-#if ! defined BOOST_THREAD_DONT_USE_CHRONO
+#if defined __IBMCPP__ && (__IBMCPP__ < 1100) && ! defined BOOST_THREAD_DONT_USE_CHRONO
 #define BOOST_THREAD_DONT_USE_CHRONO
 #endif
-#endif
 
 // This compiler doesn't support Boost.Move
-#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
+#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) && ! defined BOOST_THREAD_DONT_USE_MOVE
 #define BOOST_THREAD_DONT_USE_MOVE
 #endif
 
 // This compiler doesn't support Boost.Container Allocators files
-#if defined __SUNPRO_CC
+#if defined __SUNPRO_CC && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
 #define BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
 #endif
 
-#if defined _WIN32_WCE && _WIN32_WCE==0x501
+#if defined _WIN32_WCE && _WIN32_WCE==0x501 && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
 #define BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
 #endif
 
-#if ! defined BOOST_THREAD_DONT_PROVIDE_BASIC_THREAD_ID
+#if ! defined BOOST_THREAD_DONT_PROVIDE_BASIC_THREAD_ID && ! defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
 #define BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
 #endif
 
@@ -46,12 +44,12 @@
 #endif
 
 // Uses Boost.System by default if not stated the opposite defining BOOST_THREAD_DONT_USE_SYSTEM
-#if ! defined BOOST_THREAD_DONT_USE_SYSTEM
+#if ! defined BOOST_THREAD_DONT_USE_SYSTEM && ! defined BOOST_THREAD_USES_SYSTEM
 #define BOOST_THREAD_USES_SYSTEM
 #endif
 
 // Uses Boost.Chrono by default if not stated the opposite defining BOOST_THREAD_DONT_USE_CHRONO or BOOST_THREAD_DONT_USE_SYSTEM
-#if ! defined BOOST_THREAD_DONT_USE_CHRONO && ! defined BOOST_THREAD_DONT_USE_SYSTEM
+#if ! defined BOOST_THREAD_DONT_USE_CHRONO && ! defined BOOST_THREAD_DONT_USE_SYSTEM && ! defined BOOST_THREAD_USES_CHRONO
 #define BOOST_THREAD_USES_CHRONO
 #endif
 
@@ -63,15 +61,8 @@
 #endif
 
 
-// Uses Boost.Move by default if not stated the opposite defining BOOST_THREAD_DONT_USE_MOVE
-#if ! defined BOOST_THREAD_DONT_USE_MOVE
-#if ! defined BOOST_THREAD_USES_MOVE
-//#define BOOST_THREAD_USES_MOVE
-#endif
-#endif
-
 #if BOOST_THREAD_VERSION==2
-#if ! defined BOOST_THREAD_DONT_PROVIDE_PROMISE_LAZY
+#if ! defined BOOST_THREAD_DONT_PROVIDE_PROMISE_LAZY && ! defined BOOST_THREAD_PROMISE_LAZY
 #define BOOST_THREAD_PROMISE_LAZY
 #endif
 #if ! defined BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0
@@ -80,49 +71,59 @@
 #endif
 
 #if BOOST_THREAD_VERSION==3
-#if ! defined BOOST_THREAD_DONT_PROVIDE_ONCE_CXX11
+#if ! defined BOOST_THREAD_DONT_PROVIDE_ONCE_CXX11 \
+ && ! defined BOOST_THREAD_PROVIDES_ONCE_CXX11
 #define BOOST_THREAD_PROVIDES_ONCE_CXX11
 #endif
-#if ! defined BOOST_THREAD_DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
+#if ! defined BOOST_THREAD_DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE \
+ && ! defined BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
 #define BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
 #endif
-#if ! defined BOOST_THREAD_DONT_PROVIDE_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
+#if ! defined BOOST_THREAD_DONT_PROVIDE_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE \
+ && ! defined BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
 #define BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
 #endif
-#if ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE
+#if ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE \
+ && ! defined BOOST_THREAD_PROVIDES_FUTURE
 #define BOOST_THREAD_PROVIDES_FUTURE
 #endif
-#if ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
+#if ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS \
+ && ! defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
 #define BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
 #endif
-#if ! defined BOOST_THREAD_DONT_PROVIDE_SHARED_MUTEX_UPWARDS_CONVERSIONS
+#if ! defined BOOST_THREAD_DONT_PROVIDE_SHARED_MUTEX_UPWARDS_CONVERSIONS \
+ && ! defined BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
 #define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
 #endif
-#if ! defined BOOST_THREAD_DONT_PROVIDE_EXPLICIT_LOCK_CONVERSION
+#if ! defined BOOST_THREAD_DONT_PROVIDE_EXPLICIT_LOCK_CONVERSION \
+ && ! defined BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
 #define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
 #endif
-#if ! defined BOOST_THREAD_DONT_PROVIDE_GENERIC_SHARED_MUTEX_ON_WIN
+#if ! defined BOOST_THREAD_DONT_PROVIDE_GENERIC_SHARED_MUTEX_ON_WIN \
+ && ! defined BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
 #define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
 #endif
-#if ! defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
+#if ! defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 \
+ && ! defined BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_
 #define BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0
 #endif
-#if ! defined BOOST_THREAD_DONT_USE_MOVE
-#if ! defined BOOST_THREAD_USES_MOVE
+#if ! defined BOOST_THREAD_DONT_USE_MOVE \
+ && ! defined BOOST_THREAD_USES_MOVE
 #define BOOST_THREAD_USES_MOVE
 #endif
-#endif
 
 #endif
 
 // BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN is defined if BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
-#if defined BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+#if defined BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS \
+&& ! defined BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
 #define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
 #endif
 
 // BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 defined by default up to Boost 1.52
 // BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0 defined by default up to Boost 1.55
-#if ! defined BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0
+#if ! defined BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0 \
+&& ! defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
 #define BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
 #endif
 
@@ -137,7 +138,7 @@
 
 // provided for backwards compatibility, since this
 // macro was used for several releases by mistake.
-#if defined(BOOST_THREAD_DYN_DLL)
+#if defined(BOOST_THREAD_DYN_DLL) && ! defined BOOST_THREAD_DYN_LINK
 # define BOOST_THREAD_DYN_LINK
 #endif
 

Modified: trunk/boost/thread/detail/thread.hpp
==============================================================================
--- trunk/boost/thread/detail/thread.hpp (original)
+++ trunk/boost/thread/detail/thread.hpp 2012-09-01 13:10:16 EDT (Sat, 01 Sep 2012)
@@ -23,6 +23,8 @@
 #include <boost/bind.hpp>
 #include <stdlib.h>
 #include <memory>
+//#include <vector>
+//#include <utility>
 #include <boost/utility/enable_if.hpp>
 #include <boost/type_traits/remove_reference.hpp>
 #include <boost/io/ios_state.hpp>
@@ -69,10 +71,13 @@
                 f(f_)
             {}
 #endif
+ //thread_data() {}
+
             void run()
             {
                 f();
             }
+
         private:
             F f;
         };
@@ -406,7 +411,7 @@
             return timed_join(get_system_time()+rel_time);
         }
 
- void detach() BOOST_NOEXCEPT;
+ void detach();
 
         static unsigned hardware_concurrency() BOOST_NOEXCEPT;
 

Modified: trunk/boost/thread/pthread/condition_variable_fwd.hpp
==============================================================================
--- trunk/boost/thread/pthread/condition_variable_fwd.hpp (original)
+++ trunk/boost/thread/pthread/condition_variable_fwd.hpp 2012-09-01 13:10:16 EDT (Sat, 01 Sep 2012)
@@ -229,8 +229,11 @@
             unique_lock<mutex>& lock,
             struct timespec const &timeout);
     };
+
+ BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
 }
 
+
 #include <boost/config/abi_suffix.hpp>
 
 #endif

Modified: trunk/boost/thread/pthread/thread_data.hpp
==============================================================================
--- trunk/boost/thread/pthread/thread_data.hpp (original)
+++ trunk/boost/thread/pthread/thread_data.hpp 2012-09-01 13:10:16 EDT (Sat, 01 Sep 2012)
@@ -8,18 +8,25 @@
 
 #include <boost/thread/detail/config.hpp>
 #include <boost/thread/exceptions.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/pthread/condition_variable_fwd.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>
 #include <boost/assert.hpp>
-#include <boost/thread/pthread/condition_variable_fwd.hpp>
-#include <map>
-#include <unistd.h>
 #ifdef BOOST_THREAD_USES_CHRONO
 #include <boost/chrono/system_clocks.hpp>
 #endif
+
+#include <map>
+#include <vector>
+#include <utility>
+
+#include <pthread.h>
+#include <unistd.h>
+
 #include <boost/config/abi_prefix.hpp>
 
 namespace boost
@@ -104,19 +111,28 @@
             bool interrupt_requested;
             pthread_mutex_t* cond_mutex;
             pthread_cond_t* current_cond;
+ typedef std::vector<std::pair<condition_variable*, mutex*>
+ //, hidden_allocator<std::pair<condition_variable*, mutex*> >
+ > notify_list_t;
+ notify_list_t notify;
 
             thread_data_base():
                 done(false),join_started(false),joined(false),
                 thread_exit_callbacks(0),
                 interrupt_enabled(true),
                 interrupt_requested(false),
- current_cond(0)
+ current_cond(0),
+ notify()
             {}
             virtual ~thread_data_base();
 
             typedef pthread_t native_handle_type;
 
             virtual void run()=0;
+ void notify_all_at_thread_exit(condition_variable* cv, mutex* m)
+ {
+ notify.push_back(std::pair<condition_variable*, mutex*>(cv, m));
+ }
         };
 
         BOOST_THREAD_DECL thread_data_base* get_current_thread_data();

Modified: trunk/boost/thread/win32/condition_variable.hpp
==============================================================================
--- trunk/boost/thread/win32/condition_variable.hpp (original)
+++ trunk/boost/thread/win32/condition_variable.hpp 2012-09-01 13:10:16 EDT (Sat, 01 Sep 2012)
@@ -6,23 +6,27 @@
 // (C) Copyright 2007-8 Anthony Williams
 // (C) Copyright 2011-2012 Vicente J. Botet Escriba
 
-#include <boost/thread/mutex.hpp>
 #include <boost/thread/win32/thread_primitives.hpp>
-#include <limits.h>
-#include <boost/assert.hpp>
-#include <algorithm>
-#include <boost/thread/cv_status.hpp>
 #include <boost/thread/win32/thread_data.hpp>
-#include <boost/thread/thread_time.hpp>
+#include <boost/thread/win32/thread_data.hpp>
 #include <boost/thread/win32/interlocked_read.hpp>
+#include <boost/thread/cv_status.hpp>
 #include <boost/thread/xtime.hpp>
-#include <vector>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread_time.hpp>
+
+#include <boost/assert.hpp>
 #include <boost/intrusive_ptr.hpp>
+
 #ifdef BOOST_THREAD_USES_CHRONO
 #include <boost/chrono/system_clocks.hpp>
 #include <boost/chrono/ceil.hpp>
 #endif
 
+#include <limits.h>
+#include <algorithm>
+#include <vector>
+
 #include <boost/config/abi_prefix.hpp>
 
 namespace boost
@@ -510,6 +514,7 @@
 #endif
     };
 
+ BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
 }
 
 #include <boost/config/abi_suffix.hpp>

Modified: trunk/boost/thread/win32/thread_data.hpp
==============================================================================
--- trunk/boost/thread/win32/thread_data.hpp (original)
+++ trunk/boost/thread/win32/thread_data.hpp 2012-09-01 13:10:16 EDT (Sat, 01 Sep 2012)
@@ -7,18 +7,26 @@
 // (C) Copyright 2011-2012 Vicente J. Botet Escriba
 
 #include <boost/thread/detail/config.hpp>
-#include <boost/intrusive_ptr.hpp>
 #include <boost/thread/thread_time.hpp>
 #include <boost/thread/win32/thread_primitives.hpp>
 #include <boost/thread/win32/thread_heap_alloc.hpp>
-#include <map>
+
+#include <boost/intrusive_ptr.hpp>
 #ifdef BOOST_THREAD_USES_CHRONO
 #include <boost/chrono/system_clocks.hpp>
 #endif
+
+#include <map>
+#include <vector>
+#include <utility>
+
 #include <boost/config/abi_prefix.hpp>
 
 namespace boost
 {
+ class condition_variable;
+ class mutex;
+
   class thread_attributes {
   public:
       thread_attributes() BOOST_NOEXCEPT {
@@ -76,7 +84,7 @@
         void intrusive_ptr_add_ref(thread_data_base * p);
         void intrusive_ptr_release(thread_data_base * p);
 
- struct BOOST_SYMBOL_VISIBLE thread_data_base
+ struct BOOST_THREAD_DECL thread_data_base
         {
             long count;
             detail::win32::handle_manager thread_handle;
@@ -85,16 +93,21 @@
             std::map<void const*,boost::detail::tss_data_node> tss_data;
             bool interruption_enabled;
             unsigned id;
+ typedef std::vector<std::pair<condition_variable*, mutex*>
+ //, hidden_allocator<std::pair<condition_variable*, mutex*> >
+ > notify_list_t;
+ notify_list_t notify;
+
 
             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(),
                 interruption_enabled(true),
- id(0)
- {}
- virtual ~thread_data_base()
+ id(0),
+ notify()
             {}
+ virtual ~thread_data_base();
 
             friend void intrusive_ptr_add_ref(thread_data_base * p)
             {
@@ -117,6 +130,12 @@
             typedef detail::win32::handle native_handle_type;
 
             virtual void run()=0;
+
+ void notify_all_at_thread_exit(condition_variable* cv, mutex* m)
+ {
+ notify.push_back(std::pair<condition_variable*, mutex*>(cv, m));
+ }
+
         };
 
         typedef boost::intrusive_ptr<detail::thread_data_base> thread_data_ptr;

Modified: trunk/libs/thread/build/Jamfile.v2
==============================================================================
--- trunk/libs/thread/build/Jamfile.v2 (original)
+++ trunk/libs/thread/build/Jamfile.v2 2012-09-01 13:10:16 EDT (Sat, 01 Sep 2012)
@@ -47,6 +47,7 @@
       -<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
       <tag>@$(__name__).tag
       <toolset>gcc:<cxxflags>-Wno-long-long
+ <define>BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
       <define>BOOST_SYSTEM_NO_DEPRECATED
       <library>/boost/system//boost_system
        #-pedantic -ansi -std=gnu++0x -Wextra -fpermissive
@@ -98,6 +99,7 @@
       #<link>shared:<define>BOOST_THREAD_DYN_LINK=1
       <link>static:<define>BOOST_THREAD_BUILD_LIB=1
       <link>shared:<define>BOOST_THREAD_BUILD_DLL=1
+ <define>BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
       <define>BOOST_SYSTEM_NO_DEPRECATED
       <library>/boost/system//boost_system
     ;

Modified: trunk/libs/thread/doc/thread_ref.qbk
==============================================================================
--- trunk/libs/thread/doc/thread_ref.qbk (original)
+++ trunk/libs/thread/doc/thread_ref.qbk 2012-09-01 13:10:16 EDT (Sat, 01 Sep 2012)
@@ -391,7 +391,7 @@
         void swap(thread& x) noexcept;
 
         class id;
- class attributes;
+ class attributes; // EXTENSION
 
         id get_id() const noexcept;
 
@@ -471,7 +471,7 @@
 
 [[Effects:] [Transfers ownership of the thread managed by `other` (if
 any) to `*this`. Version 2: If there was a thread previously associated with
-`*this` then that thread is detached, version 3: If the thread is joinable calls to std::terminate.]]
+`*this` then that thread is detached, Version 3: If the thread is joinable calls to std::terminate.]]
 
 [[Postconditions:] [`other->get_id()==thread::id()` and `get_id()` returns the value of `other.get_id()` prior to the assignment.]]
 
@@ -628,7 +628,7 @@
 
 [variablelist
 
-[[Effects:] [Version 1: If `*this` has an associated thread of execution, calls __detach__, Version 2: If the thread is joinable calls to std::terminate. Destroys `*this`.]]
+[[Effects:] [Version 2: If `*this` has an associated thread of execution, calls __detach__, Version 3: If the thread is joinable calls to std::terminate. Destroys `*this`.]]
 
 [[Throws:] [Nothing.]]
 
@@ -688,10 +688,12 @@
 
 [*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == std::this_thread::get_id().
 
+[*invalid_argument]: if the thread is not joinable and BOOST_THREAD_TRROW_IF_PRECONDITION_NOT_SATISFIED is defined.
+
+
 [/
 [*no_such_process]: if the thread is not valid.
 
-[*invalid_argument]: if the thread is not joinable.
 ]
 
 ]]
@@ -711,7 +713,7 @@
 
 [variablelist
 
-[[Preconditions:] [`this->get_id()!=boost::this_thread::get_id()`]]
+[[Preconditions:] [the thread is joinable.]]
 
 [[Effects:] [If `*this` refers to a thread of execution, waits for that thread of execution to complete, the time `wait_until` has
 been reach or the specified duration `rel_time` has elapsed. If `*this` doesn't refer to a thread of execution, returns immediately.]]
@@ -729,10 +731,11 @@
 
 [*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == std::this_thread::get_id().
 
+[*invalid_argument]: if the thread is not joinable and BOOST_THREAD_TRROW_IF_PRECONDITION_NOT_SATISFIED is defined.
+
+
 [/
 [*no_such_process]: if the thread is not valid.
-
-[*invalid_argument]: if the thread is not joinable.
 ]
 
 ]]
@@ -750,7 +753,7 @@
 
 [variablelist
 
-[[Preconditions:] [`this->get_id()!=boost::this_thread::get_id()`]]
+[[Preconditions:] [the thread is joinable.]]
 
 [[Effects:] [If `*this` refers to a thread of execution, waits for that thread of execution to complete,
 the specified duration `rel_time` has elapsed. If `*this` doesn't refer to a thread of execution, returns immediately.]]
@@ -768,10 +771,11 @@
 
 [*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == std::this_thread::get_id().
 
+[*invalid_argument]: if the thread is not joinable and BOOST_THREAD_TRROW_IF_PRECONDITION_NOT_SATISFIED is defined.
+
+
 [/
 [*no_such_process]: if the thread is not valid.
-
-[*invalid_argument]: if the thread is not joinable.
 ]
 
 ]]
@@ -789,7 +793,7 @@
 
 [variablelist
 
-[[Preconditions:] [`this->get_id()!=boost::this_thread::get_id()`]]
+[[Preconditions:] [the thread is joinable.]]
 
 [[Effects:] [If `*this` refers to a thread of execution, waits for that thread of execution to complete, the time `abs_time` has
 been reach. If `*this` doesn't refer to a thread of execution, returns immediately.]]
@@ -807,10 +811,12 @@
 
 [*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == std::this_thread::get_id().
 
+[*invalid_argument]: if the thread is not joinable and BOOST_THREAD_TRROW_IF_PRECONDITION_NOT_SATISFIED is defined.
+
+
 [/
 [*no_such_process]: if the thread is not valid.
 
-[*invalid_argument]: if the thread is not joinable.
 ]
 
 ]]
@@ -825,7 +831,7 @@
 
 [section:detach Member function `detach()`]
 
- void detach() noexcept;
+ void detach();
 
 [variablelist
 
@@ -835,7 +841,15 @@
 
 [[Postconditions:] [`*this` no longer refers to any thread of execution.]]
 
-[[Throws:] [Nothing]]
+[[Throws:] [`system_error`]]
+
+[[Error Conditions:] [
+
+[*no_such_process]: if the thread is not valid.
+
+[*invalid_argument]: if the thread is not joinable and BOOST_THREAD_TRROW_IF_PRECONDITION_NOT_SATISFIED is defined.
+
+]]
 
 ]
 

Modified: trunk/libs/thread/src/pthread/thread.cpp
==============================================================================
--- trunk/libs/thread/src/pthread/thread.cpp (original)
+++ trunk/libs/thread/src/pthread/thread.cpp 2012-09-01 13:10:16 EDT (Sat, 01 Sep 2012)
@@ -10,11 +10,12 @@
 
 #include <boost/thread/thread.hpp>
 #include <boost/thread/xtime.hpp>
-#include <boost/thread/condition.hpp>
+#include <boost/thread/condition_variable.hpp>
 #include <boost/thread/locks.hpp>
 #include <boost/thread/once.hpp>
 #include <boost/thread/tss.hpp>
 #include <boost/throw_exception.hpp>
+
 #ifdef __GLIBC__
 #include <sys/sysinfo.h>
 #elif defined(__APPLE__) || defined(__FreeBSD__)
@@ -31,7 +32,16 @@
     namespace detail
     {
         thread_data_base::~thread_data_base()
- {}
+ {
+ {
+ for (notify_list_t::iterator i = notify.begin(), e = notify.end();
+ i != e; ++i)
+ {
+ i->second->unlock();
+ i->first->notify_all();
+ }
+ }
+ }
 
         struct thread_exit_callback_node
         {
@@ -175,6 +185,8 @@
 
             void run()
             {}
+ void notify_all_at_thread_exit(condition_variable*, mutex*)
+ {}
 
         private:
             externally_launched_thread(externally_launched_thread&);
@@ -304,6 +316,12 @@
                 thread_info.reset();
             }
         }
+ else
+ {
+#ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
+ boost::throw_exception(thread_resource_error(system::errc::invalid_argument, "boost thread: thread not joinable"));
+#endif
+ }
     }
 
     bool thread::do_try_join_until(struct timespec const &timeout)
@@ -353,8 +371,14 @@
             {
                 thread_info.reset();
             }
+ return true;
+ }
+ else
+ {
+#ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
+ boost::throw_exception(thread_resource_error(system::errc::invalid_argument, "boost thread: thread not joinable"));
+#endif
         }
- return true;
     }
 
     bool thread::joinable() const BOOST_NOEXCEPT
@@ -363,7 +387,7 @@
     }
 
 
- void thread::detach() BOOST_NOEXCEPT
+ void thread::detach()
     {
         detail::thread_data_ptr local_thread_info;
         thread_info.swap(local_thread_info);
@@ -677,6 +701,15 @@
             }
         }
     }
+ BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk)
+ {
+ detail::thread_data_base* const current_thread_data(detail::get_current_thread_data());
+ if(current_thread_data)
+ {
+ current_thread_data->notify_all_at_thread_exit(&cond, lk.release());
+ }
+ }
+
 
 
 }

Modified: trunk/libs/thread/src/win32/thread.cpp
==============================================================================
--- trunk/libs/thread/src/win32/thread.cpp (original)
+++ trunk/libs/thread/src/win32/thread.cpp 2012-09-01 13:10:16 EDT (Sat, 01 Sep 2012)
@@ -13,22 +13,39 @@
 #endif
 
 #include <boost/thread/thread.hpp>
-#include <algorithm>
-#ifndef UNDER_CE
-#include <process.h>
-#endif
-#include <stdio.h>
 #include <boost/thread/once.hpp>
 #include <boost/thread/tss.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/detail/tss_hooks.hpp>
+
 #include <boost/assert.hpp>
 #include <boost/throw_exception.hpp>
-#include <boost/thread/detail/tss_hooks.hpp>
 #include <boost/date_time/posix_time/conversion.hpp>
-#include <windows.h>
+
 #include <memory>
+#include <algorithm>
+#ifndef UNDER_CE
+#include <process.h>
+#endif
+#include <stdio.h>
+#include <windows.h>
 
 namespace boost
 {
+ namespace detail
+ {
+ thread_data_base::~thread_data_base()
+ {
+ {
+ for (notify_list_t::iterator i = notify.begin(), e = notify.end();
+ i != e; ++i)
+ {
+ i->second->unlock();
+ i->first->notify_all();
+ }
+ }
+ }
+ }
     namespace
     {
 #ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
@@ -240,6 +257,9 @@
 
             void run()
             {}
+ void notify_all_at_thread_exit(condition_variable*, mutex*)
+ {}
+
         private:
             externally_launched_thread(externally_launched_thread&);
             void operator=(externally_launched_thread&);
@@ -303,6 +323,12 @@
             this_thread::interruptible_wait(local_thread_info->thread_handle,detail::timeout::sentinel());
             release_handle();
         }
+ else
+ {
+#ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
+ boost::throw_exception(thread_resource_error(system::errc::invalid_argument, "boost thread: thread not joinable"));
+#endif
+ }
     }
 
     bool thread::timed_join(boost::system_time const& wait_until)
@@ -324,11 +350,17 @@
               return false;
           }
           release_handle();
+ return true;
+ }
+ else
+ {
+#ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
+ boost::throw_exception(thread_resource_error(system::errc::invalid_argument, "boost thread: thread not joinable"));
+#endif
       }
- return true;
     }
 
- void thread::detach() BOOST_NOEXCEPT
+ void thread::detach()
     {
         release_handle();
     }
@@ -682,6 +714,14 @@
         boost::run_thread_exit_callbacks();
     }
 
+ BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk)
+ {
+ detail::thread_data_base* const current_thread_data(get_current_thread_data());
+ if(current_thread_data)
+ {
+ current_thread_data->notify_all_at_thread_exit(&cond, lk.release());
+ }
+ }
 }
 
 

Modified: trunk/libs/thread/src/win32/tss_dll.cpp
==============================================================================
--- trunk/libs/thread/src/win32/tss_dll.cpp (original)
+++ trunk/libs/thread/src/win32/tss_dll.cpp 2012-09-01 13:10:16 EDT (Sat, 01 Sep 2012)
@@ -5,6 +5,7 @@
 
 #include <boost/thread/detail/config.hpp>
 
+
 #if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_DLL)
 
     #include <boost/thread/detail/tss_hooks.hpp>

Modified: trunk/libs/thread/test/Jamfile.v2
==============================================================================
--- trunk/libs/thread/test/Jamfile.v2 (original)
+++ trunk/libs/thread/test/Jamfile.v2 2012-09-01 13:10:16 EDT (Sat, 01 Sep 2012)
@@ -225,6 +225,7 @@
           [ thread-run2 ./sync/conditions/condition_variable_any/wait_until_pass.cpp : condition_variable_any__wait_until_p ]
           [ thread-run2 ./sync/conditions/condition_variable_any/wait_until_pred_pass.cpp : condition_variable_any__wait_until_pred_p ]
           [ thread-run2 ./sync/conditions/cv_status/cv_status_pass.cpp : cv_status__cv_status_p ]
+ [ thread-run2 ./sync/conditions/notify_all_at_thread_exit_pass.cpp : notify_all_at_thread_exit_p ]
     ;
 
     explicit ts_async ;
@@ -469,6 +470,8 @@
           [ thread-run2 ./threads/thread/members/detach_pass.cpp : thread__detach_p ]
           [ thread-run2 ./threads/thread/members/get_id_pass.cpp : thread__get_id_p ]
           [ thread-run2 ./threads/thread/members/join_pass.cpp : thread__join_p ]
+ [ thread-run2 ./threads/thread/members/try_join_until_pass.cpp : thread__join_until_p ]
+ [ thread-run2 ./threads/thread/members/try_join_for_pass.cpp : thread__join_for_p ]
           [ thread-run2 ./threads/thread/members/joinable_pass.cpp : thread__joinable_p ]
           [ thread-run2 ./threads/thread/members/native_handle_pass.cpp : thread__native_handle_p ]
           [ thread-run2 ./threads/thread/members/swap_pass.cpp : thread__swap_p ]

Added: trunk/libs/thread/test/sync/conditions/notify_all_at_thread_exit_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/sync/conditions/notify_all_at_thread_exit_pass.cpp 2012-09-01 13:10:16 EDT (Sat, 01 Sep 2012)
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// 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)
+
+// <boost/thread/condition_variable.hpp>
+
+// void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
+
+#define BOOST_THREAD_USES_MOVE
+#define BOOST_THREAD_VESRION 3
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/chrono/chrono.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::condition_variable cv;
+boost::mutex mut;
+
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::high_resolution_clock Clock;
+
+void func()
+{
+ boost::unique_lock < boost::mutex > lk(mut);
+ boost::notify_all_at_thread_exit(cv, boost::move(lk));
+ boost::this_thread::sleep_for(ms(300));
+}
+
+int main()
+{
+ boost::unique_lock < boost::mutex > lk(mut);
+ boost::thread(func).detach();
+ Clock::time_point t0 = Clock::now();
+ cv.wait(lk);
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 > ms(250));
+ return boost::report_errors();
+}
+

Modified: trunk/libs/thread/test/threads/thread/assign/move_pass.cpp
==============================================================================
--- trunk/libs/thread/test/threads/thread/assign/move_pass.cpp (original)
+++ trunk/libs/thread/test/threads/thread/assign/move_pass.cpp 2012-09-01 13:10:16 EDT (Sat, 01 Sep 2012)
@@ -89,14 +89,14 @@
     t1.join();
     BOOST_TEST(G::op_run);
   }
-// BOOST_TEST(G::n_alive == 0);
-// {
-// boost::thread t0(G(), 5, 5.5);
-// boost::thread::id id = t0.get_id();
-// boost::thread t1;
-// t0 = boost::move(t1);
-// BOOST_TEST(false);
-// }
+ BOOST_TEST(G::n_alive == 0);
+ {
+ boost::thread t0(G(), 5, 5.5);
+ boost::thread::id id = t0.get_id();
+ boost::thread t1;
+ t0 = boost::move(t1);
+ BOOST_TEST(false);
+ }
   return boost::report_errors();
 }
 

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-09-01 13:10:16 EDT (Sat, 01 Sep 2012)
@@ -16,7 +16,6 @@
 // class thread
 
 // void join();
-
 #define BOOST_THREAD_VESRION 3
 #include <boost/thread/thread.hpp>
 #include <boost/thread/mutex.hpp>
@@ -53,7 +52,7 @@
   void operator()()
   {
     BOOST_TEST(alive_ == 1);
- BOOST_TEST(n_alive == 1);
+ //BOOST_TEST(n_alive == 1);
     op_run = true;
   }
 };
@@ -68,8 +67,6 @@
   try
   {
     boost::unique_lock<boost::mutex> lk(resource_deadlock_would_occur_mtx);
-
-
     resource_deadlock_would_occur_th->join();
     BOOST_TEST(false);
   }
@@ -83,28 +80,6 @@
   }
 }
 
-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()
 {
   {
@@ -115,10 +90,6 @@
   }
 
   {
- boost::thread t0( throws_thread_resource_error_tester );
- t0.join();
- }
- {
     boost::unique_lock<boost::mutex> lk(resource_deadlock_would_occur_mtx);
     boost::thread t0( resource_deadlock_would_occur_tester );
     resource_deadlock_would_occur_th = &t0;
@@ -130,35 +101,34 @@
     BOOST_TEST(!t0.joinable());
   }
 
-// {
-// boost::thread t0( (G()));
-// t0.detach();
-// try
-// {
-// t0.join();
-// BOOST_TEST(false);
-// }
-// catch (boost::system::system_error& e)
-// {
-// BOOST_TEST(e.code().value() == boost::system::errc::no_such_process);
-// }
-// }
-// {
-// boost::thread t0( (G()));
-// BOOST_TEST(t0.joinable());
-// t0.join();
-// BOOST_TEST(!t0.joinable());
-// try
-// {
-// t0.join();
-// BOOST_TEST(false);
-// }
-// catch (boost::system::system_error& e)
-// {
-// BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
-// }
-//
-// }
+ {
+ boost::thread t0( (G()));
+ t0.detach();
+ try
+ {
+ t0.join();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
+ }
+ }
+ {
+ boost::thread t0( (G()));
+ BOOST_TEST(t0.joinable());
+ t0.join();
+ try
+ {
+ t0.join();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
+ }
+
+ }
 
   return boost::report_errors();
 }

Added: trunk/libs/thread/test/threads/thread/members/try_join_for_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/threads/thread/members/try_join_for_pass.cpp 2012-09-01 13:10:16 EDT (Sat, 01 Sep 2012)
@@ -0,0 +1,161 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// 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)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// template <class Rep, class Period>
+// bool try_join_for(const chrono::duration<Rep, Period>& rel_time);
+
+#define BOOST_THREAD_VESRION 3
+#include <boost/thread/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+class G
+{
+ int alive_;
+public:
+ static bool op_run;
+
+ G() :
+ alive_(1)
+ {
+ }
+ G(const G& g) :
+ alive_(g.alive_)
+ {
+ }
+ ~G()
+ {
+ alive_ = 0;
+ }
+
+ void operator()()
+ {
+ BOOST_TEST(alive_ == 1);
+ op_run = true;
+ }
+};
+
+bool G::op_run = false;
+
+boost::thread* resource_deadlock_would_occur_th=0;
+boost::mutex resource_deadlock_would_occur_mtx;
+void resource_deadlock_would_occur_tester()
+{
+ try
+ {
+ boost::unique_lock<boost::mutex> lk(resource_deadlock_would_occur_mtx);
+ resource_deadlock_would_occur_th->try_join_for(boost::chrono::milliseconds(50));
+ 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");
+ }
+}
+
+void th_100_ms()
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
+}
+
+int main()
+{
+ {
+ boost::thread t0( (G()));
+ BOOST_TEST(t0.joinable());
+ BOOST_TEST(t0.try_join_for(boost::chrono::milliseconds(50)));
+ BOOST_TEST(!t0.joinable());
+ }
+ {
+ boost::thread t0( (th_100_ms));
+ BOOST_TEST(!t0.try_join_for(boost::chrono::milliseconds(50)));
+ t0.join();
+ }
+
+ {
+ boost::unique_lock<boost::mutex> lk(resource_deadlock_would_occur_mtx);
+ boost::thread t0( resource_deadlock_would_occur_tester );
+ resource_deadlock_would_occur_th = &t0;
+ BOOST_TEST(t0.joinable());
+ lk.unlock();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
+ boost::unique_lock<boost::mutex> lk2(resource_deadlock_would_occur_mtx);
+ t0.join();
+ BOOST_TEST(!t0.joinable());
+ }
+
+ {
+ boost::thread t0( (G()));
+ t0.detach();
+ try
+ {
+ t0.try_join_for(boost::chrono::milliseconds(50));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
+ }
+ }
+ {
+ boost::thread t0( (G()));
+ BOOST_TEST(t0.joinable());
+ t0.join();
+ try
+ {
+ t0.try_join_for(boost::chrono::milliseconds(50));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
+ }
+
+ }
+ {
+ boost::thread t0( (G()));
+ BOOST_TEST(t0.joinable());
+ t0.try_join_for(boost::chrono::milliseconds(50));
+ try
+ {
+ t0.join();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
+ }
+
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif

Added: trunk/libs/thread/test/threads/thread/members/try_join_until_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/threads/thread/members/try_join_until_pass.cpp 2012-09-01 13:10:16 EDT (Sat, 01 Sep 2012)
@@ -0,0 +1,162 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// 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)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// template <class Clock, class Duration>
+// bool try_join_until(const chrono::time_point<Clock, Duration>& t);
+
+#define BOOST_THREAD_VESRION 3
+#include <boost/thread/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+class G
+{
+ int alive_;
+public:
+ static bool op_run;
+
+ G() :
+ alive_(1)
+ {
+ }
+ G(const G& g) :
+ alive_(g.alive_)
+ {
+ }
+ ~G()
+ {
+ alive_ = 0;
+ }
+
+ void operator()()
+ {
+ BOOST_TEST(alive_ == 1);
+ op_run = true;
+ }
+};
+
+bool G::op_run = false;
+
+boost::thread* resource_deadlock_would_occur_th=0;
+boost::mutex resource_deadlock_would_occur_mtx;
+void resource_deadlock_would_occur_tester()
+{
+ try
+ {
+ boost::unique_lock<boost::mutex> lk(resource_deadlock_would_occur_mtx);
+ resource_deadlock_would_occur_th->try_join_until(boost::chrono::steady_clock::now()+boost::chrono::milliseconds(50));
+ 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");
+ }
+}
+
+void th_100_ms()
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
+}
+
+
+int main()
+{
+ {
+ boost::thread t0( (G()));
+ BOOST_TEST(t0.joinable());
+ t0.try_join_until(boost::chrono::steady_clock::now()+boost::chrono::milliseconds(50));
+ BOOST_TEST(!t0.joinable());
+ }
+ {
+ boost::thread t0( (th_100_ms));
+ BOOST_TEST(!t0.try_join_until(boost::chrono::steady_clock::now()+boost::chrono::milliseconds(50)));
+ t0.join();
+ }
+
+ {
+ boost::unique_lock<boost::mutex> lk(resource_deadlock_would_occur_mtx);
+ boost::thread t0( resource_deadlock_would_occur_tester );
+ resource_deadlock_would_occur_th = &t0;
+ BOOST_TEST(t0.joinable());
+ lk.unlock();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
+ boost::unique_lock<boost::mutex> lk2(resource_deadlock_would_occur_mtx);
+ t0.join();
+ BOOST_TEST(!t0.joinable());
+ }
+
+ {
+ boost::thread t0( (G()));
+ t0.detach();
+ try
+ {
+ t0.try_join_until(boost::chrono::steady_clock::now()+boost::chrono::milliseconds(50));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
+ }
+ }
+ {
+ boost::thread t0( (G()));
+ BOOST_TEST(t0.joinable());
+ t0.join();
+ try
+ {
+ t0.try_join_until(boost::chrono::steady_clock::now()+boost::chrono::milliseconds(50));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
+ }
+
+ }
+ {
+ boost::thread t0( (G()));
+ BOOST_TEST(t0.joinable());
+ t0.try_join_until(boost::chrono::steady_clock::now()+boost::chrono::milliseconds(50));
+ try
+ {
+ t0.join();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
+ }
+
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif


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