2
0
mirror of https://github.com/boostorg/thread.git synced 2026-02-07 23:02:13 +00:00

Compare commits

...

7 Commits

Author SHA1 Message Date
Marshall Clow
0b71353f28 Release 1.51.0
[SVN r80098]
2012-08-20 22:07:05 +00:00
Vicente J. Botet Escriba
c4420d7591 Thread: merge fix for #6174
[SVN r80040]
2012-08-15 09:54:21 +00:00
Andrey Semashev
6ef2dade3a Merged changes from trunk.
[SVN r79794]
2012-07-29 08:44:22 +00:00
Vicente J. Botet Escriba
c594f5d9ae Thread: update changes
[SVN r79408]
2012-07-10 20:58:07 +00:00
Vicente J. Botet Escriba
a73cf83971 Thread: Merge from trunk
[SVN r79397]
2012-07-09 22:13:44 +00:00
Vicente J. Botet Escriba
67a5a6f39e Thread: merge from trunk
[SVN r79373]
2012-07-09 05:55:01 +00:00
Vicente J. Botet Escriba
348bd080ef Thread: remove unused file: shared_mutex.cpp 7044
[SVN r79238]
2012-07-03 06:20:41 +00:00
30 changed files with 331 additions and 479 deletions

View File

@@ -40,6 +40,8 @@ import path ;
project boost/thread
: source-location ../src
: requirements <threading>multi
#<link>static:<define>BOOST_THREAD_STATIC_LINK=1
#<link>shared:<define>BOOST_THREAD_DYN_LINK=1
<link>static:<define>BOOST_THREAD_BUILD_LIB=1
<link>shared:<define>BOOST_THREAD_BUILD_DLL=1
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
@@ -85,13 +87,15 @@ project boost/thread
#<toolset>clang-2.8:<cxxflags>-Wno-unused-function
#<toolset>clang-2.9:<cxxflags>-Wno-delete-non-virtual-dtor
#<toolset>clang-2.9:<cxxflags>-Wno-unused-function
<toolset>clang-3.0:<cxxflags>-Wno-delete-non-virtual-dtor
<toolset>clang-3.0:<cxxflags>-Wno-delete-non-virtual-dtor
#<toolset>clang-3.0:<cxxflags>-Wno-unused-function
#<toolset>clang-3.0:<cxxflags>-Wno-unused-variable
# : default-build <threading>multi
: usage-requirements # pass these requirement to dependents (i.e. users)
#<link>static:<define>BOOST_THREAD_STATIC_LINK=1
#<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_SYSTEM_NO_DEPRECATED
@@ -207,7 +211,7 @@ rule usage-requirements ( properties * )
if ! <toolset>vacpp in $(properties) || <toolset-vacpp:version>11.1 in $(properties)
{
result += <library>/boost/chrono//boost_chrono ;
}
}
return $(result) ;
}
@@ -235,7 +239,7 @@ rule requirements ( properties * )
if ! <toolset>vacpp in $(properties) || <toolset-vacpp:version>11.1 in $(properties)
{
result += <library>/boost/chrono//boost_chrono ;
}
}
return $(result) ;
}

View File

@@ -8,8 +8,45 @@
[section:changes History]
[heading Version 3.0.1 - boost 1.51]
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 1 year and a half 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:
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.
Fixed Bugs:
* [@http://svn.boost.org/trac/boost/ticket/4258 #4258] Linking with boost thread does not work on mingw/gcc 4.5.
* [@http://svn.boost.org/trac/boost/ticket/4885 #4885] Access violation in set_tss_data at process exit due to invalid assumption about TlsAlloc.
* [@http://svn.boost.org/trac/boost/ticket/6931 #6931] mutex waits forwever with Intel Compiler and /debug:parallel
* [@http://svn.boost.org/trac/boost/ticket/7044 #7044] boost 1.50.0 header missing.
* [@http://svn.boost.org/trac/boost/ticket/7052 #7052] Thread: BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 only masks thread::operator==, thread::operator!= forward declarations, not definitions.
* [@http://svn.boost.org/trac/boost/ticket/7066 #7066] An attempt to fix current_thread_tls_key static initialization order.
* [@http://svn.boost.org/trac/boost/ticket/7074 #7074] Multiply defined symbol boost::allocator_arg.
* [@http://svn.boost.org/trac/boost/ticket/7078 #7078] Trivial 64-bit warning fix on Windows for thread attribute stack size
* [@http://svn.boost.org/trac/boost/ticket/7089 #7089] BOOST_THREAD_WAIT_BUG limits functionality without solving anything
[heading Version 3.0.0 - boost 1.50]
Breaking changes when BOOST_THREAD_VERSION==3:
* [@http://svn.boost.org/trac/boost/ticket/6229 #6229] Breaking change: 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/1850 #1850] Request for unlock_guard to compliment lock_guard.
@@ -23,11 +60,8 @@ New Features:
* [@http://svn.boost.org/trac/boost/ticket/6225 #6225] Add the use of standard =delete defaulted operations on compilers supporting them.
* [@http://svn.boost.org/trac/boost/ticket/6226 #6226] c++11 compliance: Add explicit bool conversion from locks.
* [@http://svn.boost.org/trac/boost/ticket/6228 #6228] Add promise constructor with allocator following the standard c++11.
* [@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/6230 #6230] c++11 compliance: Follows the exception reporting mechanism as defined in the c++11.
* [@http://svn.boost.org/trac/boost/ticket/6231 #6231] Add BasicLockable requirements in the documentation to follow 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.
* [@http://svn.boost.org/trac/boost/ticket/6272 #6272] c++11 compliance: Add thread::id hash specialization.
* [@http://svn.boost.org/trac/boost/ticket/6273 #6273] c++11 compliance: Add cv_status enum class and use it on the conditions wait functions.
* [@http://svn.boost.org/trac/boost/ticket/6342 #6342] c++11 compliance: Adapt the one_flag to the c++11 interface.
@@ -64,20 +98,7 @@ Fixed Bugs:
* [@http://svn.boost.org/trac/boost/ticket/6959 #6959] call of abs is ambiguous.
* Fix issue signaled on the ML with task_object(task_object const&) in presence of task_object(task_object &&)
[/
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 1 year and a half to move to the new features.
* Time related functions don't using the Boost.Chrono library, use the chrono overloads instead.
Breaking changes:
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 2, but the user can however choose the version 1 behavior by defining the corresponding macro. As for the deprecated features, these broken features will be only available until boost 1.55.
* #6266 c++11 compliance: thread destructor should call terminate if joinable
* #6269 c++11 compliance: thread move assignment should call terminate if joinable
]
[heading Version 2.1.1 - boost 1.49]

View File

@@ -5,12 +5,12 @@
http://www.boost.org/LICENSE_1_0.txt).
]
[section:compliance Conformace and Extension]
[section:compliance Conformance and Extension]
[section:cpp11 C++11 standard Thread library]
[table C++11 standard Conformace
[table C++11 standard Conformance
[[Section] [Description] [Status] [Comments] [Ticket]]
[[30] [Thread support library] [Partial] [-] [-]]
[[30.1] [General] [-] [-] [-]]
@@ -89,7 +89,7 @@
[section:shared Shared Locking extensions]
[table Howard's Shared Locking Proposal Conformace
[table Howard's Shared Locking Proposal Conformance
[[Section] [Description] [Status] [Comments]]
[[X] [Shared Locking] [Yes] [Needs `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION]]
[[X.1] [Shared Lockables Concepts] [Yes] [ - ]]

View File

@@ -167,12 +167,12 @@ These deprecated features will be provided by default up to boost 1.52. If you d
[section:version Version]
`BOOST_THREAD_VERSION` defines the Boost.Thread version.
The default version is 1. In this case the following breaking or extending macros are defined if the opposite is not requested:
The default version is 2. In this case the following breaking or extending macros are defined if the opposite is not requested:
* `BOOST_THREAD_PROVIDES_PROMISE_LAZY`
* `BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0`
The user can request the version 2 by defining `BOOST_THREAD_VERSION` to 2. In this case the following breaking or extending macros are defined if the opposite is not requested:
The user can request the version 3 by defining `BOOST_THREAD_VERSION` to 3. In this case the following breaking or extending macros are defined if the opposite is not requested:
* Breaking change `BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION `
* Breaking change `BOOST_THREAD_PROVIDES_FUTURE`
@@ -186,6 +186,8 @@ The user can request the version 2 by defining `BOOST_THREAD_VERSION` to 2. In t
* Breaking change `BOOST_THREAD_DONT_PROVIDE_PROMISE_LAZY`
* Breaking change `BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0`
The default value for `BOOST_THREAD_VERSION` will be changed to 3 since Boost 1.53.
[endsect]
[endsect]

View File

@@ -8,7 +8,7 @@
[library Thread
[quickbook 1.5]
[version 3.0.0]
[version 3.0.1]
[authors [Williams, Anthony] [Botet Escriba, Vicente J.]]
[copyright 2007-11 Anthony Williams]
[copyright 2011-12 Vicente J. Botet Escriba]

View File

@@ -11,6 +11,7 @@
#include <boost/thread/mutex.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/thread.hpp>
#include <vector>
#if defined BOOST_THREAD_USES_CHRONO
#include <boost/chrono/chrono_io.hpp>

View File

@@ -41,7 +41,7 @@ namespace boost
} //namespace thread_detail
typedef container::allocator_arg_t allocator_arg_t;
BOOST_CONSTEXPR allocator_arg_t allocator_arg = {};
BOOST_CONSTEXPR_OR_CONST allocator_arg_t allocator_arg = {};
template <class T, class Alloc>
struct uses_allocator: public container::uses_allocator<T, Alloc>

View File

@@ -19,7 +19,7 @@
// choose platform
#if defined(linux) || defined(__linux) || defined(__linux__)
# define BOOST_THREAD_LINUX
# define BOOST_THREAD_WAIT_BUG boost::posix_time::microseconds(100000)
//# define BOOST_THREAD_WAIT_BUG boost::posix_time::microseconds(100000)
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
# define BOOST_THREAD_BSD
#elif defined(sun) || defined(__sun)
@@ -36,7 +36,7 @@
# define BOOST_THREAD_BEOS
#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
# define BOOST_THREAD_MACOS
# define BOOST_THREAD_WAIT_BUG boost::posix_time::microseconds(1000)
//# define BOOST_THREAD_WAIT_BUG boost::posix_time::microseconds(1000)
#elif defined(__IBMCPP__) || defined(_AIX)
# define BOOST_THREAD_AIX
#elif defined(__amigaos__)

View File

@@ -582,6 +582,7 @@ namespace boost
}
#endif
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
inline bool thread::operator==(const thread& other) const
{
return get_id()==other.get_id();
@@ -591,6 +592,7 @@ namespace boost
{
return get_id()!=other.get_id();
}
#endif
namespace detail
{

View File

@@ -9,6 +9,12 @@
#define BOOST_THREAD_FUTURE_HPP
#include <boost/thread/detail/config.hpp>
// boost::thread::future requires exception handling
// due to boost::exception::exception_ptr dependency
#ifndef BOOST_NO_EXCEPTIONS
#include <boost/detail/scoped_enum_emulation.hpp>
#include <stdexcept>
#include <boost/thread/detail/move.hpp>
@@ -43,12 +49,16 @@
#include <boost/thread/detail/memory.hpp>
#endif
#include <boost/utility/result_of.hpp>
//#include <boost/thread.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_FUTURE future
#else
#define BOOST_THREAD_FUTURE unique_future
#endif
namespace boost
{
@@ -474,7 +484,7 @@ namespace boost
void mark_finished_with_result(rvalue_source_type result_)
{
boost::lock_guard<boost::mutex> lock(mutex);
mark_finished_with_result_internal(result_);
mark_finished_with_result_internal(static_cast<rvalue_source_type>(result_));
}
move_dest_type get()
@@ -1655,8 +1665,39 @@ namespace boost
BOOST_THREAD_DCL_MOVABLE_BEG(T) packaged_task<T> BOOST_THREAD_DCL_MOVABLE_END
// template <class F>
// BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
// async(launch policy, F f)
// {
// typedef typename boost::result_of<F()>::type R;
// typedef BOOST_THREAD_FUTURE<R> future;
// if (int(policy) & int(launch::async))
// {
// packaged_task<R> pt( f );
//
// BOOST_THREAD_FUTURE ret = pt.get_future();
// boost::thread( boost::move(pt) ).detach();
// return ::boost::move(ret);
// }
// else if (int(policy) & int(launch::deferred))
// {
// packaged_task<R> pt( f );
//
// BOOST_THREAD_FUTURE ret = pt.get_future();
// return ::boost::move(ret);
// }
// }
//
// template <class F>
// BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
// async(F f)
// {
// return async(launch::any, f);
// }
}
#endif
#endif // BOOST_NO_EXCEPTION
#endif // header

View File

@@ -78,18 +78,18 @@ namespace boost
{
flag.epoch=being_initialized;
#ifndef BOOST_NO_EXCEPTIONS
try
try // BOOST_NO_EXCEPTIONS protected
{
#endif
pthread::pthread_mutex_scoped_unlock relocker(&detail::once_epoch_mutex);
f();
#ifndef BOOST_NO_EXCEPTIONS
}
catch(...)
catch(...) // BOOST_NO_EXCEPTIONS protected
{
flag.epoch=uninitialized_flag;
BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
flag.epoch=--detail::once_global_epoch;

View File

@@ -129,11 +129,13 @@ namespace boost
void check_for_interruption()
{
#ifndef BOOST_NO_EXCEPTIONS
if(thread_info->interrupt_requested)
{
thread_info->interrupt_requested=false;
throw thread_interrupted();
throw thread_interrupted(); // BOOST_NO_EXCEPTIONS protected
}
#endif
}
void operator=(interruption_checker&);

View File

@@ -159,6 +159,7 @@ namespace boost
return timed_lock(system_time(timeout));
}
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
{
@@ -209,6 +210,7 @@ namespace boost
}
return true;
}
#endif
void unlock()
{

View File

@@ -81,9 +81,9 @@ namespace boost
return notified;
}
bool wait(timeout wait_until)
bool wait(timeout abs_time)
{
return this_thread::interruptible_wait(semaphore,wait_until);
return this_thread::interruptible_wait(semaphore,abs_time);
}
bool woken()
@@ -203,7 +203,7 @@ namespace boost
protected:
template<typename lock_type>
bool do_wait(lock_type& lock,timeout wait_until)
bool do_wait(lock_type& lock,timeout abs_time)
{
relocker<lock_type> locker(lock);
@@ -214,7 +214,7 @@ namespace boost
bool woken=false;
while(!woken)
{
if(!entry->wait(wait_until))
if(!entry->wait(abs_time))
{
return false;
}
@@ -225,11 +225,11 @@ namespace boost
}
template<typename lock_type,typename predicate_type>
bool do_wait(lock_type& m,timeout const& wait_until,predicate_type pred)
bool do_wait(lock_type& m,timeout const& abs_time,predicate_type pred)
{
while (!pred())
{
if(!do_wait(m, wait_until))
if(!do_wait(m, abs_time))
return pred();
}
return true;
@@ -314,14 +314,14 @@ namespace boost
}
bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until)
bool timed_wait(unique_lock<mutex>& m,boost::system_time const& abs_time)
{
return do_wait(m,wait_until);
return do_wait(m,abs_time);
}
bool timed_wait(unique_lock<mutex>& m,boost::xtime const& wait_until)
bool timed_wait(unique_lock<mutex>& m,boost::xtime const& abs_time)
{
return do_wait(m,system_time(wait_until));
return do_wait(m,system_time(abs_time));
}
template<typename duration_type>
bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration)
@@ -330,14 +330,14 @@ namespace boost
}
template<typename predicate_type>
bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until,predicate_type pred)
bool timed_wait(unique_lock<mutex>& m,boost::system_time const& abs_time,predicate_type pred)
{
return do_wait(m,wait_until,pred);
return do_wait(m,abs_time,pred);
}
template<typename predicate_type>
bool timed_wait(unique_lock<mutex>& m,boost::xtime const& wait_until,predicate_type pred)
bool timed_wait(unique_lock<mutex>& m,boost::xtime const& abs_time,predicate_type pred)
{
return do_wait(m,system_time(wait_until),pred);
return do_wait(m,system_time(abs_time),pred);
}
template<typename duration_type,typename predicate_type>
bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration,predicate_type pred)
@@ -422,15 +422,15 @@ namespace boost
}
template<typename lock_type>
bool timed_wait(lock_type& m,boost::system_time const& wait_until)
bool timed_wait(lock_type& m,boost::system_time const& abs_time)
{
return do_wait(m,wait_until);
return do_wait(m,abs_time);
}
template<typename lock_type>
bool timed_wait(lock_type& m,boost::xtime const& wait_until)
bool timed_wait(lock_type& m,boost::xtime const& abs_time)
{
return do_wait(m,system_time(wait_until));
return do_wait(m,system_time(abs_time));
}
template<typename lock_type,typename duration_type>
@@ -440,15 +440,15 @@ namespace boost
}
template<typename lock_type,typename predicate_type>
bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred)
bool timed_wait(lock_type& m,boost::system_time const& abs_time,predicate_type pred)
{
return do_wait(m,wait_until,pred);
return do_wait(m,abs_time,pred);
}
template<typename lock_type,typename predicate_type>
bool timed_wait(lock_type& m,boost::xtime const& wait_until,predicate_type pred)
bool timed_wait(lock_type& m,boost::xtime const& abs_time,predicate_type pred)
{
return do_wait(m,system_time(wait_until),pred);
return do_wait(m,system_time(abs_time),pred);
}
template<typename lock_type,typename duration_type,typename predicate_type>

View File

@@ -157,7 +157,9 @@ namespace boost
status=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&flag.status,running_value,0);
if(!status)
{
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
if(!event_handle)
{
@@ -185,7 +187,8 @@ namespace boost
}
break;
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
BOOST_INTERLOCKED_EXCHANGE(&flag.status,0);
if(!event_handle)
@@ -196,8 +199,9 @@ namespace boost
{
::boost::detail::win32::SetEvent(event_handle);
}
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}
if(!counted)

View File

@@ -221,6 +221,7 @@ namespace boost
}
}
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
{
@@ -327,6 +328,7 @@ namespace boost
BOOST_ASSERT(res==0);
}
}
#endif
void unlock_shared()
{
@@ -490,7 +492,7 @@ namespace boost
}
}
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
{
@@ -598,6 +600,7 @@ namespace boost
BOOST_ASSERT(wait_res<2);
}
}
#endif
void unlock()
{

View File

@@ -75,16 +75,20 @@ namespace boost
inline T* heap_new()
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
T* const data=new (heap_memory) T();
return data;
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}
#ifndef BOOST_NO_RVALUE_REFERENCES
@@ -92,127 +96,159 @@ namespace boost
inline T* heap_new(A1&& a1)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
T* const data=new (heap_memory) T(static_cast<A1&&>(a1));
return data;
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}
template<typename T,typename A1,typename A2>
inline T* heap_new(A1&& a1,A2&& a2)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2));
return data;
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}
template<typename T,typename A1,typename A2,typename A3>
inline T* heap_new(A1&& a1,A2&& a2,A3&& a3)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
static_cast<A3&&>(a3));
return data;
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}
template<typename T,typename A1,typename A2,typename A3,typename A4>
inline T* heap_new(A1&& a1,A2&& a2,A3&& a3,A4&& a4)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
static_cast<A3&&>(a3),static_cast<A4&&>(a4));
return data;
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}
#else
template<typename T,typename A1>
inline T* heap_new_impl(A1 a1)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
T* const data=new (heap_memory) T(a1);
return data;
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}
template<typename T,typename A1,typename A2>
inline T* heap_new_impl(A1 a1,A2 a2)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
T* const data=new (heap_memory) T(a1,a2);
return data;
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}
template<typename T,typename A1,typename A2,typename A3>
inline T* heap_new_impl(A1 a1,A2 a2,A3 a3)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
T* const data=new (heap_memory) T(a1,a2,a3);
return data;
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}
template<typename T,typename A1,typename A2,typename A3,typename A4>
inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
T* const data=new (heap_memory) T(a1,a2,a3,a4);
return data;
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}

View File

@@ -341,22 +341,42 @@ namespace boost
{
inline bool interlocked_bit_test_and_set(long* x,long bit)
{
#if 0
__asm {
mov eax,bit;
mov edx,x;
lock bts [edx],eax;
setc al;
};
#else
bool ret;
__asm {
mov eax,bit; mov edx,x; lock bts [edx],eax; setc al; mov ret, al
};
return ret;
#endif
}
inline bool interlocked_bit_test_and_reset(long* x,long bit)
{
#if 0
__asm {
mov eax,bit;
mov edx,x;
lock btr [edx],eax;
setc al;
};
#else
bool ret;
__asm {
mov eax,bit; mov edx,x; lock btr [edx],eax; setc al; mov ret, al
};
return ret;
#endif
}
}

View File

@@ -3,6 +3,10 @@
// 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/detail/config.hpp>
#ifndef BOOST_NO_EXCEPTIONS
#include <boost/thread/future.hpp>
namespace boost
@@ -54,3 +58,4 @@ namespace boost
}
}
#endif

View File

@@ -138,16 +138,20 @@ namespace boost
boost::detail::thread_data_ptr thread_info = static_cast<boost::detail::thread_data_base*>(param)->self;
thread_info->self.reset();
detail::set_current_thread_data(thread_info.get());
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
thread_info->run();
}
catch(thread_interrupted const&)
#ifndef BOOST_NO_EXCEPTIONS
catch(thread_interrupted const&) // BOOST_NO_EXCEPTIONS protected
{
}
#endif
// Removed as it stops the debugger identifying the cause of the exception
// Unhandled exceptions still cause the application to terminate
// catch(...)
// catch(...) // BOOST_NO_EXCEPTIONS protected
// {
// std::terminate();
// }
@@ -221,14 +225,14 @@ namespace boost
if (res != 0)
{
thread_info->self.reset();
throw thread_resource_error();
boost::throw_exception(thread_resource_error());
}
int detached_state;
res = pthread_attr_getdetachstate(h, &detached_state);
if (res != 0)
{
thread_info->self.reset();
throw thread_resource_error();
boost::throw_exception(thread_resource_error());
}
if (PTHREAD_CREATE_DETACHED==detached_state)
{
@@ -558,6 +562,7 @@ namespace boost
void interruption_point()
{
#ifndef BOOST_NO_EXCEPTIONS
boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data();
if(thread_info && thread_info->interrupt_enabled)
{
@@ -568,6 +573,7 @@ namespace boost
throw thread_interrupted();
}
}
#endif
}
bool interruption_enabled() BOOST_NOEXCEPT

View File

@@ -1,328 +0,0 @@
// Copyright Howard Hinnant 2007-2010.
// Copyright Vicente J. Botet Escriba 2012.
// Use, modification and distribution are subject to 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/v2/shared_mutex.hpp>
#include <boost/thread/locks.hpp>
namespace boost
{
namespace thread_v2
{
// shared_mutex
shared_mutex::shared_mutex()
: state_(0)
{
}
shared_mutex::~shared_mutex()
{
boost::lock_guard<mutex_t> _(mut_);
}
// Exclusive ownership
void
shared_mutex::lock()
{
boost::unique_lock<mutex_t> lk(mut_);
while (state_ & write_entered_)
gate1_.wait(lk);
state_ |= write_entered_;
while (state_ & n_readers_)
gate2_.wait(lk);
}
bool
shared_mutex::try_lock()
{
boost::unique_lock<mutex_t> lk(mut_);
if (state_ == 0)
{
state_ = write_entered_;
return true;
}
return false;
}
void
shared_mutex::unlock()
{
boost::lock_guard<mutex_t> _(mut_);
state_ = 0;
gate1_.notify_all();
}
// Shared ownership
void
shared_mutex::lock_shared()
{
boost::unique_lock<mutex_t> lk(mut_);
while ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
gate1_.wait(lk);
count_t num_readers = (state_ & n_readers_) + 1;
state_ &= ~n_readers_;
state_ |= num_readers;
}
bool
shared_mutex::try_lock_shared()
{
boost::unique_lock<mutex_t> lk(mut_);
count_t num_readers = state_ & n_readers_;
if (!(state_ & write_entered_) && num_readers != n_readers_)
{
++num_readers;
state_ &= ~n_readers_;
state_ |= num_readers;
return true;
}
return false;
}
void
shared_mutex::unlock_shared()
{
boost::lock_guard<mutex_t> _(mut_);
count_t num_readers = (state_ & n_readers_) - 1;
state_ &= ~n_readers_;
state_ |= num_readers;
if (state_ & write_entered_)
{
if (num_readers == 0)
gate2_.notify_one();
}
else
{
if (num_readers == n_readers_ - 1)
gate1_.notify_one();
}
}
// upgrade_mutex
upgrade_mutex::upgrade_mutex()
: gate1_(),
gate2_(),
state_(0)
{
}
upgrade_mutex::~upgrade_mutex()
{
boost::lock_guard<mutex_t> _(mut_);
}
// Exclusive ownership
void
upgrade_mutex::lock()
{
boost::unique_lock<mutex_t> lk(mut_);
while (state_ & (write_entered_ | upgradable_entered_))
gate1_.wait(lk);
state_ |= write_entered_;
while (state_ & n_readers_)
gate2_.wait(lk);
}
bool
upgrade_mutex::try_lock()
{
boost::unique_lock<mutex_t> lk(mut_);
if (state_ == 0)
{
state_ = write_entered_;
return true;
}
return false;
}
void
upgrade_mutex::unlock()
{
boost::lock_guard<mutex_t> _(mut_);
state_ = 0;
gate1_.notify_all();
}
// Shared ownership
void
upgrade_mutex::lock_shared()
{
boost::unique_lock<mutex_t> lk(mut_);
while ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
gate1_.wait(lk);
count_t num_readers = (state_ & n_readers_) + 1;
state_ &= ~n_readers_;
state_ |= num_readers;
}
bool
upgrade_mutex::try_lock_shared()
{
boost::unique_lock<mutex_t> lk(mut_);
count_t num_readers = state_ & n_readers_;
if (!(state_ & write_entered_) && num_readers != n_readers_)
{
++num_readers;
state_ &= ~n_readers_;
state_ |= num_readers;
return true;
}
return false;
}
void
upgrade_mutex::unlock_shared()
{
boost::lock_guard<mutex_t> _(mut_);
count_t num_readers = (state_ & n_readers_) - 1;
state_ &= ~n_readers_;
state_ |= num_readers;
if (state_ & write_entered_)
{
if (num_readers == 0)
gate2_.notify_one();
}
else
{
if (num_readers == n_readers_ - 1)
gate1_.notify_one();
}
}
// Upgrade ownership
void
upgrade_mutex::lock_upgrade()
{
boost::unique_lock<mutex_t> lk(mut_);
while ((state_ & (write_entered_ | upgradable_entered_)) ||
(state_ & n_readers_) == n_readers_)
gate1_.wait(lk);
count_t num_readers = (state_ & n_readers_) + 1;
state_ &= ~n_readers_;
state_ |= upgradable_entered_ | num_readers;
}
bool
upgrade_mutex::try_lock_upgrade()
{
boost::unique_lock<mutex_t> lk(mut_);
count_t num_readers = state_ & n_readers_;
if (!(state_ & (write_entered_ | upgradable_entered_))
&& num_readers != n_readers_)
{
++num_readers;
state_ &= ~n_readers_;
state_ |= upgradable_entered_ | num_readers;
return true;
}
return false;
}
void
upgrade_mutex::unlock_upgrade()
{
{
boost::lock_guard<mutex_t> _(mut_);
count_t num_readers = (state_ & n_readers_) - 1;
state_ &= ~(upgradable_entered_ | n_readers_);
state_ |= num_readers;
}
gate1_.notify_all();
}
// Shared <-> Exclusive
bool
upgrade_mutex::try_unlock_shared_and_lock()
{
boost::unique_lock<mutex_t> lk(mut_);
if (state_ == 1)
{
state_ = write_entered_;
return true;
}
return false;
}
void
upgrade_mutex::unlock_and_lock_shared()
{
{
boost::lock_guard<mutex_t> _(mut_);
state_ = 1;
}
gate1_.notify_all();
}
// Shared <-> Upgrade
bool
upgrade_mutex::try_unlock_shared_and_lock_upgrade()
{
boost::unique_lock<mutex_t> lk(mut_);
if (!(state_ & (write_entered_ | upgradable_entered_)))
{
state_ |= upgradable_entered_;
return true;
}
return false;
}
void
upgrade_mutex::unlock_upgrade_and_lock_shared()
{
{
boost::lock_guard<mutex_t> _(mut_);
state_ &= ~upgradable_entered_;
}
gate1_.notify_all();
}
// Upgrade <-> Exclusive
void
upgrade_mutex::unlock_upgrade_and_lock()
{
boost::unique_lock<mutex_t> lk(mut_);
count_t num_readers = (state_ & n_readers_) - 1;
state_ &= ~(upgradable_entered_ | n_readers_);
state_ |= write_entered_ | num_readers;
while (state_ & n_readers_)
gate2_.wait(lk);
}
bool
upgrade_mutex::try_unlock_upgrade_and_lock()
{
boost::unique_lock<mutex_t> lk(mut_);
if (state_ == (upgradable_entered_ | 1))
{
state_ = write_entered_;
return true;
}
return false;
}
void
upgrade_mutex::unlock_and_lock_upgrade()
{
{
boost::lock_guard<mutex_t> _(mut_);
state_ = upgradable_entered_ | 1;
}
gate1_.notify_all();
}
} // thread_v2
} // boost

View File

@@ -36,33 +36,31 @@ namespace boost
#else
boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT;
#endif
#if defined(UNDER_CE)
#if defined(UNDER_CE)
// Windows CE does not define the TLS_OUT_OF_INDEXES constant.
DWORD tls_out_of_index=0xFFFFFFFF;
#else
DWORD tls_out_of_index=TLS_OUT_OF_INDEXES;
#endif
DWORD current_thread_tls_key=tls_out_of_index;
#define TLS_OUT_OF_INDEXES 0xFFFFFFFF
#endif
DWORD current_thread_tls_key=TLS_OUT_OF_INDEXES;
void create_current_thread_tls_key()
{
tss_cleanup_implemented(); // if anyone uses TSS, we need the cleanup linked in
current_thread_tls_key=TlsAlloc();
BOOST_ASSERT(current_thread_tls_key!=tls_out_of_index);
BOOST_ASSERT(current_thread_tls_key!=TLS_OUT_OF_INDEXES);
}
void cleanup_tls_key()
{
if(current_thread_tls_key!=tls_out_of_index)
if(current_thread_tls_key!=TLS_OUT_OF_INDEXES)
{
TlsFree(current_thread_tls_key);
current_thread_tls_key=tls_out_of_index;
current_thread_tls_key=TLS_OUT_OF_INDEXES;
}
}
detail::thread_data_base* get_current_thread_data()
{
if(current_thread_tls_key==tls_out_of_index)
if(current_thread_tls_key==TLS_OUT_OF_INDEXES)
{
return 0;
}
@@ -72,7 +70,7 @@ namespace boost
void set_current_thread_data(detail::thread_data_base* new_data)
{
boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key);
if(current_thread_tls_key!=tls_out_of_index)
if(current_thread_tls_key!=TLS_OUT_OF_INDEXES)
BOOST_VERIFY(TlsSetValue(current_thread_tls_key,new_data));
else
boost::throw_exception(thread_resource_error());
@@ -185,16 +183,20 @@ namespace boost
{
detail::thread_data_base* const thread_info(reinterpret_cast<detail::thread_data_base*>(param));
set_current_thread_data(thread_info);
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
thread_info->run();
}
catch(thread_interrupted const&)
#ifndef BOOST_NO_EXCEPTIONS
catch(thread_interrupted const&) // BOOST_NO_EXCEPTIONS protected
{
}
#endif
// Removed as it stops the debugger identifying the cause of the exception
// Unhandled exceptions still cause the application to terminate
// catch(...)
// catch(...) // BOOST_NO_EXCEPTIONS protected
// {
// std::terminate();
// }
@@ -221,7 +223,7 @@ namespace boost
void thread::start_thread(const attributes& attr)
{
//uintptr_t const new_thread=_beginthreadex(attr.get_security(),attr.get_stack_size(),&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id);
uintptr_t const new_thread=_beginthreadex(0,attr.get_stack_size(),&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id);
uintptr_t const new_thread=_beginthreadex(0,static_cast<unsigned int>(attr.get_stack_size()),&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id);
if(!new_thread)
{
boost::throw_exception(thread_resource_error());
@@ -256,15 +258,19 @@ namespace boost
void make_external_thread_data()
{
externally_launched_thread* me=detail::heap_new<externally_launched_thread>();
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
set_current_thread_data(me);
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
detail::heap_delete(me);
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}
detail::thread_data_base* get_or_make_current_thread_data()

View File

@@ -11,7 +11,7 @@
#if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB)
#if (defined(__MINGW32__) && !defined(_WIN64)) || defined(__MINGW64__)
#if (defined(__MINGW32__) && !defined(_WIN64)) || defined(__MINGW64__) || (__MINGW64_VERSION_MAJOR)
#include <boost/thread/detail/tss_hooks.hpp>
@@ -38,7 +38,7 @@ namespace {
}
}
#if defined(__MINGW64__) || (__MINGW32_MAJOR_VERSION >3) || \
#if defined(__MINGW64__) || (__MINGW64_VERSION_MAJOR) || (__MINGW32_MAJOR_VERSION >3) || \
((__MINGW32_MAJOR_VERSION==3) && (__MINGW32_MINOR_VERSION>=18))
extern "C"
{

View File

@@ -80,9 +80,14 @@ rule thread-run ( sources )
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
]
;
}
@@ -160,6 +165,7 @@ rule thread-compile-fail ( sources : reqs * : name )
#[ thread-test test_vhh_shared_mutex_timed_locks.cpp ]
;
#explicit t_futures ;
test-suite t_futures
:
[ thread-test test_futures.cpp ]
@@ -194,7 +200,7 @@ rule thread-compile-fail ( sources : reqs * : name )
#explicit conditions ;
#explicit ts_conditions ;
test-suite ts_conditions
:
[ thread-compile-fail ./sync/conditions/condition_variable/assign_fail.cpp : : condition_variable__assign_f ]
@@ -218,13 +224,13 @@ rule thread-compile-fail ( sources : reqs * : name )
[ thread-run2 ./sync/conditions/cv_status/cv_status_pass.cpp : cv_status__cv_status_p ]
;
#explicit async ;
#explicit ts_async ;
test-suite ts_async
:
# [ thread-run2 ./sync/futures/async/async_pass.cpp : async__async_p ]
;
#explicit promise ;
#explicit ts_promise ;
test-suite ts_promise
:
[ thread-compile-fail ./sync/futures/promise/copy_assign_fail.cpp : : promise__copy_assign_f ]
@@ -238,7 +244,7 @@ rule thread-compile-fail ( sources : reqs * : name )
[ thread-run2 ./sync/futures/promise/use_allocator_pass.cpp : promise__use_allocator_p ]
;
#explicit future ;
#explicit ts_future ;
test-suite ts_future
:
[ thread-compile-fail ./sync/futures/future/copy_assign_fail.cpp : : future__copy_assign_f ]
@@ -251,7 +257,7 @@ rule thread-compile-fail ( sources : reqs * : name )
[ thread-run2 ./sync/futures/future/share_pass.cpp : future__share_p ]
;
#explicit packaged_task ;
#explicit ts_packaged_task ;
test-suite ts_packaged_task
:
[ thread-run2 ./sync/futures/packaged_task/alloc_ctor_pass.cpp : packaged_task__alloc_ctor_p ]
@@ -272,7 +278,7 @@ rule thread-compile-fail ( sources : reqs * : name )
;
#explicit lock_guard ;
#explicit ts_lock_guard ;
test-suite ts_lock_guard
:
[ thread-compile-fail ./sync/mutual_exclusion/locks/lock_guard/copy_assign_fail.cpp : : lock_guard__cons__copy_assign_f ]
@@ -282,7 +288,7 @@ rule thread-compile-fail ( sources : reqs * : name )
[ thread-run2 ./sync/mutual_exclusion/locks/lock_guard/types_pass.cpp : lock_guard__types_p ]
;
#explicit unique_lock ;
#explicit ts_unique_lock ;
test-suite ts_unique_lock
:
[ thread-compile-fail ./sync/mutual_exclusion/locks/unique_lock/cons/copy_assign_fail.cpp : : unique_lock__cons__copy_assign_f ]
@@ -315,7 +321,7 @@ rule thread-compile-fail ( sources : reqs * : name )
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/types_pass.cpp : unique_lock__types_p ]
;
#explicit shared_lock ;
#explicit ts_shared_lock ;
test-suite ts_shared_lock
:
[ thread-compile-fail ./sync/mutual_exclusion/locks/shared_lock/cons/copy_assign_fail.cpp : : shared_lock__cons__copy_assign_f ]
@@ -345,7 +351,7 @@ rule thread-compile-fail ( sources : reqs * : name )
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/types_pass.cpp : shared_lock__types_p ]
;
#explicit upgrade_lock ;
#explicit ts_upgrade_lock ;
test-suite ts_upgrade_lock
:
[ thread-compile-fail ./sync/mutual_exclusion/locks/upgrade_lock/cons/copy_assign_fail.cpp : : upgrade_lock__cons__copy_assign_f ]
@@ -374,7 +380,7 @@ rule thread-compile-fail ( sources : reqs * : name )
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/types_pass.cpp : upgrade_lock__types_p ]
;
#explicit mutexs ;
#explicit ts_mutex ;
test-suite ts_mutex
:
[ thread-compile-fail ./sync/mutual_exclusion/mutex/assign_fail.cpp : : mutex__assign_f ]
@@ -385,7 +391,7 @@ rule thread-compile-fail ( sources : reqs * : name )
[ thread-run2 ./sync/mutual_exclusion/mutex/try_lock_pass.cpp : mutex__try_lock_p ]
;
#explicit recursive_mutex ;
#explicit ts_recursive_mutex ;
test-suite ts_recursive_mutex
:
[ thread-compile-fail ./sync/mutual_exclusion/recursive_mutex/assign_fail.cpp : : recursive_mutex__assign_f ]
@@ -396,7 +402,7 @@ rule thread-compile-fail ( sources : reqs * : name )
[ thread-run2 ./sync/mutual_exclusion/recursive_mutex/try_lock_pass.cpp : recursive_mutex__try_lock_p ]
;
#explicit recursive_timed_mutex ;
#explicit ts_recursive_timed_mutex ;
test-suite ts_recursive_timed_mutex
:
[ thread-compile-fail ./sync/mutual_exclusion/recursive_timed_mutex/assign_fail.cpp : : recursive_timed_mutex__assign_f ]
@@ -409,7 +415,7 @@ rule thread-compile-fail ( sources : reqs * : name )
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/try_lock_until_pass.cpp : recursive_timed_mutex__try_lock_until_p ]
;
#explicit timed_mutex ;
#explicit ts_timed_mutex ;
test-suite ts_timed_mutex
:
[ thread-compile-fail ./sync/mutual_exclusion/timed_mutex/assign_fail.cpp : : timed_mutex__assign_f ]
@@ -422,7 +428,7 @@ rule thread-compile-fail ( sources : reqs * : name )
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/try_lock_until_pass.cpp : timed_mutex__try_lock_until_p ]
;
#explicit shared_mutexs ;
#explicit ts_shared_mutex ;
test-suite ts_shared_mutex
:
[ thread-compile-fail ./sync/mutual_exclusion/shared_mutex/assign_fail.cpp : : shared_mutex__assign_f ]
@@ -435,7 +441,7 @@ rule thread-compile-fail ( sources : reqs * : name )
;
#explicit this_thread ;
#explicit ts_this_thread ;
test-suite ts_this_thread
:
[ thread-run2 ./threads/this_thread/get_id/get_id_pass.cpp : this_thread__get_id_p ]
@@ -443,7 +449,7 @@ rule thread-compile-fail ( sources : reqs * : name )
[ thread-run2 ./threads/this_thread/sleep_until/sleep_until_pass.cpp : this_thread__sleep_until_p ]
;
#explicit thread ;
#explicit ts_thread ;
test-suite ts_thread
:
[ thread-compile-fail ./threads/thread/assign/copy_fail.cpp : : thread__assign__copy_f ]
@@ -474,7 +480,7 @@ rule thread-compile-fail ( sources : reqs * : name )
[ thread-run2 ./threads/container/thread_ptr_list_pass.cpp : container__thread_ptr_list_p ]
;
#explicit examples ;
#explicit ts_examples ;
test-suite ts_examples
:
[ thread-run ../example/monitor.cpp ]
@@ -494,7 +500,7 @@ rule thread-compile-fail ( sources : reqs * : name )
#[ thread-run ../example/vhh_shared_mutex.cpp ]
;
#explicit shared_upwards ;
#explicit ts_shared_upwards ;
test-suite ts_shared_upwards
:
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp : unique_lock__cons__move_ctor_shared_lock_try_p ]
@@ -507,7 +513,7 @@ rule thread-compile-fail ( sources : reqs * : name )
;
#explicit shared_lock_guard ;
#explicit ts_shared_lock_guard ;
test-suite ts_shared_lock_guard
:
[ thread-compile-fail ./sync/mutual_exclusion/locks/shared_lock_guard/copy_assign_fail.cpp : : shared_lock_guard__cons__copy_assign_f ]
@@ -517,7 +523,7 @@ rule thread-compile-fail ( sources : reqs * : name )
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock_guard/types_pass.cpp : shared_lock_guard__types_p ]
;
#explicit reverse_lock ;
#explicit ts_reverse_lock ;
test-suite ts_reverse_lock
:
[ thread-compile-fail ./sync/mutual_exclusion/locks/reverse_lock/copy_assign_fail.cpp : : reverse_lock__copy_assign_f ]

View File

@@ -24,6 +24,8 @@
#include <boost/thread/future.hpp>
#include <boost/thread/thread.hpp>
#include <boost/interprocess/smart_ptr/unique_ptr.hpp>
#include <memory>
#include <boost/detail/lightweight_test.hpp>
@@ -49,13 +51,13 @@ void f2()
boost::this_thread::sleep_for(ms(200));
}
boost::unique_ptr<int> f3(int i)
boost::interprocess::unique_ptr<int> f3(int i)
{
boost::this_thread::sleep_for(ms(200));
return boost::unique_ptr<int>(new int(i));
return boost::interprocess::unique_ptr<int>(new int(i));
}
boost::unique_ptr<int> f4(boost::unique_ptr<int>&& p)
boost::interprocess::unique_ptr<int> f4(boost::interprocess::unique_ptr<int>&& p)
{
boost::this_thread::sleep_for(ms(200));
return boost::move(p);
@@ -163,7 +165,7 @@ int main()
}
{
boost::future<boost::unique_ptr<int>> f = boost::async(f3, 3);
boost::future<boost::interprocess::unique_ptr<int>> f = boost::async(f3, 3);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(*f.get() == 3);
@@ -172,7 +174,7 @@ int main()
}
{
boost::future<boost::unique_ptr<int>> f = boost::async(f4, boost::unique_ptr<int>(new int(3)));
boost::future<boost::interprocess::unique_ptr<int>> f = boost::async(f4, boost::interprocess::unique_ptr<int>(new int(3)));
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(*f.get() == 3);

View File

@@ -8,7 +8,9 @@ boost::shared_mutex mutex;
void thread()
{
std::cout << __FILE__ << ":" << __LINE__ << std::endl;
#ifndef BOOST_NO_EXCEPTIONS
try
#endif
{
for (int i =0; i<10; ++i)
{
@@ -23,10 +25,12 @@ void thread()
}
}
}
#ifndef BOOST_NO_EXCEPTIONS
catch (boost::lock_error& le)
{
std::cerr << "lock_error exception\n";
}
#endif
std::cout << __FILE__ << ":" << __LINE__ << std::endl;
}

View File

@@ -11,16 +11,16 @@ typedef upgrade_to_unique_lock<shared_mutex> auto_upgrade_unique_lock;
void testUpgrade(void)
{
shared_mutex mtx;
auto_upgrade_lock lock(mtx);
// Do some read-only stuff
shared_mutex mtx;
auto_upgrade_lock lock(mtx);
// Do some read-only stuff
auto_upgrade_unique_lock writeLock(lock);
// Do some write-only stuff with the upgraded lock
auto_upgrade_unique_lock writeLock(lock);
// Do some write-only stuff with the upgraded lock
}
int main()
{
testUpgrade();
return 0;
}
}

View File

@@ -1,3 +1,8 @@
// Copyright (C) 2010 Vicente Botet
//
// 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.hpp>
@@ -16,13 +21,21 @@ private:
public:
MovableButNonCopyable() {};
MovableButNonCopyable(MovableButNonCopyable&&) {};
MovableButNonCopyable& operator=(MovableButNonCopyable&&) {
MovableButNonCopyable& operator=(MovableButNonCopyable&&)
{
return *this;
};
};
MovableButNonCopyable construct()
{
return MovableButNonCopyable();
}
int main()
{
boost::packaged_task<MovableButNonCopyable>(MovableButNonCopyable());
boost::packaged_task<MovableButNonCopyable> pt(construct);
pt();
return 0;
}
#else

View File

@@ -36,7 +36,7 @@ int main()
boost::chrono::nanoseconds err = ms / 100;
// The time slept is within 1% of 500ms
// This test is spurious as it depends on the time the thread system switches the threads
BOOST_TEST(std::max(ns.count(), -ns.count()) < (err+boost::chrono::milliseconds(1000)).count());
BOOST_TEST((std::max)(ns.count(), -ns.count()) < (err+boost::chrono::milliseconds(1000)).count());
//BOOST_TEST(std::abs(static_cast<long>(ns.count())) < (err+boost::chrono::milliseconds(1000)).count());
return boost::report_errors();

View File

@@ -36,7 +36,7 @@ int main()
boost::chrono::nanoseconds err = ms / 100;
// The time slept is within 1% of 500ms
// This test is spurious as it depends on the time the thread system switches the threads
BOOST_TEST(std::max(ns.count(), -ns.count()) < (err+boost::chrono::milliseconds(1000)).count());
BOOST_TEST((std::max)(ns.count(), -ns.count()) < (err+boost::chrono::milliseconds(1000)).count());
//BOOST_TEST(std::abs(static_cast<long>(ns.count())) < (err+boost::chrono::milliseconds(1000)).count());
return boost::report_errors();