From 12a1c7c71c2a6a93f697cf616e56dc2db150943e Mon Sep 17 00:00:00 2001 From: "Vicente J. Botet Escriba" Date: Thu, 13 Sep 2012 18:57:04 +0000 Subject: [PATCH] Thread: merge from trunk [SVN r80516] --- doc/changes.qbk | 61 ++++++++++++------- doc/configuration.qbk | 12 +--- doc/overview.qbk | 21 +++++++ doc/tss.qbk | 2 +- include/boost/thread/detail/config.hpp | 9 +-- include/boost/thread/detail/memory.hpp | 3 +- include/boost/thread/pthread/once.hpp | 2 + .../thread/win32/basic_recursive_mutex.hpp | 6 +- .../boost/thread/win32/basic_timed_mutex.hpp | 2 +- .../boost/thread/win32/interlocked_read.hpp | 19 +++--- .../boost/thread/win32/thread_primitives.hpp | 4 +- .../futures/packaged_task/alloc_ctor_pass.cpp | 11 ++++ 12 files changed, 97 insertions(+), 55 deletions(-) diff --git a/doc/changes.qbk b/doc/changes.qbk index 65240e5b..8ce3abaf 100644 --- a/doc/changes.qbk +++ b/doc/changes.qbk @@ -10,35 +10,52 @@ [heading Version 3.1.0 - boost 1.52] +Deprecated Features: + +Deprecated features since boost 1.50 available only until boost 1.55: + +These deprecated features will be provided by default up to boost 1.52. If you don't want to include the deprecated features you could define BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0. Since 1.53 these features will not be included any more by default. Since this version, if you want to include the deprecated features yet you could define BOOST_THREAD_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0. These deprecated features will be only available until boost 1.55, that is you have yet 1 year to move to the new features. + +* Time related functions don't using the Boost.Chrono library, use the chrono overloads instead. + +Breaking changes when BOOST_THREAD_VERSION==3 (Default value since Boost 1.53): + +There are some new features which share the same interface but with different behavior. These breaking features are provided by default when BOOST_THREAD_VERSION is 3, but the user can however choose the version 2 behavior by defining the corresponding macro. As for the deprecated features, these broken features will be only available until boost 1.55. + +* [@http://svn.boost.org/trac/boost/ticket/6229 #6229] Rename the unique_future to future following the c++11. +* [@http://svn.boost.org/trac/boost/ticket/6266 #6266] Breaking change: thread destructor should call terminate if joinable. +* [@http://svn.boost.org/trac/boost/ticket/6269 #6269] Breaking change: thread move assignment should call terminate if joinable. + New Features: -* [@http://svn.boost.org/trac/boost/ticket/2361 #2361] thread_specific_ptr: document nature of the key, complexity and rationale -* [@http://svn.boost.org/trac/boost/ticket/4710 #4710] C++11 compliance: : Missing async() -* [@http://svn.boost.org/trac/boost/ticket/7283 #7283] C++11 compliance: Add notify_all_at_thread_exit -* [@http://svn.boost.org/trac/boost/ticket/7345 #7345] C++11 compliance: Add noexcept to recursive mutex try_lock +* [@http://svn.boost.org/trac/boost/ticket/2361 #2361] thread_specific_ptr: document nature of the key, complexity and rationale. +* [@http://svn.boost.org/trac/boost/ticket/4710 #4710] C++11 compliance: Missing async(). +* [@http://svn.boost.org/trac/boost/ticket/7283 #7283] C++11 compliance: Add notify_all_at_thread_exit. +* [@http://svn.boost.org/trac/boost/ticket/7345 #7345] C++11 compliance: Add noexcept to recursive mutex try_lock. Fixed Bugs: -* [@http://svn.boost.org/trac/boost/ticket/2797 #2797] Two problems with thread_specific_ptr -* [@http://svn.boost.org/trac/boost/ticket/5274 #5274] failed to compile future.hpp with stlport 5.1.5 under msvc8.1, because of undefined class -* [@http://svn.boost.org/trac/boost/ticket/5431 #5431] compile error in Windows CE 6.0(interlocked) -* [@http://svn.boost.org/trac/boost/ticket/5752 #5752] boost::call_once() is unreliable on some platforms -* [@http://svn.boost.org/trac/boost/ticket/5696 #5696] win32 detail::set_tss_data does nothing when tss_cleanup_function is NULL -* [@http://svn.boost.org/trac/boost/ticket/7045 #7045] Thread library does not automatically compile date_time -* [@http://svn.boost.org/trac/boost/ticket/7173 #7173] wrong function name interrupt_point() -* [@http://svn.boost.org/trac/boost/ticket/7200 #7200] Unable to build boost.thread modularized -* [@http://svn.boost.org/trac/boost/ticket/7220 #7220 7238 gcc 4.6.2 warns about inline+dllimport functions -* [@http://svn.boost.org/trac/boost/ticket/7238 #5274] this_thread::sleep_for() does not respond to interrupt() -* [@http://svn.boost.org/trac/boost/ticket/7245 #7245] Minor typos on documentation related to version 3 -* [@http://svn.boost.org/trac/boost/ticket/7272 #7272] win32/thread_primitives.hpp: (Unneccessary) Warning -* [@http://svn.boost.org/trac/boost/ticket/7284 #7284] Clarify that there is no access priority between lock and shared_lock on shared mutex -* [@http://svn.boost.org/trac/boost/ticket/7329 #7329] boost/thread/future.hpp does not compile on HPUX - +* [@http://svn.boost.org/trac/boost/ticket/2797 #2797] Two problems with thread_specific_ptr. +* [@http://svn.boost.org/trac/boost/ticket/5274 #5274] failed to compile future.hpp with stlport 5.1.5 under msvc8.1, because of undefined class. +* [@http://svn.boost.org/trac/boost/ticket/5431 #5431] compile error in Windows CE 6.0(interlocked). +* [@http://svn.boost.org/trac/boost/ticket/5752 #5752] boost::call_once() is unreliable on some platforms. +[/* [@http://svn.boost.org/trac/boost/ticket/5696 #5696] win32 detail::set_tss_data does nothing when tss_cleanup_function is NULL]. +* [@http://svn.boost.org/trac/boost/ticket/7045 #7045] Thread library does not automatically compile date_time. +* [@http://svn.boost.org/trac/boost/ticket/7173 #7173] wrong function name interrupt_point(). +* [@http://svn.boost.org/trac/boost/ticket/7200 #7200] Unable to build boost.thread modularized. +* [@http://svn.boost.org/trac/boost/ticket/7220 #7220] gcc 4.6.2 warns about inline+dllimport functions. +* [@http://svn.boost.org/trac/boost/ticket/7238 #7238] this_thread::sleep_for() does not respond to interrupt(). +* [@http://svn.boost.org/trac/boost/ticket/7245 #7245] Minor typos on documentation related to version 3. +* [@http://svn.boost.org/trac/boost/ticket/7272 #7272] win32/thread_primitives.hpp: (Unneccessary) Warning. +* [@http://svn.boost.org/trac/boost/ticket/7284 #7284] Clarify that there is no access priority between lock and shared_lock on shared mutex. +* [@http://svn.boost.org/trac/boost/ticket/7329 #7329] boost/thread/future.hpp does not compile on HPUX. +* [@http://svn.boost.org/trac/boost/ticket/7336 #7336] BOOST_THREAD_DONT_USE_SYSTEM doesn't work. +* [@http://svn.boost.org/trac/boost/ticket/7329 #7349] packaged_task holds reference to temporary. +* [@http://svn.boost.org/trac/boost/ticket/7350 #7350] allocator_destructor does not destroy object + [heading Version 3.0.1 - boost 1.51] -New Features: - -* [@http://svn.boost.org/trac/boost/ticket/2100 #2100] thread fails to compile with -fno-exceptions +Deprecated Features: Deprecated features since boost 1.50 available only until boost 1.55: diff --git a/doc/configuration.qbk b/doc/configuration.qbk index 60852cea..35d63724 100644 --- a/doc/configuration.qbk +++ b/doc/configuration.qbk @@ -8,20 +8,14 @@ [section:configuration Configuration] -[section:system Boost.System] - -Boost.Thread uses by default Boost.System to define the exceptions. For backward compatibility and also for compilers that don't work well with Boost.System the user can define `BOOST_THREAD_DONT_USE_SYSTEM `. - -`BOOST_THREAD_USES_SYSTEM` is defined when Boost.Thread uses Boost.Move. - -[endsect] [section:chrono Boost.Chrono] -Boost.Thread uses by default Boost.Chrono for the time related functions. For backward compatibility and also for compilers that don't work well with Boost.Chrono the user can define `BOOST_THREAD_DONT_USE_CHRONO`. If `BOOST_THREAD_DONT_USE_SYSTEM` is defined then `BOOST_THREAD_DONT_USE_CHRONO` is defined implicitly. +Boost.Thread uses by default Boost.Chrono for the time related functions. For backward compatibility and also for compilers that don't work well with Boost.Chrono the user can define `BOOST_THREAD_DONT_USE_CHRONO`. `BOOST_THREAD_USES_CHRONO` is defined when Boost.Thread uses Boost.Chrono. + [endsect] [section:move Boost.Move] @@ -29,7 +23,7 @@ Boost.Thread uses by default Boost.Chrono for the time related functions. For ba Boost.Thread uses by default an internal move semantic implementation. Since version 3.0.0 you can use the move emulation emulation provided by Boost.Move. When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_USES_MOVE ` if you want to use Boost.Move interface. -When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_USE_MOVE ` if you want to use boost::unique_future. +When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_USE_MOVE ` if you don't want to use Boost.Move interface. [endsect] diff --git a/doc/overview.qbk b/doc/overview.qbk index f98ded00..973b87bf 100644 --- a/doc/overview.qbk +++ b/doc/overview.qbk @@ -42,6 +42,27 @@ The definition of these macros determines whether BOOST_THREAD_USE_DLL is define The source code compiled when building the library defines a macros BOOST_THREAD_SOURCE that is used to import or export it. The user must not define this macro in any case. +Boost.Thread depends on some non header-only libraries. + +* Boost.System: This dependency is mandatory and you will need to link with the library. + +* Boost.Chrono: This dependency is optional (see below how to configure) and you will need to link with the library if you use some of the time related interfaces. + +* Boost.DateTime: This dependency is mandatory, but even if Boost.DateTime is a non header-only library Boost.Thread uses only parts that are header-only, so in principle you should not need to link with the library. + +It seems that there are some IDE (as e.g. Visual Studio) that deduce the libraries that a program needs to link to inspecting the sources. Such IDE could force to link to Boost.DateTime and/or Boost.Chrono. + +As the single mandatory dependency is to Boost.System, the following + + bjam toolset=msvc-11.0 --build-type=complete --with-thread + +will install only boost_thread and boost_system. + +Users of such IDE should force the Boost.Chrono and Boost.DateTime build using + + bjam toolset=msvc-11.0 --build-type=complete --with-thread --with-chrono --with-date_time + + The following section describes all the macros used to configure Boost.Thread. [include configuration.qbk] diff --git a/doc/tss.qbk b/doc/tss.qbk index c35f05ae..374a9199 100644 --- a/doc/tss.qbk +++ b/doc/tss.qbk @@ -47,7 +47,7 @@ platforms such cleanup is only done for threads that are started with `boost::thread` unless `boost::on_thread_exit()` is called manually from that thread. -[heading Rational about the nature of the key] +[heading Rationale about the nature of the key] Boost.Thread uses the address of the `thread_specific_ptr` instance as key of the thread specific pointers. This avoids to create/destroy a key which will need a lock to protect from race conditions. This has a little performance liability, as the access must be done using an associative container. diff --git a/include/boost/thread/detail/config.hpp b/include/boost/thread/detail/config.hpp index 5ec3e7c1..3cb769df 100644 --- a/include/boost/thread/detail/config.hpp +++ b/include/boost/thread/detail/config.hpp @@ -43,13 +43,8 @@ #endif #endif -// Uses Boost.System by default if not stated the opposite defining 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 && ! defined BOOST_THREAD_USES_CHRONO +// Uses Boost.Chrono by default if not stated the opposite defining BOOST_THREAD_DONT_USE_CHRONO +#if ! defined BOOST_THREAD_DONT_USE_CHRONO && ! defined BOOST_THREAD_USES_CHRONO #define BOOST_THREAD_USES_CHRONO #endif diff --git a/include/boost/thread/detail/memory.hpp b/include/boost/thread/detail/memory.hpp index e5fd5dc0..3c1692d0 100644 --- a/include/boost/thread/detail/memory.hpp +++ b/include/boost/thread/detail/memory.hpp @@ -33,7 +33,7 @@ namespace boost typedef typename alloc_traits::pointer pointer; typedef typename alloc_traits::size_type size_type; private: - _Alloc& alloc_; + _Alloc alloc_; size_type s_; public: allocator_destructor(_Alloc& a, size_type s)BOOST_NOEXCEPT @@ -41,6 +41,7 @@ namespace boost {} void operator()(pointer p)BOOST_NOEXCEPT { + alloc_traits::destroy(alloc_, p); alloc_traits::deallocate(alloc_, p, s_); } }; diff --git a/include/boost/thread/pthread/once.hpp b/include/boost/thread/pthread/once.hpp index 5c3d0238..4b177aa1 100644 --- a/include/boost/thread/pthread/once.hpp +++ b/include/boost/thread/pthread/once.hpp @@ -17,6 +17,8 @@ #include #include #include +// Force SIG_ATOMIC_MAX tobe defined +#define __STDC_LIMIT_MACROS #include #include diff --git a/include/boost/thread/win32/basic_recursive_mutex.hpp b/include/boost/thread/win32/basic_recursive_mutex.hpp index 890931b6..e259121a 100644 --- a/include/boost/thread/win32/basic_recursive_mutex.hpp +++ b/include/boost/thread/win32/basic_recursive_mutex.hpp @@ -42,7 +42,7 @@ namespace boost mutex.destroy(); } - bool try_lock() // BOOST_NOEXCEPT + bool try_lock() BOOST_NOEXCEPT { long const current_thread_id=win32::GetCurrentThreadId(); return try_recursive_lock(current_thread_id) || try_basic_lock(current_thread_id); @@ -93,7 +93,7 @@ namespace boost } private: - bool try_recursive_lock(long current_thread_id) // BOOST_NOEXCEPT + bool try_recursive_lock(long current_thread_id) BOOST_NOEXCEPT { if(::boost::detail::interlocked_read_acquire(&locking_thread_id)==current_thread_id) { @@ -103,7 +103,7 @@ namespace boost return false; } - bool try_basic_lock(long current_thread_id) // BOOST_NOEXCEPT + bool try_basic_lock(long current_thread_id) BOOST_NOEXCEPT { if(mutex.try_lock()) { diff --git a/include/boost/thread/win32/basic_timed_mutex.hpp b/include/boost/thread/win32/basic_timed_mutex.hpp index 30580e7c..6a430774 100644 --- a/include/boost/thread/win32/basic_timed_mutex.hpp +++ b/include/boost/thread/win32/basic_timed_mutex.hpp @@ -58,7 +58,7 @@ namespace boost } - bool try_lock() + bool try_lock() BOOST_NOEXCEPT { return !win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit); } diff --git a/include/boost/thread/win32/interlocked_read.hpp b/include/boost/thread/win32/interlocked_read.hpp index 96a47dcb..4a969985 100644 --- a/include/boost/thread/win32/interlocked_read.hpp +++ b/include/boost/thread/win32/interlocked_read.hpp @@ -4,13 +4,14 @@ // interlocked_read_win32.hpp // // (C) Copyright 2005-8 Anthony Williams +// (C) Copyright 2012 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) #include -//#include +#include #include @@ -23,25 +24,25 @@ namespace boost { namespace detail { - inline long interlocked_read_acquire(long volatile* x) //BOOST_NOEXCEPT + inline long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT { long const res=*x; _ReadWriteBarrier(); return res; } - inline void* interlocked_read_acquire(void* volatile* x) //BOOST_NOEXCEPT + inline void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT { void* const res=*x; _ReadWriteBarrier(); return res; } - inline void interlocked_write_release(long volatile* x,long value) //BOOST_NOEXCEPT + inline void interlocked_write_release(long volatile* x,long value) BOOST_NOEXCEPT { _ReadWriteBarrier(); *x=value; } - inline void interlocked_write_release(void* volatile* x,void* value) //BOOST_NOEXCEPT + inline void interlocked_write_release(void* volatile* x,void* value) BOOST_NOEXCEPT { _ReadWriteBarrier(); *x=value; @@ -55,19 +56,19 @@ namespace boost { namespace detail { - inline long interlocked_read_acquire(long volatile* x) //BOOST_NOEXCEPT + inline long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT { return BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,0,0); } - inline void* interlocked_read_acquire(void* volatile* x) //BOOST_NOEXCEPT + inline void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT { return BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(x,0,0); } - inline void interlocked_write_release(long volatile* x,long value) //BOOST_NOEXCEPT + inline void interlocked_write_release(long volatile* x,long value) BOOST_NOEXCEPT { BOOST_INTERLOCKED_EXCHANGE(x,value); } - inline void interlocked_write_release(void* volatile* x,void* value) //BOOST_NOEXCEPT + inline void interlocked_write_release(void* volatile* x,void* value) BOOST_NOEXCEPT { BOOST_INTERLOCKED_EXCHANGE_POINTER(x,value); } diff --git a/include/boost/thread/win32/thread_primitives.hpp b/include/boost/thread/win32/thread_primitives.hpp index a68548e8..0f5dc08d 100644 --- a/include/boost/thread/win32/thread_primitives.hpp +++ b/include/boost/thread/win32/thread_primitives.hpp @@ -299,7 +299,7 @@ namespace boost } } -#if defined(BOOST_MSVC) && (_MSC_VER>=1400) && !defined(UNDER_CE) +#if (defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)) && (_MSC_VER>=1400) && !defined(UNDER_CE) namespace boost { @@ -332,7 +332,7 @@ namespace boost } } #define BOOST_THREAD_BTS_DEFINED -#elif (defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)) && defined(_M_IX86) +#elif defined(BOOST_MSVC) && defined(_M_IX86) namespace boost { namespace detail diff --git a/test/sync/futures/packaged_task/alloc_ctor_pass.cpp b/test/sync/futures/packaged_task/alloc_ctor_pass.cpp index a1f82655..993c159c 100644 --- a/test/sync/futures/packaged_task/alloc_ctor_pass.cpp +++ b/test/sync/futures/packaged_task/alloc_ctor_pass.cpp @@ -44,20 +44,27 @@ public: BOOST_THREAD_COPYABLE_AND_MOVABLE(A) static int n_moves; static int n_copies; + static int n_instances; + static int n_destroy; explicit A(long i) : data_(i) { + ++n_instances; } A(BOOST_THREAD_RV_REF(A) a) : data_(BOOST_THREAD_RV(a).data_) { + ++n_instances; ++n_moves; BOOST_THREAD_RV(a).data_ = -1; } A(const A& a) : data_(a.data_) { + ++n_instances; ++n_copies; } ~A() { + --n_instances; + ++n_destroy; } long operator()() const @@ -68,6 +75,8 @@ public: int A::n_moves = 0; int A::n_copies = 0; +int A::n_instances = 0; +int A::n_destroy = 0; int main() { @@ -83,6 +92,8 @@ int main() } BOOST_TEST(A::n_copies == 0); BOOST_TEST(A::n_moves > 0); + BOOST_TEST(A::n_instances == 0); + BOOST_TEST(A::n_destroy > 0); BOOST_TEST(test_alloc_base::count == 0); A::n_copies = 0; A::n_copies = 0;