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

Compare commits

..

84 Commits

Author SHA1 Message Date
Beman Dawes
8584eea537 Boost 1.42.0
[SVN r59432]
2010-02-02 20:03:43 +00:00
Anthony Williams
9087fd904d Merged documentation changes to boost.thread (re at_thread_exit) from trunk
[SVN r57381]
2009-11-04 21:48:18 +00:00
Anthony Williams
66ac6942b6 Merged boost.thread changes from trunk
[SVN r57243]
2009-10-30 09:50:13 +00:00
Anthony Williams
20980fe54d Merged thread changes from trunk
[SVN r56992]
2009-10-19 09:18:13 +00:00
Troy D. Straszheim
fb54acfe69 rm cmake from the release branch before it goes out broken. Policy dictates that you never commit to release, you commit to trunk and merge to release.
[SVN r56941]
2009-10-17 01:10:45 +00:00
Troy D. Straszheim
0e69edd066 Add basic copyright/license to keep cmake out of the inspection report
[SVN r55095]
2009-07-22 21:51:01 +00:00
John Maddock
9255a035f4 Merge PDF build changes from Trunk.
[SVN r51417]
2009-02-23 18:39:32 +00:00
Troy D. Straszheim
fbdc23f482 merge of cmake build files from trunk per beman
[SVN r50756]
2009-01-24 18:57:20 +00:00
Anthony Williams
8ab0d5acdd Merged change from trunk removing catch(...) clauses
[SVN r50524]
2009-01-09 11:06:53 +00:00
Daniel James
5af323102a Merge [46445] - add line ending properties. Ref #2441.
[SVN r49577]
2008-11-03 22:29:39 +00:00
Anthony Williams
0997fad8ec Merged Boost.Thread changes from trunk
[SVN r49324]
2008-10-13 20:30:13 +00:00
Anthony Williams
8749696538 Merged Thread doc changes from trunk
[SVN r48038]
2008-08-08 20:38:50 +00:00
Anthony Williams
9beea23f63 Merged thread doc changes from trunk
[SVN r47827]
2008-07-26 08:39:51 +00:00
Anthony Williams
2978d43a5d Merged thread doc changes from trunk
[SVN r47701]
2008-07-23 09:37:02 +00:00
Anthony Williams
a264766584 Merged changes over from trunk
[SVN r47700]
2008-07-23 09:35:40 +00:00
Anthony Williams
f03a9bfcf3 Merged thread changes from trunk
[SVN r47211]
2008-07-08 07:44:55 +00:00
Anthony Williams
60fdcddcb5 Merge of new boost.thread code along with required changes from boost.bind
[SVN r46474]
2008-06-18 13:01:08 +00:00
Anthony Williams
525d190f91 removed declaration of undefined type exclusive_lock
[SVN r43850]
2008-03-25 07:59:58 +00:00
Anthony Williams
1e0154335b Imported revision #43730 from trunk to eliminate some warnings
[SVN r43743]
2008-03-21 15:04:10 +00:00
Anthony Williams
413c29a5e4 New documentation for thread library imported from trunk revision 43671
[SVN r43674]
2008-03-17 13:59:17 +00:00
Anthony Williams
30bb6143c1 Test and fix for bug #1693 to ensure thread_specific_ptr::release works as desired imported from trunk changeset 43666
[SVN r43673]
2008-03-17 13:46:19 +00:00
Anthony Williams
991ac727c6 Imported changeset 43461 to fix issue #1665
[SVN r43520]
2008-03-05 20:47:56 +00:00
Daniel James
569a78649f Merged revisions 43211,43214-43219,43222-43225,43227-43238,43242,43244-43245,43249-43250,43257-43259,43261,43263,43265,43267-43268,43270-43271,43273,43275-43279,43284-43289,43291,43295,43297-43298,43304-43305,43307,43313,43315,43324,43326-43327,43331,43333,43339-43343,43345,43348,43350,43352-43353,43355-43356,43358,43360,43366-43367,43369-43370,43372-43376,43378-43389,43394,43396-43398,43400-43401,43403-43404,43406-43408,43413-43415,43417-43418,43420,43422-43423 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r43417 | danieljames | 2008-02-26 22:04:55 +0000 (Tue, 26 Feb 2008) | 2 lines
  
  Fix a link to Boost.Bimap.
........
  r43418 | danieljames | 2008-02-26 22:07:25 +0000 (Tue, 26 Feb 2008) | 2 lines
  
  Change another link that's no longer in the repository to link to the website.
........
  r43422 | danieljames | 2008-02-27 18:51:14 +0000 (Wed, 27 Feb 2008) | 1 line
  
  Fix broken copyright urls. Fixes #1573.
........
  r43423 | danieljames | 2008-02-27 19:22:01 +0000 (Wed, 27 Feb 2008) | 1 line
  
  Fix incorrect links to copyright of the form 'http:#www.boost.org
........


[SVN r43425]
2008-02-27 20:00:24 +00:00
Anthony Williams
7caec1ec33 Fix for ticket #1547 --- Change use of NULL to 0
[SVN r43268]
2008-02-15 17:56:13 +00:00
Anthony Williams
7fd3fb48b1 Pulling changeset 43094 over from trunk
[SVN r43227]
2008-02-12 20:49:56 +00:00
Anthony Williams
a32a3b37db Merged latest changes to boost.thread over from trunk
[SVN r42230]
2007-12-21 11:51:05 +00:00
Beman Dawes
88f6076f3c Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41370]
2007-11-25 18:38:02 +00:00
Beman Dawes
b4d12e08dd Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41369]
2007-11-25 18:07:19 +00:00
Beman Dawes
1c0f470032 Starting point for releases
[SVN r39706]
2007-10-05 14:25:06 +00:00
nobody
92b8789532 This commit was manufactured by cvs2svn to create tag
'Version_1_34_1'.

[SVN r38286]
2007-07-24 19:28:14 +00:00
Thomas Witt
8f61694057 Fix #1039.
[SVN r37948]
2007-06-08 18:48:50 +00:00
Thomas Witt
67f7de5305 Fix #996.
[SVN r37815]
2007-05-29 17:12:59 +00:00
Anthony Williams
6faecefb73 Fix for ticket #906
[SVN r37740]
2007-05-22 15:38:58 +00:00
Anthony Williams
68c5bd44e8 undone accidental commit
[SVN r37647]
2007-05-09 07:04:46 +00:00
Anthony Williams
3656277053 Removed read_write_mutex source files and header
[SVN r37646]
2007-05-09 07:02:13 +00:00
Thomas Witt
19846ff356 Fix Xml error. This change is already in HEAD.
[SVN r37499]
2007-04-24 16:11:17 +00:00
Roland Schwarz
db2aaa04fd Merged from HEAD.
[SVN r36923]
2007-02-11 13:55:21 +00:00
Roland Schwarz
b48f9aa609 Merged patch from trunk.
[SVN r36921]
2007-02-11 13:14:44 +00:00
Anthony Williams
7915ab1ec6 Fixed typos and improved phrasing
[SVN r36751]
2007-01-18 17:33:50 +00:00
Roland Schwarz
f0faf88d66 Updated the build instructions and acknowledgements.
[SVN r36706]
2007-01-12 16:48:02 +00:00
Roland Schwarz
7dd7537f5f renamed back to .v2 since build process is broken otherwise.
[SVN r36641]
2007-01-07 14:53:25 +00:00
Roland Schwarz
f51680e8d9 Renamed Jamfile.
[SVN r36640]
2007-01-07 14:08:02 +00:00
Roland Schwarz
a6bc072c6d removing obsolete files
[SVN r36639]
2007-01-07 14:05:30 +00:00
Roland Schwarz
85f2508157 Updating build instructions.
[SVN r36638]
2007-01-07 12:33:42 +00:00
Roland Schwarz
ebb6c8d637 Corrected a typo; more prominent note of unavailability of RW-Mutex.
[SVN r36565]
2007-01-02 21:44:39 +00:00
Roland Schwarz
ddc83e270c Corrected a typo, and reactivated links to read_write mutex.
[SVN r36560]
2007-01-01 16:45:52 +00:00
Roland Schwarz
0173148a2e Recovered file, since it is linked to rest of doc.
[SVN r36559]
2007-01-01 14:10:28 +00:00
Roland Schwarz
69a4ec6c00 QNX debuging
[SVN r36489]
2006-12-22 13:40:38 +00:00
Roland Schwarz
2d52219af2 Merged from HEAD
[SVN r36488]
2006-12-22 10:38:23 +00:00
Roland Schwarz
1f87a9e4c0 Temporary test code for QNX debugging.
[SVN r36430]
2006-12-16 16:17:55 +00:00
Roland Schwarz
ba8afde42b Additional asserions in an attempt to find the errors on QNX.
[SVN r36395]
2006-12-14 21:44:20 +00:00
Roland Schwarz
93f677cba6 Changed back to CHECK since WARNING not showing up in regression tables.
[SVN r36387]
2006-12-14 17:51:25 +00:00
Roland Schwarz
dfd865d67d Fixed missing tss_null file.
[SVN r36332]
2006-12-11 19:51:14 +00:00
Vladimir Prus
96a04402db Merge from HEAD.
Allow building of shared versions of some Boost.Test libraries.
Adjust tests to use always use static linking to Boost.Test, since
linking to the shared version requires test changes.

Patch from Juergen Hunold.


[SVN r35990]
2006-11-10 19:59:52 +00:00
Anthony Williams
78e644c7c1 removed docs for read_write_mutex
[SVN r35976]
2006-11-10 15:51:13 +00:00
Rene Rivera
89cc7fc34e Remove obsolete Boost.Build v1 files.
[SVN r35880]
2006-11-06 17:10:46 +00:00
Roland Schwarz
974754598e Removed recursive_mutex from library builds and regression testing for RC_1_34_0 branch.
[SVN r35818]
2006-11-03 04:39:17 +00:00
Roland Schwarz
87acbb406d Forced read_write_mutex unusable for RC_1_34_0 branch.
[SVN r35817]
2006-11-03 04:37:45 +00:00
Roland Schwarz
597517157c Updated documentation for the RC_1_34_0 branch to reflect current state of read_write_mutex.
[SVN r35816]
2006-11-03 04:05:55 +00:00
Roland Schwarz
a0b816be8c Get rid of dll import warnings for noncopyable classes
[SVN r35797]
2006-10-30 19:35:40 +00:00
Roland Schwarz
4a056924d2 Added a warning about usage of read_write_mutex.
[SVN r35675]
2006-10-20 17:26:18 +00:00
Roland Schwarz
d5a81f990c Inified spelling of thread library in documentation. (singular)
Added RC_1_34_0 release notes.


[SVN r35619]
2006-10-15 14:52:54 +00:00
Markus Schöpflin
da8c92f057 Reverted last checkin. Works when patching the compiler.
[SVN r35495]
2006-10-05 08:08:40 +00:00
Roland Schwarz
866b33c808 Untabified file
[SVN r35458]
2006-10-03 18:23:06 +00:00
Roland Schwarz
182daf0b17 Disabled certain borland warnings
[SVN r35449]
2006-10-02 21:22:49 +00:00
Roland Schwarz
2552febc2a Made non-availability of automatic TSS cleanup for native Windows threads a warning instead of an error.
[SVN r35448]
2006-10-02 21:19:55 +00:00
Roland Schwarz
eb9db9b683 Added changes for MSVC 7.0
[SVN r35445]
2006-10-02 18:17:26 +00:00
Roland Schwarz
11dbdfca4d added assertions around gettimeofday and clock_gettime
[SVN r35439]
2006-10-02 09:45:28 +00:00
Markus Schöpflin
f49de9ec10 Disable threading tests on Tru64/GCC-4.1.1.
[SVN r35438]
2006-10-02 09:07:47 +00:00
Roland Schwarz
3a7e569a65 Test if this turns regressions green on win x64 platforms
[SVN r35437]
2006-10-02 07:49:04 +00:00
Roland Schwarz
c376c1a62a Removed the "intentional memory leak" of the TSS implementation.
[SVN r35434]
2006-10-01 12:57:18 +00:00
Roland Schwarz
fbbc52063a avoid complaints of boostinspect about unnamed namespace usage
[SVN r35412]
2006-09-29 07:49:51 +00:00
Roland Schwarz
78b4fe3d07 avoid complaints of boostinspect about unnamed namespace usage
[SVN r35411]
2006-09-29 07:36:49 +00:00
Roland Schwarz
b8c8b250b1 Removed try catch(...) from thread proxy
[SVN r35328]
2006-09-26 03:05:06 +00:00
Roland Schwarz
b26d01c8d7 Fixed on of the memory leaks related to TSS
[SVN r35324]
2006-09-25 23:53:10 +00:00
Hartmut Kaiser
4dbd8a66af Changed Boost.Thread to use the Boost license.
[SVN r35115]
2006-09-14 23:02:29 +00:00
Hartmut Kaiser
cb4d739fd1 Changed Boost.Thread to use the Boost license.
[SVN r35112]
2006-09-14 21:51:01 +00:00
Anthony Williams
11f913e8fb added BSL for files with authors in blanket_permissions.txt
[SVN r35090]
2006-09-13 14:11:49 +00:00
Anthony Williams
0b6054a919 added boostinspect:nolicense to files with old license from William Kempf
[SVN r35087]
2006-09-13 08:54:53 +00:00
Anthony Williams
e7620a1050 added boostinspect:nolicense to files with old license from William Kempf
[SVN r35086]
2006-09-13 08:33:30 +00:00
Nicola Musatti
811a03f281 Updated Borland workaround
[SVN r33942]
2006-05-05 21:13:45 +00:00
Anthony Williams
2528bd0b8f Added patch from http://lists.boost.org/Archives/boost/2005/05/86395.php to fix bug
https://sourceforge.net/tracker/index.php?func=detail&aid=1424965&group_id=7586&atid=107586


[SVN r33802]
2006-04-25 10:06:38 +00:00
Vladimir Prus
ed587be470 Merge from trunk
[SVN r33597]
2006-04-07 14:01:36 +00:00
nobody
55b48874a4 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r33417]
2006-03-21 02:26:31 +00:00
34 changed files with 346 additions and 864 deletions

View File

@@ -45,15 +45,6 @@ all subsequent `call_once` invocations on the same `once_flag` object. ]]
[[Throws:] [`thread_resource_error` when the effects cannot be achieved. or any exception propagated from `func`.]]
[[Note:] [The function passed to `call_once` must not also call
`call_once` passing the same `once_flag` object. This may cause
deadlock, or invoking the passed function a second time. The
alternative is to allow the second call to return immediately, but
that assumes the code knows it has been called recursively, and can
proceed even though the call to `call_once` didn't actually call the
function, in which case it could also avoid calling `call_once`
recursively.]]
]
void call_once(void (*func)(),once_flag& flag);

View File

@@ -219,7 +219,6 @@ __thread_id__ yield a total order for every non-equal thread ID.
};
void swap(thread& lhs,thread& rhs);
detail::thread_move_t<thread> move(detail::thread_move_t<thread> t);
[section:default_constructor Default Constructor]
@@ -235,40 +234,6 @@ __thread_id__ yield a total order for every non-equal thread ID.
[endsect]
[section:move_constructor Move Constructor]
thread(detail::thread_move_t<thread> other);
[variablelist
[[Effects:] [Transfers ownership of the thread managed by `other` (if any) to the newly constructed __thread__ instance.]]
[[Postconditions:] [`other->get_id()==thread::id()`]]
[[Throws:] [Nothing]]
]
[endsect]
[section:move_assignment Move assignment operator]
thread& operator=(detail::thread_move_t<thread> other);
[variablelist
[[Effects:] [Transfers ownership of the thread managed by `other` (if
any) to `*this`. If there was a thread previously associated with
`*this` then that thread is detached.]]
[[Postconditions:] [`other->get_id()==thread::id()`]]
[[Throws:] [Nothing]]
]
[endsect]
[section:callable_constructor Thread Constructor]
template<typename Callable>
@@ -556,26 +521,6 @@ value as `this->get_id()` prior to the call.]]
[endsect]
[section:non_member_move Non-member function `move()`]
#include <boost/thread/thread.hpp>
detail::thread_move_t<thread> move(detail::thread_move_t<thread> t)
[variablelist
[[Returns:] [`t`.]]
]
Enables moving thread objects. e.g.
extern void some_func();
boost::thread t(some_func);
boost::thread t2(boost::move(t)); // transfer thread from t to t2
[endsect]
[section:id Class `boost::thread::id`]
@@ -811,14 +756,11 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
{
template<typename TimeDuration>
void sleep(TimeDuration const& rel_time);
void sleep(system_time const& abs_time)
}
[variablelist
[[Effects:] [Suspends the current thread until the time period
specified by `rel_time` has elapsed or the time point specified by
`abs_time` has been reached.]]
[[Effects:] [Suspends the current thread until the specified time has elapsed.]]
[[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted.]]

View File

@@ -9,7 +9,6 @@
#define BOOST_BARRIER_JDM030602_HPP
#include <boost/thread/detail/config.hpp>
#include <boost/throw_exception.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
@@ -28,7 +27,7 @@ namespace boost
: m_threshold(count), m_count(count), m_generation(0)
{
if (count == 0)
boost::throw_exception(std::invalid_argument("count cannot be zero."));
throw std::invalid_argument("count cannot be zero.");
}
bool wait()

View File

@@ -20,7 +20,7 @@
#include "platform.hpp"
// compatibility with the rest of Boost's auto-linking code:
#if defined(BOOST_THREAD_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)
#if defined(BOOST_THREAD_DYN_DLL) || defined(BOOST_ALL_DYN_LINK)
# undef BOOST_THREAD_USE_LIB
# define BOOST_THREAD_USE_DLL
#endif

View File

@@ -3,12 +3,10 @@
// 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)
// (C) Copyright 2007-10 Anthony Williams
// (C) Copyright 2007-8 Anthony Williams
#include <boost/thread/exceptions.hpp>
#ifndef BOOST_NO_IOSTREAM
#include <ostream>
#endif
#include <boost/thread/detail/move.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/xtime.hpp>
@@ -41,13 +39,10 @@ namespace boost
public detail::thread_data_base
{
public:
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
thread_data(F&& f_):
f(static_cast<F&&>(f_))
{}
thread_data(F& f_):
f(f_)
{}
#else
thread_data(F f_):
f(f_)
@@ -124,7 +119,7 @@ namespace boost
detail::thread_data_ptr get_thread_info() const;
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
template<typename F>
static inline detail::thread_data_ptr make_thread_info(F&& f)
{
@@ -132,7 +127,7 @@ namespace boost
}
static inline detail::thread_data_ptr make_thread_info(void (*f)())
{
return detail::thread_data_ptr(detail::heap_new<detail::thread_data<void(*)()> >(static_cast<void(*&&)()>(f)));
return detail::thread_data_ptr(detail::heap_new<detail::thread_data<void(*)()> >(f));
}
#else
template<typename F>
@@ -146,31 +141,22 @@ namespace boost
return detail::thread_data_ptr(detail::heap_new<detail::thread_data<F> >(f));
}
#endif
struct dummy;
#endif
public:
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
#ifdef __SUNPRO_CC
thread(const volatile thread&);
#endif
thread();
~thread();
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_MSVC
template <class F>
explicit thread(F f,typename disable_if<boost::is_convertible<F&,detail::thread_move_t<F> >, dummy* >::type=0):
thread_info(make_thread_info(f))
{
start_thread();
}
#else
#ifdef BOOST_HAS_RVALUE_REFS
template <class F>
thread(F&& f):
thread_info(make_thread_info(static_cast<F&&>(f)))
{
start_thread();
}
#endif
thread(thread&& other)
{
@@ -219,7 +205,7 @@ namespace boost
x->thread_info.reset();
}
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
#ifdef __SUNPRO_CC
thread& operator=(thread x)
{
swap(x);
@@ -357,14 +343,10 @@ namespace boost
return lhs.swap(rhs);
}
#ifndef BOOST_NO_RVALUE_REFERENCES
inline thread&& move(thread& t)
{
return static_cast<thread&&>(t);
}
#ifdef BOOST_HAS_RVALUE_REFS
inline thread&& move(thread&& t)
{
return static_cast<thread&&>(t);
return t;
}
#else
inline detail::thread_move_t<thread> move(detail::thread_move_t<thread> t)
@@ -396,7 +378,7 @@ namespace boost
thread_data(thread_data_)
{}
friend class thread;
friend id BOOST_THREAD_DECL this_thread::get_id();
friend id this_thread::get_id();
public:
id():
thread_data()
@@ -432,7 +414,6 @@ namespace boost
return !(thread_data<y.thread_data);
}
#ifndef BOOST_NO_IOSTREAM
template<class charT, class traits>
friend std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const id& x)
@@ -446,7 +427,6 @@ namespace boost
return os<<"{Not-any-thread}";
}
}
#endif
};
inline bool thread::operator==(const thread& other) const
@@ -465,7 +445,7 @@ namespace boost
{
virtual ~thread_exit_function_base()
{}
virtual void operator()()=0;
virtual void operator()() const=0;
};
template<typename F>
@@ -478,13 +458,13 @@ namespace boost
f(f_)
{}
void operator()()
void operator()() const
{
f();
}
};
void BOOST_THREAD_DECL add_thread_exit_function(thread_exit_function_base*);
void add_thread_exit_function(thread_exit_function_base*);
}
namespace this_thread

View File

@@ -18,13 +18,10 @@
namespace boost
{
class thread_group
class thread_group:
private noncopyable
{
private:
thread_group(thread_group const&);
thread_group& operator=(thread_group const&);
public:
thread_group() {}
~thread_group()
{
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();

View File

@@ -12,9 +12,27 @@
#if defined(BOOST_HAS_WINTHREADS)
namespace boost
{
BOOST_THREAD_DECL void __cdecl on_process_enter(void);
typedef void (__cdecl *thread_exit_handler)(void);
extern "C" BOOST_THREAD_DECL int at_thread_exit(
thread_exit_handler exit_handler
);
//Add a function to the list of functions that will
//be called when a thread is about to exit.
//Currently only implemented for Win32, but should
//later be implemented for all platforms.
//Used by Win32 implementation of Boost.Threads
//tss to perform cleanup.
//Like the C runtime library atexit() function,
//which it mimics, at_thread_exit() returns
//zero if successful and a nonzero
//value if an error occurs.
#endif //defined(BOOST_HAS_WINTHREADS)
#if defined(BOOST_HAS_WINTHREADS)
extern "C" BOOST_THREAD_DECL void on_process_enter(void);
//Function to be called when the exe or dll
//that uses Boost.Threads first starts
//or is first loaded.
@@ -24,7 +42,7 @@ namespace boost
//a method for doing so has been discovered.
//May be omitted; may be called multiple times.
BOOST_THREAD_DECL void __cdecl on_process_exit(void);
extern "C" BOOST_THREAD_DECL void on_process_exit(void);
//Function to be called when the exe or dll
//that uses Boost.Threads first starts
//or is first loaded.
@@ -34,7 +52,7 @@ namespace boost
//a method for doing so has been discovered.
//Must not be omitted; may be called multiple times.
BOOST_THREAD_DECL void __cdecl on_thread_enter(void);
extern "C" BOOST_THREAD_DECL void on_thread_enter(void);
//Function to be called just after a thread starts
//in an exe or dll that uses Boost.Threads.
//Must be called in the context of the thread
@@ -43,7 +61,7 @@ namespace boost
//a method for doing so has been discovered.
//May be omitted; may be called multiple times.
BOOST_THREAD_DECL void __cdecl on_thread_exit(void);
extern "C" BOOST_THREAD_DECL void __cdecl on_thread_exit(void);
//Function to be called just be fore a thread ends
//in an exe or dll that uses Boost.Threads.
//Must be called in the context of the thread
@@ -52,11 +70,10 @@ namespace boost
//a method for doing so has been discovered.
//Must not be omitted; may be called multiple times.
void tss_cleanup_implemented();
extern "C" void tss_cleanup_implemented(void);
//Dummy function used both to detect whether tss cleanup
//cleanup has been implemented and to force
//it to be linked into the Boost.Threads library.
}
#endif //defined(BOOST_HAS_WINTHREADS)

View File

@@ -1,4 +1,4 @@
// (C) Copyright 2008-10 Anthony Williams
// (C) Copyright 2008-9 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -9,8 +9,6 @@
#include <stdexcept>
#include <boost/thread/detail/move.hpp>
#include <boost/thread/thread_time.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/exception_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
@@ -18,7 +16,6 @@
#include <boost/type_traits/is_convertible.hpp>
#include <boost/mpl/if.hpp>
#include <boost/config.hpp>
#include <boost/throw_exception.hpp>
#include <algorithm>
#include <boost/function.hpp>
#include <boost/bind.hpp>
@@ -221,7 +218,7 @@ namespace boost
struct future_traits
{
typedef boost::scoped_ptr<T> storage_type;
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
typedef T const& source_reference_type;
struct dummy;
typedef typename boost::mpl::if_<boost::is_fundamental<T>,dummy&,T&&>::type rvalue_source_type;
@@ -326,7 +323,7 @@ namespace boost
move_dest_type get()
{
wait();
return static_cast<move_dest_type>(*result);
return *result;
}
future_state::state get_state()
@@ -390,18 +387,15 @@ namespace boost
class future_waiter
{
struct registered_waiter;
typedef std::vector<registered_waiter>::size_type count_type;
struct registered_waiter
{
boost::shared_ptr<detail::future_object_base> future;
detail::future_object_base::waiter_list::iterator wait_iterator;
count_type index;
unsigned index;
registered_waiter(boost::shared_ptr<detail::future_object_base> const& future_,
detail::future_object_base::waiter_list::iterator wait_iterator_,
count_type index_):
unsigned index_):
future(future_),wait_iterator(wait_iterator_),index(index_)
{}
@@ -409,13 +403,13 @@ namespace boost
struct all_futures_lock
{
count_type count;
unsigned count;
boost::scoped_array<boost::unique_lock<boost::mutex> > locks;
all_futures_lock(std::vector<registered_waiter>& futures):
count(futures.size()),locks(new boost::unique_lock<boost::mutex>[count])
{
for(count_type i=0;i<count;++i)
for(unsigned i=0;i<count;++i)
{
locks[i]=boost::unique_lock<boost::mutex>(futures[i].future->mutex);
}
@@ -428,7 +422,7 @@ namespace boost
void unlock()
{
for(count_type i=0;i<count;++i)
for(unsigned i=0;i<count;++i)
{
locks[i].unlock();
}
@@ -437,7 +431,7 @@ namespace boost
boost::condition_variable_any cv;
std::vector<registered_waiter> futures;
count_type future_count;
unsigned future_count;
public:
future_waiter():
@@ -454,12 +448,12 @@ namespace boost
++future_count;
}
count_type wait()
unsigned wait()
{
all_futures_lock lk(futures);
for(;;)
{
for(count_type i=0;i<futures.size();++i)
for(unsigned i=0;i<futures.size();++i)
{
if(futures[i].future->done)
{
@@ -472,7 +466,7 @@ namespace boost
~future_waiter()
{
for(count_type i=0;i<futures.size();++i)
for(unsigned i=0;i<futures.size();++i)
{
futures[i].future->remove_external_waiter(futures[i].wait_iterator);
}
@@ -638,7 +632,7 @@ namespace boost
~unique_future()
{}
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
unique_future(unique_future && other)
{
future.swap(other.future);
@@ -679,7 +673,7 @@ namespace boost
{
if(!future)
{
boost::throw_exception(future_uninitialized());
throw future_uninitialized();
}
return future->get();
@@ -715,7 +709,7 @@ namespace boost
{
if(!future)
{
boost::throw_exception(future_uninitialized());
throw future_uninitialized();
}
future->wait(false);
}
@@ -730,7 +724,7 @@ namespace boost
{
if(!future)
{
boost::throw_exception(future_uninitialized());
throw future_uninitialized();
}
return future->timed_wait_until(abs_time);
}
@@ -773,7 +767,7 @@ namespace boost
future=other.future;
return *this;
}
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
shared_future(shared_future && other)
{
future.swap(other.future);
@@ -836,7 +830,7 @@ namespace boost
{
if(!future)
{
boost::throw_exception(future_uninitialized());
throw future_uninitialized();
}
return future->get();
@@ -872,7 +866,7 @@ namespace boost
{
if(!future)
{
boost::throw_exception(future_uninitialized());
throw future_uninitialized();
}
future->wait(false);
}
@@ -887,7 +881,7 @@ namespace boost
{
if(!future)
{
boost::throw_exception(future_uninitialized());
throw future_uninitialized();
}
return future->timed_wait_until(abs_time);
}
@@ -935,7 +929,7 @@ namespace boost
}
// Assignment
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
promise(promise && rhs):
future_obtained(rhs.future_obtained)
{
@@ -980,7 +974,7 @@ namespace boost
lazy_init();
if(future_obtained)
{
boost::throw_exception(future_already_retrieved());
throw future_already_retrieved();
}
future_obtained=true;
return unique_future<R>(future);
@@ -992,7 +986,7 @@ namespace boost
boost::lock_guard<boost::mutex> lock(future->mutex);
if(future->done)
{
boost::throw_exception(promise_already_satisfied());
throw promise_already_satisfied();
}
future->mark_finished_with_result_internal(r);
}
@@ -1004,7 +998,7 @@ namespace boost
boost::lock_guard<boost::mutex> lock(future->mutex);
if(future->done)
{
boost::throw_exception(promise_already_satisfied());
throw promise_already_satisfied();
}
future->mark_finished_with_result_internal(static_cast<typename detail::future_traits<R>::rvalue_source_type>(r));
}
@@ -1015,7 +1009,7 @@ namespace boost
boost::lock_guard<boost::mutex> lock(future->mutex);
if(future->done)
{
boost::throw_exception(promise_already_satisfied());
throw promise_already_satisfied();
}
future->mark_exceptional_finish_internal(p);
}
@@ -1069,7 +1063,7 @@ namespace boost
}
// Assignment
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
promise(promise && rhs):
future_obtained(rhs.future_obtained)
{
@@ -1115,7 +1109,7 @@ namespace boost
if(future_obtained)
{
boost::throw_exception(future_already_retrieved());
throw future_already_retrieved();
}
future_obtained=true;
return unique_future<void>(future);
@@ -1127,7 +1121,7 @@ namespace boost
boost::lock_guard<boost::mutex> lock(future->mutex);
if(future->done)
{
boost::throw_exception(promise_already_satisfied());
throw promise_already_satisfied();
}
future->mark_finished_with_result_internal();
}
@@ -1138,7 +1132,7 @@ namespace boost
boost::lock_guard<boost::mutex> lock(future->mutex);
if(future->done)
{
boost::throw_exception(promise_already_satisfied());
throw promise_already_satisfied();
}
future->mark_exceptional_finish_internal(p);
}
@@ -1170,7 +1164,7 @@ namespace boost
boost::lock_guard<boost::mutex> lk(this->mutex);
if(started)
{
boost::throw_exception(task_already_started());
throw task_already_started();
}
started=true;
}
@@ -1289,7 +1283,7 @@ namespace boost
}
// assignment
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
packaged_task(packaged_task&& other):
future_obtained(other.future_obtained)
{
@@ -1332,7 +1326,7 @@ namespace boost
{
if(!task)
{
boost::throw_exception(task_moved());
throw task_moved();
}
else if(!future_obtained)
{
@@ -1341,7 +1335,7 @@ namespace boost
}
else
{
boost::throw_exception(future_already_retrieved());
throw future_already_retrieved();
}
}
@@ -1351,7 +1345,7 @@ namespace boost
{
if(!task)
{
boost::throw_exception(task_moved());
throw task_moved();
}
task->run();
}

View File

@@ -11,7 +11,6 @@
#include <iterator>
#include <boost/thread/thread_time.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/type_traits/is_class.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -28,52 +27,8 @@ namespace boost
#ifndef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
namespace detail
{
#define BOOST_DEFINE_HAS_MEMBER_CALLED(member_name) \
template<typename T, bool=boost::is_class<T>::value> \
struct has_member_called_##member_name \
{ \
BOOST_STATIC_CONSTANT(bool, value=false); \
}; \
\
template<typename T> \
struct has_member_called_##member_name<T,true> \
{ \
typedef char true_type; \
struct false_type \
{ \
true_type dummy[2]; \
}; \
\
struct fallback { int member_name; }; \
struct derived: \
T, fallback \
{ \
derived(); \
}; \
\
template<int fallback::*> struct tester; \
\
template<typename U> \
static false_type has_member(tester<&U::member_name>*); \
template<typename U> \
static true_type has_member(...); \
\
BOOST_STATIC_CONSTANT( \
bool, value=sizeof(has_member<derived>(0))==sizeof(true_type)); \
}
BOOST_DEFINE_HAS_MEMBER_CALLED(lock);
BOOST_DEFINE_HAS_MEMBER_CALLED(unlock);
BOOST_DEFINE_HAS_MEMBER_CALLED(try_lock);
template<typename T,bool=has_member_called_lock<T>::value >
template<typename T>
struct has_member_lock
{
BOOST_STATIC_CONSTANT(bool, value=false);
};
template<typename T>
struct has_member_lock<T,true>
{
typedef char true_type;
struct false_type
@@ -81,23 +36,15 @@ namespace boost
true_type dummy[2];
};
template<typename U,typename V>
static true_type has_member(V (U::*)());
template<typename U>
static false_type has_member(U);
static true_type has_member(U*,void (U::*dummy)()=&U::lock);
static false_type has_member(void*);
BOOST_STATIC_CONSTANT(
bool,value=sizeof(has_member_lock<T>::has_member(&T::lock))==sizeof(true_type));
BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_lock<T>::has_member((T*)NULL))==sizeof(true_type));
};
template<typename T,bool=has_member_called_unlock<T>::value >
template<typename T>
struct has_member_unlock
{
BOOST_STATIC_CONSTANT(bool, value=false);
};
template<typename T>
struct has_member_unlock<T,true>
{
typedef char true_type;
struct false_type
@@ -105,23 +52,15 @@ namespace boost
true_type dummy[2];
};
template<typename U,typename V>
static true_type has_member(V (U::*)());
template<typename U>
static false_type has_member(U);
static true_type has_member(U*,void (U::*dummy)()=&U::unlock);
static false_type has_member(void*);
BOOST_STATIC_CONSTANT(
bool,value=sizeof(has_member_unlock<T>::has_member(&T::unlock))==sizeof(true_type));
BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_unlock<T>::has_member((T*)NULL))==sizeof(true_type));
};
template<typename T,bool=has_member_called_try_lock<T>::value >
template<typename T>
struct has_member_try_lock
{
BOOST_STATIC_CONSTANT(bool, value=false);
};
template<typename T>
struct has_member_try_lock<T,true>
{
typedef char true_type;
struct false_type
@@ -130,12 +69,10 @@ namespace boost
};
template<typename U>
static true_type has_member(bool (U::*)());
template<typename U>
static false_type has_member(U);
static true_type has_member(U*,bool (U::*dummy)()=&U::try_lock);
static false_type has_member(void*);
BOOST_STATIC_CONSTANT(
bool,value=sizeof(has_member_try_lock<T>::has_member(&T::try_lock))==sizeof(true_type));
BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_try_lock<T>::has_member((T*)NULL))==sizeof(true_type));
};
}
@@ -311,7 +248,7 @@ namespace boost
{
timed_lock(target_time);
}
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
unique_lock(unique_lock&& other):
m(other.m),is_locked(other.is_locked)
{
@@ -384,17 +321,17 @@ namespace boost
swap(temp);
return *this;
}
void swap(unique_lock& other)
{
std::swap(m,other.m);
std::swap(is_locked,other.is_locked);
}
void swap(detail::thread_move_t<unique_lock<Mutex> > other)
{
std::swap(m,other->m);
std::swap(is_locked,other->is_locked);
}
#endif
void swap(unique_lock& other)
{
std::swap(m,other.m);
std::swap(is_locked,other.is_locked);
}
~unique_lock()
{
@@ -407,7 +344,7 @@ namespace boost
{
if(owns_lock())
{
boost::throw_exception(boost::lock_error());
throw boost::lock_error();
}
m->lock();
is_locked=true;
@@ -416,7 +353,7 @@ namespace boost
{
if(owns_lock())
{
boost::throw_exception(boost::lock_error());
throw boost::lock_error();
}
is_locked=m->try_lock();
return is_locked;
@@ -442,7 +379,7 @@ namespace boost
{
if(!owns_lock())
{
boost::throw_exception(boost::lock_error());
throw boost::lock_error();
}
m->unlock();
is_locked=false;
@@ -479,36 +416,25 @@ namespace boost
friend class upgrade_lock<Mutex>;
};
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
template<typename Mutex>
void swap(unique_lock<Mutex>&& lhs,unique_lock<Mutex>&& rhs)
{
lhs.swap(rhs);
}
template<typename Mutex>
inline upgrade_lock<Mutex>&& move(upgrade_lock<Mutex>&& ul)
{
return ul;
}
#endif
#else
template<typename Mutex>
void swap(unique_lock<Mutex>& lhs,unique_lock<Mutex>& rhs)
{
lhs.swap(rhs);
}
#endif
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
template<typename Mutex>
inline unique_lock<Mutex>&& move(unique_lock<Mutex>&& ul)
{
return static_cast<unique_lock<Mutex>&&>(ul);
}
template<typename Mutex>
inline unique_lock<Mutex>&& move(unique_lock<Mutex>& ul)
{
return static_cast<unique_lock<Mutex>&&>(ul);
return ul;
}
#endif
@@ -609,24 +535,24 @@ namespace boost
return *this;
}
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
void swap(shared_lock&& other)
{
std::swap(m,other.m);
std::swap(is_locked,other.is_locked);
}
#else
void swap(shared_lock& other)
{
std::swap(m,other.m);
std::swap(is_locked,other.is_locked);
}
void swap(boost::detail::thread_move_t<shared_lock<Mutex> > other)
{
std::swap(m,other->m);
std::swap(is_locked,other->is_locked);
}
#endif
void swap(shared_lock& other)
{
std::swap(m,other.m);
std::swap(is_locked,other.is_locked);
}
Mutex* mutex() const
{
@@ -644,7 +570,7 @@ namespace boost
{
if(owns_lock())
{
boost::throw_exception(boost::lock_error());
throw boost::lock_error();
}
m->lock_shared();
is_locked=true;
@@ -653,7 +579,7 @@ namespace boost
{
if(owns_lock())
{
boost::throw_exception(boost::lock_error());
throw boost::lock_error();
}
is_locked=m->try_lock_shared();
return is_locked;
@@ -662,7 +588,7 @@ namespace boost
{
if(owns_lock())
{
boost::throw_exception(boost::lock_error());
throw boost::lock_error();
}
is_locked=m->timed_lock_shared(target_time);
return is_locked;
@@ -672,7 +598,7 @@ namespace boost
{
if(owns_lock())
{
boost::throw_exception(boost::lock_error());
throw boost::lock_error();
}
is_locked=m->timed_lock_shared(target_time);
return is_locked;
@@ -681,7 +607,7 @@ namespace boost
{
if(!owns_lock())
{
boost::throw_exception(boost::lock_error());
throw boost::lock_error();
}
m->unlock_shared();
is_locked=false;
@@ -703,7 +629,7 @@ namespace boost
};
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
template<typename Mutex>
void swap(shared_lock<Mutex>&& lhs,shared_lock<Mutex>&& rhs)
{
@@ -747,39 +673,6 @@ namespace boost
{
try_lock();
}
#ifdef BOOST_HAS_RVALUE_REFS
upgrade_lock(upgrade_lock<Mutex>&& other):
m(other.m),is_locked(other.is_locked)
{
other.is_locked=false;
other.m=0;
}
upgrade_lock(unique_lock<Mutex>&& other):
m(other.m),is_locked(other.is_locked)
{
if(is_locked)
{
m->unlock_and_lock_upgrade();
}
other.is_locked=false;
other.m=0;
}
upgrade_lock& operator=(upgrade_lock<Mutex>&& other)
{
upgrade_lock temp(other);
swap(temp);
return *this;
}
upgrade_lock& operator=(unique_lock<Mutex>&& other)
{
upgrade_lock temp(other);
swap(temp);
return *this;
}
#else
upgrade_lock(detail::thread_move_t<upgrade_lock<Mutex> > other):
m(other->m),is_locked(other->is_locked)
{
@@ -822,7 +715,6 @@ namespace boost
swap(temp);
return *this;
}
#endif
void swap(upgrade_lock& other)
{
@@ -841,7 +733,7 @@ namespace boost
{
if(owns_lock())
{
boost::throw_exception(boost::lock_error());
throw boost::lock_error();
}
m->lock_upgrade();
is_locked=true;
@@ -850,7 +742,7 @@ namespace boost
{
if(owns_lock())
{
boost::throw_exception(boost::lock_error());
throw boost::lock_error();
}
is_locked=m->try_lock_upgrade();
return is_locked;
@@ -859,7 +751,7 @@ namespace boost
{
if(!owns_lock())
{
boost::throw_exception(boost::lock_error());
throw boost::lock_error();
}
m->unlock_upgrade();
is_locked=false;
@@ -883,7 +775,7 @@ namespace boost
};
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
template<typename Mutex>
unique_lock<Mutex>::unique_lock(upgrade_lock<Mutex>&& other):
m(other.m),is_locked(other.is_locked)
@@ -927,20 +819,6 @@ namespace boost
}
}
#ifdef BOOST_HAS_RVALUE_REFS
upgrade_to_unique_lock(upgrade_to_unique_lock<Mutex>&& other):
source(other.source),exclusive(move(other.exclusive))
{
other.source=0;
}
upgrade_to_unique_lock& operator=(upgrade_to_unique_lock<Mutex>&& other)
{
upgrade_to_unique_lock temp(other);
swap(temp);
return *this;
}
#else
upgrade_to_unique_lock(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other):
source(other->source),exclusive(move(other->exclusive))
{
@@ -953,7 +831,6 @@ namespace boost
swap(temp);
return *this;
}
#endif
void swap(upgrade_to_unique_lock& other)
{
std::swap(source,other.source);
@@ -998,7 +875,7 @@ namespace boost
try_lock_wrapper(Mutex& m_,try_to_lock_t):
base(m_,try_to_lock)
{}
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
try_lock_wrapper(try_lock_wrapper&& other):
base(other.move())
{}
@@ -1086,7 +963,7 @@ namespace boost
}
};
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
template<typename Mutex>
void swap(try_lock_wrapper<Mutex>&& lhs,try_lock_wrapper<Mutex>&& rhs)
{

View File

@@ -3,7 +3,7 @@
// 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)
// (C) Copyright 2007-10 Anthony Williams
// (C) Copyright 2007-8 Anthony Williams
#include "timespec.hpp"
#include "pthread_mutex_scoped_lock.hpp"
@@ -48,8 +48,8 @@ namespace boost
pthread_mutex_t internal_mutex;
pthread_cond_t cond;
condition_variable_any(condition_variable_any&);
condition_variable_any& operator=(condition_variable_any&);
condition_variable_any(condition_variable&);
condition_variable_any& operator=(condition_variable&);
public:
condition_variable_any()
@@ -57,13 +57,13 @@ namespace boost
int const res=pthread_mutex_init(&internal_mutex,NULL);
if(res)
{
boost::throw_exception(thread_resource_error());
throw thread_resource_error();
}
int const res2=pthread_cond_init(&cond,NULL);
if(res2)
{
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
boost::throw_exception(thread_resource_error());
throw thread_resource_error();
}
}
~condition_variable_any()
@@ -87,7 +87,7 @@ namespace boost
}
if(res)
{
boost::throw_exception(condition_error());
throw condition_error();
}
}
@@ -117,7 +117,7 @@ namespace boost
}
if(res)
{
boost::throw_exception(condition_error());
throw condition_error();
}
return true;
}

View File

@@ -6,7 +6,6 @@
// (C) Copyright 2007-8 Anthony Williams
#include <boost/assert.hpp>
#include <boost/throw_exception.hpp>
#include <pthread.h>
#include <boost/thread/mutex.hpp>
#include <boost/thread/locks.hpp>
@@ -31,7 +30,7 @@ namespace boost
int const res=pthread_cond_init(&cond,NULL);
if(res)
{
boost::throw_exception(thread_resource_error());
throw thread_resource_error();
}
}
~condition_variable()
@@ -47,8 +46,7 @@ namespace boost
while(!pred()) wait(m);
}
inline bool timed_wait(unique_lock<mutex>& m,
boost::system_time const& wait_until);
bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until);
bool timed_wait(unique_lock<mutex>& m,xtime const& wait_until)
{
return timed_wait(m,system_time(wait_until));

View File

@@ -7,7 +7,6 @@
#include <pthread.h>
#include <boost/utility.hpp>
#include <boost/throw_exception.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/thread/locks.hpp>
#include <boost/thread/thread_time.hpp>
@@ -27,11 +26,10 @@
namespace boost
{
class mutex
class mutex:
boost::noncopyable
{
private:
mutex(mutex const&);
mutex& operator=(mutex const&);
pthread_mutex_t m;
public:
mutex()
@@ -39,7 +37,7 @@ namespace boost
int const res=pthread_mutex_init(&m,NULL);
if(res)
{
boost::throw_exception(thread_resource_error());
throw thread_resource_error();
}
}
~mutex()
@@ -49,11 +47,7 @@ namespace boost
void lock()
{
int const res=pthread_mutex_lock(&m);
if(res)
{
boost::throw_exception(lock_error(res));
}
BOOST_VERIFY(!pthread_mutex_lock(&m));
}
void unlock()
@@ -64,11 +58,7 @@ namespace boost
bool try_lock()
{
int const res=pthread_mutex_trylock(&m);
if(res && (res!=EBUSY))
{
boost::throw_exception(lock_error(res));
}
BOOST_ASSERT(!res || res==EBUSY);
return !res;
}
@@ -84,11 +74,9 @@ namespace boost
typedef mutex try_mutex;
class timed_mutex
class timed_mutex:
boost::noncopyable
{
private:
timed_mutex(timed_mutex const&);
timed_mutex& operator=(timed_mutex const&);
private:
pthread_mutex_t m;
#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
@@ -101,14 +89,14 @@ namespace boost
int const res=pthread_mutex_init(&m,NULL);
if(res)
{
boost::throw_exception(thread_resource_error());
throw thread_resource_error();
}
#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
int const res2=pthread_cond_init(&cond,NULL);
if(res2)
{
BOOST_VERIFY(!pthread_mutex_destroy(&m));
boost::throw_exception(thread_resource_error());
throw thread_resource_error();
}
is_locked=false;
#endif

View File

@@ -10,7 +10,6 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/detail/config.hpp>
#include <boost/config.hpp>
#include <pthread.h>
#include <boost/assert.hpp>
@@ -59,13 +58,10 @@ namespace boost
if(flag.epoch==uninitialized_flag)
{
flag.epoch=being_initialized;
#ifndef BOOST_NO_EXCEPTIONS
try
{
#endif
pthread::pthread_mutex_scoped_unlock relocker(&detail::once_epoch_mutex);
f();
#ifndef BOOST_NO_EXCEPTIONS
}
catch(...)
{
@@ -73,7 +69,6 @@ namespace boost
BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));
throw;
}
#endif
flag.epoch=--detail::once_global_epoch;
BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));
}

View File

@@ -7,7 +7,6 @@
#include <pthread.h>
#include <boost/utility.hpp>
#include <boost/throw_exception.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/thread/locks.hpp>
#include <boost/thread/thread_time.hpp>
@@ -30,11 +29,10 @@
namespace boost
{
class recursive_mutex
class recursive_mutex:
boost::noncopyable
{
private:
recursive_mutex(recursive_mutex const&);
recursive_mutex& operator=(recursive_mutex const&);
pthread_mutex_t m;
public:
recursive_mutex()
@@ -44,18 +42,18 @@ namespace boost
int const init_attr_res=pthread_mutexattr_init(&attr);
if(init_attr_res)
{
boost::throw_exception(thread_resource_error());
throw thread_resource_error();
}
int const set_attr_res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
if(set_attr_res)
{
boost::throw_exception(thread_resource_error());
throw thread_resource_error();
}
int const res=pthread_mutex_init(&m,&attr);
if(res)
{
boost::throw_exception(thread_resource_error());
throw thread_resource_error();
}
BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
}
@@ -93,11 +91,9 @@ namespace boost
typedef recursive_mutex recursive_try_mutex;
class recursive_timed_mutex
class recursive_timed_mutex:
boost::noncopyable
{
private:
recursive_timed_mutex(recursive_timed_mutex const&);
recursive_timed_mutex& operator=(recursive_timed_mutex const&);
private:
pthread_mutex_t m;
#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
@@ -115,32 +111,32 @@ namespace boost
int const init_attr_res=pthread_mutexattr_init(&attr);
if(init_attr_res)
{
boost::throw_exception(thread_resource_error());
throw thread_resource_error();
}
int const set_attr_res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
if(set_attr_res)
{
boost::throw_exception(thread_resource_error());
throw thread_resource_error();
}
int const res=pthread_mutex_init(&m,&attr);
if(res)
{
BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
boost::throw_exception(thread_resource_error());
throw thread_resource_error();
}
BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
#else
int const res=pthread_mutex_init(&m,NULL);
if(res)
{
boost::throw_exception(thread_resource_error());
throw thread_resource_error();
}
int const res2=pthread_cond_init(&cond,NULL);
if(res2)
{
BOOST_VERIFY(!pthread_mutex_destroy(&m));
boost::throw_exception(thread_resource_error());
throw thread_resource_error();
}
is_locked=false;
count=0;

View File

@@ -225,7 +225,7 @@ namespace boost
template<typename TimeDuration>
bool timed_lock_upgrade(TimeDuration const & relative_time)
{
return timed_lock_upgrade(get_system_time()+relative_time);
return timed_lock(get_system_time()+relative_time);
}
bool try_lock_upgrade()

View File

@@ -17,7 +17,7 @@ namespace boost
return new T();
}
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
template<typename T,typename A1>
inline T* heap_new(A1&& a1)
{

View File

@@ -62,8 +62,6 @@ namespace boost
boost::shared_ptr<detail::tss_cleanup_function> cleanup;
public:
typedef T element_type;
thread_specific_ptr():
cleanup(detail::heap_new<delete_data>(),detail::do_heap_delete<delete_data>())
{}

View File

@@ -61,30 +61,15 @@ namespace boost
void lock()
{
if(try_lock())
BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel()));
}
bool timed_lock(::boost::system_time const& wait_until)
{
if(!win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit))
{
return;
return true;
}
long old_count=active_count;
mark_waiting_and_try_lock(old_count);
if(old_count&lock_flag_value)
{
bool lock_acquired=false;
void* const sem=get_event();
do
{
BOOST_VERIFY(win32::WaitForSingleObject(
sem,::boost::detail::win32::infinite)==0);
clear_waiting_and_try_lock(old_count);
lock_acquired=!(old_count&lock_flag_value);
}
while(!lock_acquired);
}
}
void mark_waiting_and_try_lock(long& old_count)
{
for(;;)
{
long const new_count=(old_count&lock_flag_value)?(old_count+1):(old_count|lock_flag_value);
@@ -95,33 +80,6 @@ namespace boost
}
old_count=current;
}
}
void clear_waiting_and_try_lock(long& old_count)
{
old_count&=~lock_flag_value;
old_count|=event_set_flag_value;
for(;;)
{
long const new_count=((old_count&lock_flag_value)?old_count:((old_count-1)|lock_flag_value))&~event_set_flag_value;
long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count);
if(current==old_count)
{
break;
}
old_count=current;
}
}
bool timed_lock(::boost::system_time const& wait_until)
{
if(try_lock())
{
return true;
}
long old_count=active_count;
mark_waiting_and_try_lock(old_count);
if(old_count&lock_flag_value)
{
@@ -135,7 +93,18 @@ namespace boost
BOOST_INTERLOCKED_DECREMENT(&active_count);
return false;
}
clear_waiting_and_try_lock(old_count);
old_count&=~lock_flag_value;
old_count|=event_set_flag_value;
for(;;)
{
long const new_count=((old_count&lock_flag_value)?old_count:((old_count-1)|lock_flag_value))&~event_set_flag_value;
long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count);
if(current==old_count)
{
break;
}
old_count=current;
}
lock_acquired=!(old_count&lock_flag_value);
}
while(!lock_acquired);

View File

@@ -20,11 +20,9 @@ namespace boost
}
class mutex:
boost::noncopyable,
public ::boost::detail::underlying_mutex
{
private:
mutex(mutex const&);
mutex& operator=(mutex const&);
public:
mutex()
{
@@ -42,11 +40,9 @@ namespace boost
typedef mutex try_mutex;
class timed_mutex:
boost::noncopyable,
public ::boost::detail::basic_timed_mutex
{
private:
timed_mutex(timed_mutex const&);
timed_mutex& operator=(timed_mutex const&);
public:
timed_mutex()
{

View File

@@ -30,47 +30,81 @@ namespace std
namespace boost
{
struct once_flag
{
long status;
long count;
long throw_count;
void* event_handle;
typedef long once_flag;
~once_flag()
{
if(count)
{
BOOST_ASSERT(count==throw_count);
}
void* const old_event=BOOST_INTERLOCKED_EXCHANGE_POINTER(&event_handle,0);
if(old_event)
{
::boost::detail::win32::CloseHandle(old_event);
}
}
};
#define BOOST_ONCE_INIT {0,0,0,0}
#define BOOST_ONCE_INIT 0
namespace detail
{
inline void* allocate_event_handle(void*& handle)
struct win32_mutex_scoped_lock
{
void* const new_handle=::boost::detail::win32::create_anonymous_event(
::boost::detail::win32::manual_reset_event,
::boost::detail::win32::event_initially_reset);
void* event_handle=BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&handle,
new_handle,0);
if(event_handle)
void* const mutex_handle;
explicit win32_mutex_scoped_lock(void* mutex_handle_):
mutex_handle(mutex_handle_)
{
::boost::detail::win32::CloseHandle(new_handle);
return event_handle;
BOOST_VERIFY(!win32::WaitForSingleObject(mutex_handle,win32::infinite));
}
return new_handle;
~win32_mutex_scoped_lock()
{
BOOST_VERIFY(win32::ReleaseMutex(mutex_handle)!=0);
}
private:
void operator=(win32_mutex_scoped_lock&);
};
#ifdef BOOST_NO_ANSI_APIS
template <class I>
void int_to_string(I p, wchar_t* buf)
{
for(unsigned i=0; i < sizeof(I)*2; ++i,++buf)
{
*buf = L'A' + static_cast<wchar_t>((p >> (i*4)) & 0x0f);
}
*buf = 0;
}
#else
template <class I>
void int_to_string(I p, char* buf)
{
for(unsigned i=0; i < sizeof(I)*2; ++i,++buf)
{
*buf = 'A' + static_cast<char>((p >> (i*4)) & 0x0f);
}
*buf = 0;
}
#endif
// create a named mutex. It doesn't really matter what this name is
// as long as it is unique both to this process, and to the address of "flag":
inline void* create_once_mutex(void* flag_address)
{
#ifdef BOOST_NO_ANSI_APIS
typedef wchar_t char_type;
static const char_type fixed_mutex_name[]=L"{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag";
#else
typedef char char_type;
static const char_type fixed_mutex_name[]="{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag";
#endif
unsigned const once_mutex_name_fixed_buffer_size=sizeof(fixed_mutex_name)/sizeof(char_type);
unsigned const once_mutex_name_fixed_length=once_mutex_name_fixed_buffer_size-1;
unsigned const once_mutex_name_length=once_mutex_name_fixed_buffer_size+sizeof(void*)*2+sizeof(unsigned long)*2;
char_type mutex_name[once_mutex_name_length];
std::memcpy(mutex_name,fixed_mutex_name,sizeof(fixed_mutex_name));
BOOST_STATIC_ASSERT(sizeof(void*) == sizeof(std::ptrdiff_t));
detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address), mutex_name + once_mutex_name_fixed_length);
detail::int_to_string(win32::GetCurrentProcessId(), mutex_name + once_mutex_name_fixed_length + sizeof(void*)*2);
#ifdef BOOST_NO_ANSI_APIS
return win32::CreateMutexW(0, 0, mutex_name);
#else
return win32::CreateMutexA(0, 0, mutex_name);
#endif
}
}
@@ -80,98 +114,18 @@ namespace boost
// Try for a quick win: if the procedure has already been called
// just skip through:
long const function_complete_flag_value=0xc15730e2;
long const running_value=0x7f0725e3;
long status;
bool counted=false;
void* event_handle=0;
long throw_count=0;
while((status=::boost::detail::interlocked_read_acquire(&flag.status))
!=function_complete_flag_value)
if(::boost::detail::interlocked_read_acquire(&flag)!=function_complete_flag_value)
{
status=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&flag.status,running_value,0);
if(!status)
void* const mutex_handle(::boost::detail::create_once_mutex(&flag));
BOOST_ASSERT(mutex_handle);
detail::win32::handle_manager const closer(mutex_handle);
detail::win32_mutex_scoped_lock const lock(mutex_handle);
if(flag!=function_complete_flag_value)
{
try
{
if(!event_handle)
{
event_handle=::boost::detail::interlocked_read_acquire(&flag.event_handle);
}
if(event_handle)
{
::boost::detail::win32::ResetEvent(event_handle);
}
f();
if(!counted)
{
BOOST_INTERLOCKED_INCREMENT(&flag.count);
counted=true;
}
BOOST_INTERLOCKED_EXCHANGE(&flag.status,function_complete_flag_value);
if(!event_handle &&
(::boost::detail::interlocked_read_acquire(&flag.count)>1))
{
event_handle=::boost::detail::allocate_event_handle(flag.event_handle);
}
if(event_handle)
{
::boost::detail::win32::SetEvent(event_handle);
}
throw_count=::boost::detail::interlocked_read_acquire(&flag.throw_count);
break;
}
catch(...)
{
if(counted)
{
BOOST_INTERLOCKED_INCREMENT(&flag.throw_count);
}
BOOST_INTERLOCKED_EXCHANGE(&flag.status,0);
if(!event_handle)
{
event_handle=::boost::detail::interlocked_read_acquire(&flag.event_handle);
}
if(event_handle)
{
::boost::detail::win32::SetEvent(event_handle);
}
throw;
}
}
if(!counted)
{
BOOST_INTERLOCKED_INCREMENT(&flag.count);
counted=true;
status=::boost::detail::interlocked_read_acquire(&flag.status);
if(status==function_complete_flag_value)
{
break;
}
event_handle=::boost::detail::interlocked_read_acquire(&flag.event_handle);
if(!event_handle)
{
event_handle=::boost::detail::allocate_event_handle(flag.event_handle);
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
event_handle,::boost::detail::win32::infinite));
}
if(counted || throw_count)
{
if(!BOOST_INTERLOCKED_EXCHANGE_ADD(&flag.count,(counted?-1:0)-throw_count))
{
if(!event_handle)
{
event_handle=::boost::detail::interlocked_read_acquire(&flag.event_handle);
}
if(event_handle)
{
BOOST_INTERLOCKED_EXCHANGE_POINTER(&flag.event_handle,0);
::boost::detail::win32::CloseHandle(event_handle);
}
f();
BOOST_INTERLOCKED_EXCHANGE(&flag,function_complete_flag_value);
}
}
}

View File

@@ -20,11 +20,9 @@
namespace boost
{
class recursive_mutex:
boost::noncopyable,
public ::boost::detail::basic_recursive_mutex
{
private:
recursive_mutex(recursive_mutex const&);
recursive_mutex& operator=(recursive_mutex const&);
public:
recursive_mutex()
{
@@ -42,11 +40,9 @@ namespace boost
typedef recursive_mutex recursive_try_mutex;
class recursive_timed_mutex:
boost::noncopyable,
public ::boost::detail::basic_recursive_timed_mutex
{
private:
recursive_timed_mutex(recursive_timed_mutex const&);
recursive_timed_mutex& operator=(recursive_timed_mutex const&);
public:
recursive_timed_mutex()
{

View File

@@ -19,11 +19,9 @@
namespace boost
{
class shared_mutex
class shared_mutex:
private boost::noncopyable
{
private:
shared_mutex(shared_mutex const&);
shared_mutex& operator=(shared_mutex const&);
private:
struct state_data
{
@@ -51,35 +49,33 @@ namespace boost
return *reinterpret_cast<T const*>(&res);
}
enum
{
unlock_sem = 0,
exclusive_sem = 1
};
state_data state;
detail::win32::handle semaphores[2];
detail::win32::handle &unlock_sem;
detail::win32::handle &exclusive_sem;
detail::win32::handle upgrade_sem;
void release_waiters(state_data old_state)
{
if(old_state.exclusive_waiting)
{
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[exclusive_sem],1,0)!=0);
BOOST_VERIFY(detail::win32::ReleaseSemaphore(exclusive_sem,1,0)!=0);
}
if(old_state.shared_waiting || old_state.exclusive_waiting)
{
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
BOOST_VERIFY(detail::win32::ReleaseSemaphore(unlock_sem,old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
}
}
public:
shared_mutex()
shared_mutex():
unlock_sem(semaphores[0]),
exclusive_sem(semaphores[1])
{
semaphores[unlock_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
semaphores[exclusive_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
unlock_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
exclusive_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
upgrade_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
state_data state_={0};
state=state_;
@@ -88,8 +84,8 @@ namespace boost
~shared_mutex()
{
detail::win32::CloseHandle(upgrade_sem);
detail::win32::CloseHandle(semaphores[unlock_sem]);
detail::win32::CloseHandle(semaphores[exclusive_sem]);
detail::win32::CloseHandle(unlock_sem);
detail::win32::CloseHandle(exclusive_sem);
}
bool try_lock_shared()
@@ -101,10 +97,6 @@ namespace boost
if(!new_state.exclusive && !new_state.exclusive_waiting_blocked)
{
++new_state.shared_count;
if(!new_state.shared_count)
{
return false;
}
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
@@ -139,18 +131,10 @@ namespace boost
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
{
++new_state.shared_waiting;
if(!new_state.shared_waiting)
{
boost::throw_exception(boost::lock_error());
}
}
else
{
++new_state.shared_count;
if(!new_state.shared_count)
{
boost::throw_exception(boost::lock_error());
}
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
@@ -166,7 +150,7 @@ namespace boost
return true;
}
unsigned long const res=detail::win32::WaitForSingleObject(semaphores[unlock_sem],::boost::detail::get_milliseconds_until(wait_until));
unsigned long const res=detail::win32::WaitForSingleObject(unlock_sem,::boost::detail::get_milliseconds_until(wait_until));
if(res==detail::win32::timeout)
{
for(;;)
@@ -182,10 +166,6 @@ namespace boost
else
{
++new_state.shared_count;
if(!new_state.shared_count)
{
return false;
}
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
@@ -302,11 +282,6 @@ namespace boost
if(new_state.shared_count || new_state.exclusive)
{
++new_state.exclusive_waiting;
if(!new_state.exclusive_waiting)
{
boost::throw_exception(boost::lock_error());
}
new_state.exclusive_waiting_blocked=true;
}
else
@@ -399,18 +374,10 @@ namespace boost
if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade)
{
++new_state.shared_waiting;
if(!new_state.shared_waiting)
{
boost::throw_exception(boost::lock_error());
}
}
else
{
++new_state.shared_count;
if(!new_state.shared_count)
{
boost::throw_exception(boost::lock_error());
}
new_state.upgrade=true;
}
@@ -427,7 +394,7 @@ namespace boost
return;
}
BOOST_VERIFY(!detail::win32::WaitForSingleObject(semaphores[unlock_sem],detail::win32::infinite));
BOOST_VERIFY(!detail::win32::WaitForSingleObject(unlock_sem,detail::win32::infinite));
}
}
@@ -444,10 +411,6 @@ namespace boost
else
{
++new_state.shared_count;
if(!new_state.shared_count)
{
return false;
}
new_state.upgrade=true;
}

View File

@@ -144,11 +144,6 @@ namespace boost
start(0),milliseconds(~uintmax_t(0)),relative(true)
{}
};
inline unsigned long pin_to_zero(long value)
{
return (value<0)?0u:(unsigned long)value;
}
}
namespace this_thread
@@ -168,7 +163,7 @@ namespace boost
template<typename TimeDuration>
inline void sleep(TimeDuration const& rel_time)
{
interruptible_wait(detail::pin_to_zero(rel_time.total_milliseconds()));
interruptible_wait(static_cast<unsigned long>(rel_time.total_milliseconds()));
}
inline void sleep(system_time const& abs_time)
{

View File

@@ -8,7 +8,6 @@
#include "thread_primitives.hpp"
#include <stdexcept>
#include <boost/assert.hpp>
#include <boost/throw_exception.hpp>
#if defined( BOOST_USE_WINDOWS_H )
# include <windows.h>
@@ -61,7 +60,7 @@ namespace boost
void* const heap_memory=detail::win32::HeapAlloc(detail::win32::GetProcessHeap(),0,size);
if(!heap_memory)
{
boost::throw_exception(std::bad_alloc());
throw std::bad_alloc();
}
return heap_memory;
}
@@ -87,7 +86,7 @@ namespace boost
}
}
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
template<typename T,typename A1>
inline T* heap_new(A1&& a1)
{

View File

@@ -11,7 +11,6 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
#include <boost/throw_exception.hpp>
#include <boost/assert.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/detail/interlocked.hpp>
@@ -178,7 +177,7 @@ namespace boost
#endif
if(!res)
{
boost::throw_exception(thread_resource_error());
throw thread_resource_error();
}
return res;
}
@@ -192,7 +191,7 @@ namespace boost
#endif
if(!res)
{
boost::throw_exception(thread_resource_error());
throw thread_resource_error();
}
return res;
}
@@ -205,7 +204,7 @@ namespace boost
bool const success=DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0;
if(!success)
{
boost::throw_exception(thread_resource_error());
throw thread_resource_error();
}
return new_handle;
}

View File

@@ -13,7 +13,6 @@
#include <boost/thread/locks.hpp>
#include <boost/thread/once.hpp>
#include <boost/thread/tss.hpp>
#include <boost/throw_exception.hpp>
#ifdef __linux__
#include <sys/sysinfo.h>
#elif defined(__APPLE__) || defined(__FreeBSD__)
@@ -75,7 +74,7 @@ namespace boost
{
current=next;
++next;
if(current->second.func && (current->second.value!=0))
if(current->second.func && current->second.value)
{
(*current->second.func)(current->second.value);
}
@@ -187,7 +186,7 @@ namespace boost
if (res != 0)
{
thread_info->self.reset();
boost::throw_exception(thread_resource_error());
throw thread_resource_error();
}
}
@@ -381,12 +380,12 @@ namespace boost
{
#if defined(PTW32_VERSION) || defined(__hpux)
return pthread_num_processors_np();
#elif defined(_GNU_SOURCE)
return get_nprocs();
#elif defined(__APPLE__) || defined(__FreeBSD__)
int count;
size_t size=sizeof(count);
return sysctlbyname("hw.ncpu",&count,&size,NULL,0)?0:count;
#elif defined(_GNU_SOURCE)
return get_nprocs();
#elif defined(BOOST_HAS_UNISTD_H) && defined(_SC_NPROCESSORS_ONLN)
int const count=sysconf(_SC_NPROCESSORS_ONLN);
return (count>0)?count:0;
@@ -582,11 +581,11 @@ namespace boost
{
if(tss_data_node* const current_node=find_tss_data(key))
{
if(cleanup_existing && current_node->func && (current_node->value!=0))
if(cleanup_existing && current_node->func && current_node->value)
{
(*current_node->func)(current_node->value);
}
if(func || (tss_data!=0))
if(func || tss_data)
{
current_node->func=func;
current_node->value=tss_data;

View File

@@ -1,14 +1,11 @@
// Copyright (C) 2001-2003
// William E. Kempf
// Copyright (C) 2009 Anthony Williams
//
// 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)
// boostinspect:nounnamed
#include <boost/assert.hpp>
namespace {
const int MILLISECONDS_PER_SECOND = 1000;
const int NANOSECONDS_PER_SECOND = 1000000000;
@@ -21,7 +18,7 @@ inline void to_time(int milliseconds, boost::xtime& xt)
{
int res = 0;
res = boost::xtime_get(&xt, boost::TIME_UTC);
BOOST_ASSERT(res == boost::TIME_UTC);
assert(res == boost::TIME_UTC);
xt.sec += (milliseconds / MILLISECONDS_PER_SECOND);
xt.nsec += ((milliseconds % MILLISECONDS_PER_SECOND) *
@@ -58,7 +55,7 @@ inline void to_timespec_duration(const boost::xtime& xt, timespec& ts)
boost::xtime cur;
int res = 0;
res = boost::xtime_get(&cur, boost::TIME_UTC);
BOOST_ASSERT(res == boost::TIME_UTC);
assert(res == boost::TIME_UTC);
if (boost::xtime_cmp(xt, cur) <= 0)
{
@@ -89,7 +86,7 @@ inline void to_duration(boost::xtime xt, int& milliseconds)
boost::xtime cur;
int res = 0;
res = boost::xtime_get(&cur, boost::TIME_UTC);
BOOST_ASSERT(res == boost::TIME_UTC);
assert(res == boost::TIME_UTC);
if (boost::xtime_cmp(xt, cur) <= 0)
milliseconds = 0;
@@ -111,7 +108,7 @@ inline void to_microduration(boost::xtime xt, int& microseconds)
boost::xtime cur;
int res = 0;
res = boost::xtime_get(&cur, boost::TIME_UTC);
BOOST_ASSERT(res == boost::TIME_UTC);
assert(res == boost::TIME_UTC);
if (boost::xtime_cmp(xt, cur) <= 0)
microseconds = 0;

View File

@@ -17,7 +17,6 @@
#include <boost/thread/once.hpp>
#include <boost/thread/tss.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>
@@ -189,7 +188,7 @@ namespace boost
uintptr_t const new_thread=_beginthreadex(0,0,&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id);
if(!new_thread)
{
boost::throw_exception(thread_resource_error());
throw thread_resource_error();
}
intrusive_ptr_add_ref(thread_info.get());
thread_info->thread_handle=(detail::win32::handle)(new_thread);
@@ -304,7 +303,7 @@ namespace boost
unsigned thread::hardware_concurrency()
{
SYSTEM_INFO info={{0}};
SYSTEM_INFO info={0};
GetSystemInfo(&info);
return info.dwNumberOfProcessors;
}
@@ -327,7 +326,7 @@ namespace boost
{
LARGE_INTEGER get_due_time(detail::timeout const& target_time)
{
LARGE_INTEGER due_time={{0}};
LARGE_INTEGER due_time={0};
if(target_time.relative)
{
unsigned long const elapsed_milliseconds=GetTickCount()-target_time.start;
@@ -356,23 +355,7 @@ namespace boost
else
{
long const hundred_nanoseconds_in_one_second=10000000;
posix_time::time_duration::tick_type const ticks_per_second=
target_time.abs_time.time_of_day().ticks_per_second();
if(ticks_per_second>hundred_nanoseconds_in_one_second)
{
posix_time::time_duration::tick_type const
ticks_per_hundred_nanoseconds=
ticks_per_second/hundred_nanoseconds_in_one_second;
due_time.QuadPart+=
target_time.abs_time.time_of_day().fractional_seconds()/
ticks_per_hundred_nanoseconds;
}
else
{
due_time.QuadPart+=
target_time.abs_time.time_of_day().fractional_seconds()*
(hundred_nanoseconds_in_one_second/ticks_per_second);
}
due_time.QuadPart+=target_time.abs_time.time_of_day().fractional_seconds()*(hundred_nanoseconds_in_one_second/target_time.abs_time.time_of_day().ticks_per_second());
}
}
return due_time;
@@ -593,22 +576,22 @@ namespace boost
}
}
}
BOOST_THREAD_DECL void __cdecl on_process_enter()
{}
BOOST_THREAD_DECL void __cdecl on_thread_enter()
{}
BOOST_THREAD_DECL void __cdecl on_process_exit()
{
boost::cleanup_tls_key();
}
BOOST_THREAD_DECL void __cdecl on_thread_exit()
{
boost::run_thread_exit_callbacks();
}
}
extern "C" BOOST_THREAD_DECL void on_process_enter()
{}
extern "C" BOOST_THREAD_DECL void on_thread_enter()
{}
extern "C" BOOST_THREAD_DECL void on_process_exit()
{
boost::cleanup_tls_key();
}
extern "C" BOOST_THREAD_DECL void on_thread_exit()
{
boost::run_thread_exit_callbacks();
}

View File

@@ -24,27 +24,27 @@
{
case DLL_PROCESS_ATTACH:
{
boost::on_process_enter();
boost::on_thread_enter();
on_process_enter();
on_thread_enter();
break;
}
case DLL_THREAD_ATTACH:
{
boost::on_thread_enter();
on_thread_enter();
break;
}
case DLL_THREAD_DETACH:
{
boost::on_thread_exit();
on_thread_exit();
break;
}
case DLL_PROCESS_DETACH:
{
boost::on_thread_exit();
boost::on_process_exit();
on_thread_exit();
on_process_exit();
break;
}
}
@@ -52,9 +52,7 @@
return TRUE;
}
namespace boost
{
void tss_cleanup_implemented()
extern "C" void tss_cleanup_implemented(void)
{
/*
This function's sole purpose is to cause a link error in cases where
@@ -70,7 +68,5 @@ namespace boost
longer needed and can be removed.
*/
}
}
#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_DLL)

View File

@@ -19,10 +19,7 @@
#include <cstdlib>
namespace boost
{
void tss_cleanup_implemented() {}
}
extern "C" void tss_cleanup_implemented(void) {}
namespace {
void NTAPI on_tls_callback(void* h, DWORD dwReason, PVOID pv)
@@ -31,18 +28,33 @@ namespace {
{
case DLL_THREAD_DETACH:
{
boost::on_thread_exit();
on_thread_exit();
break;
}
}
}
void on_after_ctors(void)
{
on_process_enter();
}
void on_before_dtors(void)
{
on_thread_exit();
}
void on_after_dtors(void)
{
on_process_exit();
}
}
extern "C" {
void (* after_ctors )(void) __attribute__((section(".ctors"))) = boost::on_process_enter;
void (* before_dtors)(void) __attribute__((section(".dtors"))) = boost::on_thread_exit;
void (* after_dtors )(void) __attribute__((section(".dtors.zzz"))) = boost::on_process_exit;
void (* after_ctors )(void) __attribute__((section(".ctors"))) = on_after_ctors;
void (* before_dtors)(void) __attribute__((section(".dtors"))) = on_before_dtors;
void (* after_dtors )(void) __attribute__((section(".dtors.zzz"))) = on_after_dtors;
ULONG __tls_index__ = 0;
char __tls_end__ __attribute__((section(".tls$zzz"))) = 0;
@@ -209,18 +221,18 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
//for destructors of global objects, so that
//shouldn't be a problem.
atexit(boost::on_thread_exit);
atexit(on_thread_exit);
//Call Boost process entry callback here
boost::on_process_enter();
on_process_enter();
return INIRETSUCCESS;
}
PVAPI on_process_term(void)
{
boost::on_process_exit();
on_process_exit();
return INIRETSUCCESS;
}
@@ -229,7 +241,7 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
switch (dwReason)
{
case DLL_THREAD_DETACH:
boost::on_thread_exit();
on_thread_exit();
break;
}
}
@@ -239,10 +251,10 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
switch (dwReason)
{
case DLL_THREAD_DETACH:
boost::on_thread_exit();
on_thread_exit();
break;
case DLL_PROCESS_DETACH:
boost::on_process_exit();
on_process_exit();
break;
}
return true;
@@ -253,9 +265,8 @@ extern "C"
{
extern BOOL (WINAPI * const _pRawDllMain)(HANDLE, DWORD, LPVOID)=&dll_callback;
}
namespace boost
{
void tss_cleanup_implemented()
extern "C" void tss_cleanup_implemented(void)
{
/*
This function's sole purpose is to cause a link error in cases where
@@ -271,8 +282,6 @@ namespace boost
longer needed and can be removed.
*/
}
}
#endif //defined(_MSC_VER) && !defined(UNDER_CE)
#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB)

View File

@@ -42,7 +42,6 @@ rule thread-run ( sources )
[ thread-run test_thread_move_return.cpp ]
[ thread-run test_thread_launching.cpp ]
[ thread-run test_thread_mf.cpp ]
[ thread-run test_thread_exit.cpp ]
[ thread-run test_move_function.cpp ]
[ thread-run test_mutex.cpp ]
[ thread-run test_condition_notify_one.cpp ]

View File

@@ -1,4 +1,4 @@
// (C) Copyright 2008-10 Anthony Williams
// (C) Copyright 2008-9 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -14,7 +14,7 @@
#include <boost/test/unit_test.hpp>
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
template<typename T>
typename boost::remove_reference<T>::type&& cast_to_rval(T&& t)
{
@@ -41,7 +41,7 @@ public:
X():
i(42)
{}
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
X(X&& other):
i(other.i)
{
@@ -89,7 +89,7 @@ void set_promise_exception_thread(boost::promise<int>* p)
void test_store_value_from_thread()
{
boost::promise<int> pi2;
boost::unique_future<int> fi2(pi2.get_future());
boost::unique_future<int> fi2=pi2.get_future();
boost::thread(set_promise_thread,&pi2);
int j=fi2.get();
BOOST_CHECK(j==42);

View File

@@ -296,80 +296,10 @@ void test_lock_five_in_range()
}
}
class dummy_iterator:
public std::iterator<std::forward_iterator_tag,
dummy_mutex>
{
private:
dummy_mutex* p;
public:
explicit dummy_iterator(dummy_mutex* p_):
p(p_)
{}
bool operator==(dummy_iterator const& other) const
{
return p==other.p;
}
bool operator!=(dummy_iterator const& other) const
{
return p!=other.p;
}
bool operator<(dummy_iterator const& other) const
{
return p<other.p;
}
dummy_mutex& operator*() const
{
return *p;
}
dummy_mutex* operator->() const
{
return p;
}
dummy_iterator operator++(int)
{
dummy_iterator temp(*this);
++p;
return temp;
}
dummy_iterator& operator++()
{
++p;
return *this;
}
};
void test_lock_five_in_range_custom_iterator()
{
unsigned const num_mutexes=5;
dummy_mutex mutexes[num_mutexes];
boost::lock(dummy_iterator(mutexes),dummy_iterator(mutexes+num_mutexes));
for(unsigned i=0;i<num_mutexes;++i)
{
BOOST_CHECK(mutexes[i].is_locked);
}
}
class dummy_mutex2:
public dummy_mutex
{};
void test_lock_ten_in_range_inherited_mutex()
void test_lock_ten_in_range()
{
unsigned const num_mutexes=10;
dummy_mutex2 mutexes[num_mutexes];
dummy_mutex mutexes[num_mutexes];
boost::lock(mutexes,mutexes+num_mutexes);
@@ -580,8 +510,7 @@ boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
test->add(BOOST_TEST_CASE(&test_lock_five_other_thread_locks_in_order));
test->add(BOOST_TEST_CASE(&test_lock_five_other_thread_locks_in_different_order));
test->add(BOOST_TEST_CASE(&test_lock_five_in_range));
test->add(BOOST_TEST_CASE(&test_lock_five_in_range_custom_iterator));
test->add(BOOST_TEST_CASE(&test_lock_ten_in_range_inherited_mutex));
test->add(BOOST_TEST_CASE(&test_lock_ten_in_range));
test->add(BOOST_TEST_CASE(&test_lock_ten_other_thread_locks_in_different_order));
test->add(BOOST_TEST_CASE(&test_try_lock_two_uncontended));
test->add(BOOST_TEST_CASE(&test_try_lock_two_first_locked));

View File

@@ -1,73 +0,0 @@
// (C) Copyright 2009 Anthony Williams
//
// 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/thread.hpp"
#include "boost/thread/mutex.hpp"
#include "boost/thread/condition.hpp"
#include "boost/thread/future.hpp"
#include <utility>
#include <memory>
#include <string>
#include <boost/test/unit_test.hpp>
boost::thread::id exit_func_thread_id;
void exit_func()
{
exit_func_thread_id=boost::this_thread::get_id();
}
void tf1()
{
boost::this_thread::at_thread_exit(exit_func);
BOOST_CHECK(exit_func_thread_id!=boost::this_thread::get_id());
}
void test_thread_exit_func_runs_when_thread_exits()
{
exit_func_thread_id=boost::thread::id();
boost::thread t(tf1);
boost::thread::id const t_id=t.get_id();
t.join();
BOOST_CHECK(exit_func_thread_id==t_id);
}
struct fo
{
void operator()()
{
exit_func_thread_id=boost::this_thread::get_id();
}
};
void tf2()
{
boost::this_thread::at_thread_exit(fo());
BOOST_CHECK(exit_func_thread_id!=boost::this_thread::get_id());
}
void test_can_use_function_object_for_exit_func()
{
exit_func_thread_id=boost::thread::id();
boost::thread t(tf2);
boost::thread::id const t_id=t.get_id();
t.join();
BOOST_CHECK(exit_func_thread_id==t_id);
}
boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
{
boost::unit_test_framework::test_suite* test =
BOOST_TEST_SUITE("Boost.Threads: futures test suite");
test->add(BOOST_TEST_CASE(test_thread_exit_func_runs_when_thread_exits));
test->add(BOOST_TEST_CASE(test_can_use_function_object_for_exit_func));
return test;
}