2
0
mirror of https://github.com/boostorg/thread.git synced 2026-02-03 09:42:16 +00:00

Compare commits

..

187 Commits

Author SHA1 Message Date
Vladimir Prus
4b5296a4cc Branch for merging Boost.Build and Boost.Jam completely.
[SVN r59143]
2010-01-19 20:47:20 +00:00
Anthony Williams
174d701bc3 Using BOOST_ASSERT rather than assert
[SVN r57940]
2009-11-26 09:35:31 +00:00
Anthony Williams
f2143d08b9 Added missing BOOST_THREAD_DECL for at_thread_exit_function
[SVN r57937]
2009-11-26 08:13:44 +00:00
Anthony Williams
1273e2620d Don't use timed_lock to do a lock
[SVN r57936]
2009-11-26 08:13:01 +00:00
Anthony Williams
c719f6e37e Added test and fix for issue 2742
[SVN r57925]
2009-11-25 11:05:55 +00:00
Anthony Williams
37922d8ce0 Added a wait call to new call_once
[SVN r57924]
2009-11-25 09:42:29 +00:00
Anthony Williams
7b79a31f40 A partial fix for issue #2100: use boost::throw_exception for all exceptions except thread_interrupted
[SVN r57912]
2009-11-24 21:49:27 +00:00
Anthony Williams
9a09406f77 Ensure call_once event is correctly cleaned up
[SVN r57889]
2009-11-24 11:52:09 +00:00
Anthony Williams
9bdb778478 Only allocate an event if there is contention in call_once
[SVN r57882]
2009-11-24 09:59:21 +00:00
Anthony Williams
9621dafe46 Clarify note on call_once
[SVN r57862]
2009-11-23 11:31:08 +00:00
Anthony Williams
d7c9837844 Added a note highlighting that recursive use of call_once will cause deadlock.
[SVN r57861]
2009-11-23 11:24:53 +00:00
Anthony Williams
27bb7803ae Update docs for at_thread_exit
[SVN r57380]
2009-11-04 21:38:45 +00:00
Anthony Williams
c0e1086f2c More fixes for compilers with rvalue ref support
[SVN r57173]
2009-10-27 13:22:08 +00:00
Anthony Williams
ffa751c617 Fix for move assignment of unique_lock if rvalue refs supported
[SVN r57171]
2009-10-27 10:40:57 +00:00
Anthony Williams
b8ad60a2d6 Fix for bug #2067 --- use shared_mutex for thread_group rather than a simple mutex
[SVN r57169]
2009-10-27 09:45:53 +00:00
Anthony Williams
5db0aac816 Added futures to boost.thread
[SVN r57064]
2009-10-22 09:33:21 +00:00
Troy D. Straszheim
3fae7c5184 rm cmake from trunk. I'm not entirely sure this is necessary to satisfy the inspect script, but I'm not taking any chances, and it is easy to put back
[SVN r56942]
2009-10-17 02:07:38 +00:00
Anthony Williams
47889a8f22 boost.thread exception types are now header-only so some uses of boost.thread can be header only
[SVN r56019]
2009-09-04 19:55:31 +00:00
Troy D. Straszheim
8d22c3869b Copyrights on CMakeLists.txt to keep them from clogging up the inspect
reports.  This is essentially the same commit as r55095 on the release
branch.



[SVN r55159]
2009-07-26 00:49:56 +00:00
Vladimir Prus
235ed4afe0 Check _GNU_SOURCE before using get_nprocs.
The latter function is not POSIX, but a GNU extension and therefore
not available universally.


[SVN r54408]
2009-06-27 09:22:41 +00:00
Anthony Williams
627cb7f774 Fixed typo
[SVN r53412]
2009-05-29 20:48:07 +00:00
Anthony Williams
09021af350 Changed thread_specific_ptr to use a map for faster lookup, and erase empty nodes
[SVN r53389]
2009-05-29 11:34:25 +00:00
Anthony Williams
31c280d1fa TSS cleanup not called for NULL data
[SVN r53388]
2009-05-29 11:05:01 +00:00
Anthony Williams
629f344f34 Test and fix for first part of issue #2797
[SVN r53387]
2009-05-29 10:57:39 +00:00
Anthony Williams
db5f924e24 Remove commented-out thread_group code
[SVN r53386]
2009-05-29 10:45:06 +00:00
Anthony Williams
9be3eb282a Attempts to improve the boost::thread move semantics; separated tests to give clearer ID; incorporated patch to fix issue #2062
[SVN r53385]
2009-05-29 09:57:15 +00:00
John Maddock
effd891a16 Remove options that are no longer required and get the PDF docs building.
[SVN r51142]
2009-02-09 16:26:26 +00:00
Anthony Williams
13db35cbf5 Undo commit from r49977 which added extraneous throw to thread example
[SVN r49978]
2008-11-28 11:01:21 +00:00
Anthony Williams
0f2d480e3c Added test for making std::thread work with std::vector
[SVN r49977]
2008-11-28 10:57:12 +00:00
Anthony Williams
9edc61e37b Removed controversial catch(...) clauses from thread class
[SVN r49969]
2008-11-27 21:15:37 +00:00
Michael A. Jackson
f4dab6aac5 Updating CMake files to latest trunk. Added dependency information for regression tests and a few new macros for internal use.
[SVN r49627]
2008-11-07 17:02:56 +00:00
Michael A. Jackson
9e0550d140 Continuing merge of CMake build system files into trunk with the encouragement of Doug Gregor
[SVN r49510]
2008-11-01 13:15:41 +00:00
Anthony Williams
0d1701c509 Enhanced thread move tests
[SVN r49124]
2008-10-03 07:02:57 +00:00
Anthony Williams
f2f62f93ea Test and fix for trac issue #2380: return boost::move(some_thread) now works
[SVN r49112]
2008-10-02 16:39:03 +00:00
Anthony Williams
8a329f66fb Renamed lock variables to lk to avoid name shadow warnings
[SVN r49013]
2008-09-29 16:32:24 +00:00
Anthony Williams
05d4c52918 fixed check on return code from pthread_mutex_timedlock
[SVN r48997]
2008-09-29 09:04:13 +00:00
Anthony Williams
8fd0dd0cc0 Define a raw DLL main which is called by the C runtime if we're statically linked into a DLL --- fix for issue #2199
[SVN r48537]
2008-09-02 16:56:57 +00:00
Anthony Williams
8eea5811ba Don't allocate TLS Key unless we need it; deallocate it on process exit --- partial fix for bug #2199
[SVN r48536]
2008-09-02 16:54:56 +00:00
Anthony Williams
a154c2adab Removed locked and get_active_count
[SVN r48531]
2008-09-02 10:38:17 +00:00
Anthony Williams
10bf4ed576 Removed locked and get_active_count
[SVN r48530]
2008-09-02 10:38:04 +00:00
Anthony Williams
60d12dd395 Added recursive_mutex/condition::wait() change to list of breaking changes
[SVN r48528]
2008-09-02 10:22:06 +00:00
Anthony Williams
b4e9be3c52 Added missing relative time constructor to unique_lock
[SVN r48213]
2008-08-19 10:26:53 +00:00
Anthony Williams
dcebae6d4a Renamed internal bind stuff to invoker, as more expressive
[SVN r48209]
2008-08-19 07:03:22 +00:00
Anthony Williams
0d776bcd26 Updated changes list
[SVN r48037]
2008-08-08 20:37:30 +00:00
Anthony Williams
2d6ed47cf2 Updated signature of create_thread
[SVN r48036]
2008-08-08 20:21:29 +00:00
Anthony Williams
ea06434425 Doc updates missed by previous checkin
[SVN r47826]
2008-07-26 08:37:55 +00:00
Anthony Williams
6508eff95e Added note about max number of arguments
[SVN r47818]
2008-07-25 22:22:58 +00:00
Anthony Williams
69930684a9 Added a description for the new thread constructors that allow functions with arguments.
[SVN r47817]
2008-07-25 22:21:05 +00:00
Anthony Williams
b1931a3eda Fix for trac issue #2118
[SVN r47816]
2008-07-25 22:01:04 +00:00
Anthony Williams
63b44d4e32 Added documentation for the lock and try_lock free functions
[SVN r47815]
2008-07-25 21:57:33 +00:00
Anthony Williams
f7cb8d8141 Added a description for the scoped_try_lock typedefs
[SVN r47814]
2008-07-25 21:30:37 +00:00
Anthony Williams
48c857e02c Fix for issue #2105: specify which header to include for each class or function
[SVN r47810]
2008-07-25 21:12:29 +00:00
Anthony Williams
442dc58e0f Use sysconf(_SC_NPROCESSORS_ONLN) where it is available, as a fallback
[SVN r47654]
2008-07-21 10:39:50 +00:00
Anthony Williams
25460c652c Use sysconf to detect number of processors on AIX too
[SVN r47653]
2008-07-21 10:25:08 +00:00
Anthony Williams
31a98f0a1e BOOST_NO_SFINAE isn't enough to identify compilers that can't auto-detect mutexes, so create a new macro for that, and add IBM and Sun compilers to list
[SVN r47652]
2008-07-21 10:04:26 +00:00
Anthony Williams
36c44b6f45 Borland-specific fixes should apply to all compilers for which enable_if is broken: check for BOOST_NO_SFINAE instead
[SVN r47554]
2008-07-18 13:42:10 +00:00
Anthony Williams
27426b18d1 Split lock and try_lock into mutex and range overloads without using enable_if, so it works on Borland compilers
[SVN r47472]
2008-07-16 14:41:09 +00:00
Anthony Williams
3ea9ce1c8c Fixes to make basic thread functionality work with Borland compilers again
[SVN r47471]
2008-07-16 13:19:43 +00:00
Anthony Williams
4dfc636c84 test and fix for issue #2080
[SVN r47199]
2008-07-07 22:19:28 +00:00
Anthony Williams
5fe4312c6c test and fix for issue #2081
[SVN r47197]
2008-07-07 22:04:10 +00:00
Anthony Williams
63e675a6bb Corrected description to avoid reference to arguments
[SVN r47172]
2008-07-07 07:30:27 +00:00
Anthony Williams
e92aeac7d7 Added notify functions to class synopsis
[SVN r47171]
2008-07-07 07:28:32 +00:00
Anthony Williams
f1f7eac1f2 Backwards compatibility with xtime --- test and fix for issue #2052
[SVN r47149]
2008-07-06 21:58:11 +00:00
Anthony Williams
eff0c84553 Test and fix for issue #2076
[SVN r47120]
2008-07-05 21:55:36 +00:00
Anthony Williams
58c8ce61c7 Fix for issue #2065
[SVN r47077]
2008-07-04 15:45:52 +00:00
Anthony Williams
6ac5e6953a Qualify everything with boost:: to try and avoid name clashes on AIX
[SVN r47070]
2008-07-04 07:30:35 +00:00
Anthony Williams
5d9ad59af2 Use rvalue refs for move semantics of unique_lock where available
[SVN r47033]
2008-07-03 09:16:49 +00:00
Anthony Williams
3c48a05437 Added try_lock_upgrade to shared_mutex: second half of #1867 fix
[SVN r46961]
2008-07-01 16:28:06 +00:00
Anthony Williams
4462124ff2 Added try_lock_upgrade to shared_mutex: second half of #1867 fix
[SVN r46960]
2008-07-01 16:27:59 +00:00
Anthony Williams
373f557ef7 Reduced thread counts to make tests run faster
[SVN r46958]
2008-07-01 16:22:47 +00:00
Anthony Williams
495e561398 Partial fix for issue #1867 - ensure boost::shared_mutex supports try_lock
[SVN r46956]
2008-07-01 16:04:51 +00:00
Anthony Williams
d24a579033 Partial fix for issue #1867 - ensure boost::shared_mutex supports try_lock
[SVN r46955]
2008-07-01 16:04:43 +00:00
Anthony Williams
77130424b4 Removed tabs from source files
[SVN r46706]
2008-06-26 06:43:30 +00:00
Anthony Williams
eb30688937 Added license and copyright to docs
[SVN r46705]
2008-06-26 06:41:00 +00:00
Anthony Williams
880bac0633 Added missing include of detail/config.hpp
[SVN r46624]
2008-06-23 12:14:58 +00:00
Anthony Williams
851d6a987f Correctly remove the reference type when copying the thread function into the thread data area so we don't end up with a dangling reference
[SVN r46295]
2008-06-10 15:29:35 +00:00
Anthony Williams
9bebd7b35f Disable general templated thread constructor for movable types, in order to prevent it trying to act as a thread copy constructor for EDG based compilers
[SVN r46273]
2008-06-09 14:00:03 +00:00
Anthony Williams
309acb9597 Don't try and use _interlockedbittestandset primitives if we don't know they're present
[SVN r46219]
2008-06-07 20:54:19 +00:00
Anthony Williams
a56887167e Added swap for try_lock_wrapper
[SVN r46164]
2008-06-05 12:25:58 +00:00
Anthony Williams
e984dff4e4 Combined TSS header for pthread and win32, #1958 now fixed for pthread too
[SVN r46162]
2008-06-05 11:19:06 +00:00
Anthony Williams
685e4d446b Test and fix for bug #1958 on Win32
[SVN r46161]
2008-06-05 11:16:05 +00:00
Anthony Williams
8af680f307 Added swap for unique_lock
[SVN r46160]
2008-06-05 10:39:08 +00:00
Anthony Williams
6c60cce60d Removed partial initializer for res: both values will be assigned later, so no need to initialize either
[SVN r46124]
2008-06-04 16:05:29 +00:00
Anthony Williams
5882a675bb Added extra initializer to timeout to try and eliminate warnings with some compilers
[SVN r46123]
2008-06-04 16:03:51 +00:00
Anthony Williams
a5e95845b3 Added documentation for swap()
[SVN r46122]
2008-06-04 16:00:13 +00:00
Anthony Williams
5b83d81e40 Added free function swap() for threads
[SVN r46121]
2008-06-04 15:50:34 +00:00
Anthony Williams
c8e5ad564d basic_condition_variable::lock_entry extracted to basic_cv_lock_entry in order to try and eliminate problems on Borland compiler
[SVN r46094]
2008-06-03 20:56:39 +00:00
Anthony Williams
5edfa273ff removed unused header
[SVN r46093]
2008-06-03 20:55:40 +00:00
Anthony Williams
4db57bcb10 Move thread_data to detail namespace rather than have it as a nested type of boost::thread, to try and help compilers that have problems with the partial specializations for reference_wrapper
[SVN r45912]
2008-05-29 15:38:08 +00:00
Anthony Williams
3f13340903 Don't construct function objects directly in boost::thread constructor as some compilers can't handle that.
[SVN r45911]
2008-05-29 15:36:52 +00:00
Anthony Williams
6abb53c9d3 Move definition of constructor and destructor of condition_variable into condition_variable_fwd.hpp, so they are always available
[SVN r45909]
2008-05-29 15:16:55 +00:00
Anthony Williams
fdd20a519e Use wrapper functions in try_lock_wrapper rather than using declarations, as the latter confuse some compilers
[SVN r45908]
2008-05-29 15:16:04 +00:00
Anthony Williams
67cc49f333 More tests for generic locks, and a new range version
[SVN r45897]
2008-05-29 09:02:05 +00:00
Anthony Williams
31a34cd0b5 Added missing "no"
[SVN r45870]
2008-05-28 14:50:25 +00:00
Anthony Williams
ef8c08ba99 Removed surplus "the"
[SVN r45869]
2008-05-28 12:55:30 +00:00
Anthony Williams
2991ca6c6f Added abi prefix and suffix headers
[SVN r45865]
2008-05-28 11:02:06 +00:00
Anthony Williams
52bace18b2 hardware_concurrency works for CYGWIN
[SVN r45860]
2008-05-28 09:38:14 +00:00
Anthony Williams
767d14ae4f Added documentation for time support in the thread library
[SVN r45859]
2008-05-28 09:00:32 +00:00
Anthony Williams
1a5c911e36 Added documentation for time support in the thread library
[SVN r45858]
2008-05-28 09:00:23 +00:00
Anthony Williams
6e42a04e43 Added note about move support
[SVN r45856]
2008-05-28 08:09:07 +00:00
Anthony Williams
28be2cfeef intrusive_ptr_add_ref and intrusive_ptr_release need to be inline if defined in the header
[SVN r45809]
2008-05-27 06:32:05 +00:00
Anthony Williams
8be168fd87 Basic tests for lock() when other thread is acquiring locks in same or opposite order
[SVN r45767]
2008-05-26 08:59:48 +00:00
Anthony Williams
eee95fef57 Initial test for generic lock functions
[SVN r45766]
2008-05-26 08:40:21 +00:00
Anthony Williams
9ea179b052 Initial test for generic lock functions
[SVN r45765]
2008-05-26 08:40:13 +00:00
Anthony Williams
6868280409 Try and avoid compile errors in test_thread_callable_object_one_argument
[SVN r45764]
2008-05-26 07:36:16 +00:00
Anthony Williams
e00b764454 The signature of _interlockedbittestandset changes between MSVC 2005 and MSVC 2008
[SVN r45689]
2008-05-23 19:53:06 +00:00
Anthony Williams
999613c686 Added note about mutex not being recursive
[SVN r45688]
2008-05-23 19:33:18 +00:00
Anthony Williams
c2661d7eb5 define intrusive_ptr_add_ref and intrusive_ptr_release at namespace scope rather than inline as friends in order to try and avoid compiler problems
[SVN r45682]
2008-05-23 15:18:19 +00:00
Anthony Williams
4d21dd1f47 try_lock_wrapper implements operator! in order to try and avoid compiler problems
[SVN r45681]
2008-05-23 15:17:14 +00:00
Anthony Williams
a0a0e57527 Fixed #ifdef to actually use BTS primitives on MSVC 9
[SVN r45676]
2008-05-23 13:16:01 +00:00
Anthony Williams
d8af0d0b4e Reset thread_info on move rather than assigning 0
[SVN r45672]
2008-05-23 10:48:07 +00:00
Anthony Williams
113288e3b0 tidying up move
[SVN r45661]
2008-05-22 16:33:34 +00:00
Anthony Williams
afecfd7c2d Refactored boost::thread code to try and remove duplication
[SVN r45647]
2008-05-22 11:49:48 +00:00
Anthony Williams
94d89aac5f more rvalue reference stuff
[SVN r45626]
2008-05-21 21:11:30 +00:00
Anthony Williams
8831b13efc Use lock_guard<> instead of unique_lock<> internally. Clear out generations after notify_all, as they're all notified
[SVN r45625]
2008-05-21 21:10:45 +00:00
Peter Dimov
01f99da03a Extended boost::thread to 9 arguments, hopefully fixed member function ambiguity.
[SVN r45621]
2008-05-21 20:44:08 +00:00
Anthony Williams
080654e3ef New tests for a normal function with one argument, and a member function with 0 or 1 arguments
[SVN r45607]
2008-05-21 13:38:04 +00:00
Anthony Williams
2ac2eb2a61 try_lock_wrapper has its own operator bool_type to avoid problems with a using declaration
[SVN r45602]
2008-05-21 10:39:47 +00:00
Anthony Williams
61b940b705 Renamed namespace user to user_test_ns to try and avoid a name clash on some platforms
[SVN r45601]
2008-05-21 09:51:53 +00:00
Anthony Williams
4a4f87e017 support for a generic lock() function
[SVN r45481]
2008-05-18 09:10:20 +00:00
Anthony Williams
6d5e7f63a7 Added beginnings of real rvalue-reference support
[SVN r45479]
2008-05-18 08:45:44 +00:00
Anthony Williams
f77285f375 Updated docs to make it explicit that terminate is called if a thread function throws an exception
[SVN r45294]
2008-05-12 09:04:02 +00:00
Anthony Williams
dc5d03a6dc Cleaned up to remove warnings
[SVN r45244]
2008-05-09 07:59:57 +00:00
Anthony Williams
ea0961b7f6 Fixed type truncation warning
[SVN r45243]
2008-05-09 07:49:22 +00:00
Anthony Williams
33d9f9774c Test and fix for bug #1905
[SVN r45242]
2008-05-09 07:48:44 +00:00
Anthony Williams
86097fa038 Use _WIN32 rather than WIN32 to prevent include of <unistd.h>
[SVN r45241]
2008-05-09 07:47:14 +00:00
Anthony Williams
70d9dbc45a Added default constructor to lock types
[SVN r45212]
2008-05-08 14:34:40 +00:00
Anthony Williams
3926fd3a20 Added docs for native_handle
[SVN r45211]
2008-05-08 12:59:59 +00:00
Anthony Williams
7861cf1146 Added native_handle to mutex types where possible
[SVN r45210]
2008-05-08 12:59:10 +00:00
Anthony Williams
0516b86a6e new BTS-based mutex implementation on win32
[SVN r45119]
2008-05-04 22:39:52 +00:00
Anthony Williams
ec735d3e9b Simplified move support
[SVN r45108]
2008-05-04 09:52:54 +00:00
Anthony Williams
1c5c070983 Updated locks.hpp to work with gcc as well as msvc
[SVN r44846]
2008-04-28 12:26:27 +00:00
Anthony Williams
a5c02b73dc Added entry to breaking changes about default-constructed threads and the current thread: issue #1835
[SVN r44840]
2008-04-28 09:10:38 +00:00
Anthony Williams
918b920670 Added detail::try_lock_wrapper for use as scoped_try_lock typedefs, to fix issue #1873
[SVN r44838]
2008-04-28 09:00:58 +00:00
Anthony Williams
de67d2e27e Fixed g++ compile error
[SVN r44773]
2008-04-26 07:34:46 +00:00
Anthony Williams
bc89df04cb Revamped condition variable to try and fix swallowed-notify problems (trac issue #1834)
[SVN r44699]
2008-04-21 16:22:16 +00:00
Anthony Williams
c26a4cf082 added private copy assignment operator and copy constructor to remove warnings
[SVN r44698]
2008-04-21 16:20:31 +00:00
Anthony Williams
6e1a866b13 Fix for issue #1657
[SVN r44424]
2008-04-14 21:04:33 +00:00
Anthony Williams
f91986ad0d Added extended adopt/defer/try constructors to upgrade_lock
[SVN r44370]
2008-04-13 15:50:08 +00:00
Anthony Williams
795cc23f3e Added test and fix for win32 condition_variable broadcast bug similar to #1803
[SVN r44168]
2008-04-11 08:52:09 +00:00
Anthony Williams
a3695bd4a0 Updated thread.hpp as catch-all header
[SVN r44153]
2008-04-10 18:34:42 +00:00
Anthony Williams
08dc521daf Added native_handle to condition_variable on pthreads
[SVN r44152]
2008-04-10 15:52:01 +00:00
Anthony Williams
8b916d21b1 added tests for plain timed_lock on shared_mutex
[SVN r44150]
2008-04-10 14:15:26 +00:00
Anthony Williams
c40f47a78a added overloads of timed_lock_shared with a relative timeout to shared_mutex
[SVN r44149]
2008-04-10 14:07:39 +00:00
Anthony Williams
e9fb470b06 Added native_handle to thread on posix platforms
[SVN r44148]
2008-04-10 13:35:07 +00:00
Anthony Williams
343d049772 fix for trac ticket #1804
[SVN r44147]
2008-04-10 13:27:44 +00:00
Anthony Williams
86f9480da4 fix for notify problem in trac ticket #1803
[SVN r44146]
2008-04-10 13:14:43 +00:00
Anthony Williams
8696b610ca Added test for trac ticket #1803: condition_variable::notify_one may fail to wake a waiting thread on win32
[SVN r44136]
2008-04-09 19:33:06 +00:00
Anthony Williams
6f13227eda Added locked-> owns_lock change to breaking changes
[SVN r44089]
2008-04-07 13:09:36 +00:00
Anthony Williams
58d5110e61 removed forward declaration for undefined type exclusive_lock
[SVN r43847]
2008-03-24 21:44:36 +00:00
Anthony Williams
76e53c7bc5 Removed some warnings: those from issue #1640 and others
[SVN r43730]
2008-03-19 17:25:13 +00:00
Anthony Williams
cfb08be1a8 New documentation for new thread library
[SVN r43671]
2008-03-17 10:29:27 +00:00
Anthony Williams
b5bbb7fb1c Test and fix for bug #1693 to ensure thread_specific_ptr works as desired
[SVN r43666]
2008-03-17 08:36:09 +00:00
Anthony Williams
a76c33f8cc made the callable_no_args function object a named object rather than a temporary, in order to avoid gratuitous breakage on some compilers
[SVN r43528]
2008-03-06 07:59:16 +00:00
Anthony Williams
810306b8f3 thread constructor now accepts up to three additional arguments to pass to thread function
[SVN r43464]
2008-03-03 10:52:44 +00:00
Anthony Williams
6c22bdb3bd Test and fix for issue #1665
[SVN r43461]
2008-03-03 08:44:42 +00:00
Daniel James
6a0d3e98bc Fix broken copyright urls. Fixes #1573.
[SVN r43422]
2008-02-27 18:51:14 +00:00
Anthony Williams
3809321037 added test for duration overloads of timed_lock, and added missing implementation to win32 version
[SVN r43094]
2008-02-04 13:16:32 +00:00
Anthony Williams
eef695bdf0 Provide tss_cleanup_implemented as a dummy function on Windows CE to allow tests to run
[SVN r42818]
2008-01-16 15:23:36 +00:00
Anthony Williams
ab01ab1e4d removed references to NULL
[SVN r42657]
2008-01-10 14:19:36 +00:00
Anthony Williams
c8d8a108a7 Updated thread ID test
[SVN r42228]
2007-12-21 10:54:59 +00:00
Anthony Williams
7afd9efcc5 added hardware_concurrency support for apple, freebsd and sun platforms
[SVN r42195]
2007-12-20 08:37:02 +00:00
Anthony Williams
56ded87ad2 added missing parentheses
[SVN r42194]
2007-12-20 07:46:00 +00:00
Anthony Williams
82e503339b Implement hardware_concurrency for pthread
[SVN r42168]
2007-12-19 10:45:01 +00:00
Anthony Williams
713d0c7ace Updated thread ID, and added tests
[SVN r42166]
2007-12-19 10:39:45 +00:00
Anthony Williams
25ad6e3f8f boost::move support for locks
[SVN r42118]
2007-12-17 12:52:50 +00:00
Anthony Williams
df0197b617 Updated move function test to be fair to Borland
[SVN r42117]
2007-12-17 11:24:13 +00:00
Anthony Williams
a89c4f01ad explicit move functions for threads, with a test
[SVN r42087]
2007-12-15 22:36:43 +00:00
Anthony Williams
ae67099633 added timed_wait overloads that take a duration
[SVN r42086]
2007-12-15 22:34:30 +00:00
Anthony Williams
57542d3a5c fixed order of comparison in timeout check
[SVN r41819]
2007-12-07 08:11:11 +00:00
Anthony Williams
9a1da14116 improved timeout checks
[SVN r41741]
2007-12-05 10:58:45 +00:00
Anthony Williams
ed050d753d added missing include of detail/config.hpp
[SVN r41738]
2007-12-05 08:27:44 +00:00
Anthony Williams
8bec363710 changed order of declaration to eliminate warnings
[SVN r41687]
2007-12-04 14:07:01 +00:00
Anthony Williams
7c68e190a9 Added test for thread move constructor; implemented move on pthreads
[SVN r41686]
2007-12-04 13:02:58 +00:00
Anthony Williams
7ebf5ea3d1 add explicit casts to remove warnings
[SVN r41684]
2007-12-04 12:08:38 +00:00
Anthony Williams
11e0435a4b don't dllexport/dllimport inline functions
[SVN r41683]
2007-12-04 11:44:25 +00:00
Anthony Williams
d15ee57cd1 split shared mutex tests in two to take less time
[SVN r41682]
2007-12-04 10:04:30 +00:00
Anthony Williams
56d660b7fd changed boost::move to boost::detail::thread_move to fix issue #1492
[SVN r41681]
2007-12-04 09:15:37 +00:00
Anthony Williams
792958e693 fixed typo in condition_variable_any::timed_wait
[SVN r41679]
2007-12-04 07:57:23 +00:00
Anthony Williams
914e67dc04 check predicate before returning if we time out on a predicated version of timed_wait
[SVN r41668]
2007-12-03 22:00:26 +00:00
Anthony Williams
b50a7ccb61 interruptible_wait (and hence condition timed_wait) now uses a WaitableTimer where possible, to be robust in the face of clock changes
[SVN r41505]
2007-11-30 18:38:21 +00:00
Anthony Williams
f827709d42 add support for relative timeouts to condition timed_wait
[SVN r41413]
2007-11-27 14:24:29 +00:00
Anthony Williams
36abb42175 reverted accidental checkin of new timed_wait functions on condition_variable
[SVN r41405]
2007-11-26 21:15:04 +00:00
Anthony Williams
40f3b1b4c8 once_flag uses zero-initialization on POSIX as well as windows
[SVN r41401]
2007-11-26 17:01:08 +00:00
Anthony Williams
4f35e25688 fixed import/export declarations so new once code works with pthread-win32
[SVN r41398]
2007-11-26 15:44:07 +00:00
Anthony Williams
270e88edd7 Don't compare native_handle_t against 0 --- do appropriate checks in create_native_thread for platforms where pthread_t is not comparable
[SVN r41396]
2007-11-26 13:29:15 +00:00
Anthony Williams
5ded171247 workaround for Borland compiler
[SVN r41395]
2007-11-26 12:17:45 +00:00
35 changed files with 344 additions and 925 deletions

View File

@@ -43,7 +43,6 @@ project boost/thread
<link>shared:<define>BOOST_THREAD_BUILD_DLL=1
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
<tag>@$(__name__).tag
<toolset>gcc:<cxxflags>-Wno-long-long
: default-build <threading>multi
;

View File

@@ -26,6 +26,11 @@ boostbook standalone
<xsl:param>generate.section.toc.level=10
# Path for links to Boost:
<xsl:param>boost.root=../../../..
# Path for libraries index:
<xsl:param>boost.libraries=../../../../libs/libraries.htm
# Use the main Boost stylesheet:
<xsl:param>html.stylesheet=../../../../doc/html/boostbook.css
;

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

@@ -19,14 +19,8 @@
#include "platform.hpp"
// provided for backwards compatibility, since this
// macro was used for several releases by mistake.
#if defined(BOOST_THREAD_DYN_DLL)
# define BOOST_THREAD_DYN_LINK
#endif
// 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

@@ -29,7 +29,7 @@
# define BOOST_THREAD_HPUX
#elif defined(__CYGWIN__)
# define BOOST_THREAD_CYGWIN
#elif (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && !defined(BOOST_DISABLE_WIN32)
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
# define BOOST_THREAD_WIN32
#elif defined(__BEOS__)
# define BOOST_THREAD_BEOS

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_)
@@ -115,15 +110,16 @@ namespace boost
void release_handle();
mutable boost::mutex thread_info_mutex;
detail::thread_data_ptr thread_info;
void start_thread();
explicit thread(detail::thread_data_ptr data);
detail::thread_data_ptr get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const;
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)
{
@@ -131,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>
@@ -145,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(static_cast<F&&>(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)
{
@@ -218,7 +205,7 @@ namespace boost
x->thread_info.reset();
}
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
#ifdef __SUNPRO_CC
thread& operator=(thread x)
{
swap(x);
@@ -356,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)
@@ -395,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()
@@ -431,8 +414,6 @@ namespace boost
return !(thread_data<y.thread_data);
}
#ifndef BOOST_NO_IOSTREAM
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
template<class charT, class traits>
friend std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const id& x)
@@ -446,34 +427,8 @@ namespace boost
return os<<"{Not-any-thread}";
}
}
#else
template<class charT, class traits>
std::basic_ostream<charT, traits>&
print(std::basic_ostream<charT, traits>& os) const
{
if(thread_data)
{
return os<<thread_data;
}
else
{
return os<<"{Not-any-thread}";
}
}
#endif
#endif
};
#if !defined(BOOST_NO_IOSTREAM) && defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class charT, class traits>
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const thread::id& x)
{
return x.print(os);
}
#endif
inline bool thread::operator==(const thread& other) const
{
return get_id()==other.get_id();

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>
@@ -142,8 +140,6 @@ namespace boost
{
lock.lock();
}
private:
relocker& operator=(relocker const&);
};
void do_callback(boost::unique_lock<boost::mutex>& lock)
@@ -223,7 +219,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;
@@ -328,7 +324,7 @@ namespace boost
move_dest_type get()
{
wait();
return static_cast<move_dest_type>(*result);
return *result;
}
future_state::state get_state()
@@ -392,18 +388,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_)
{}
@@ -411,13 +404,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);
}
@@ -430,7 +423,7 @@ namespace boost
void unlock()
{
for(count_type i=0;i<count;++i)
for(unsigned i=0;i<count;++i)
{
locks[i].unlock();
}
@@ -439,7 +432,7 @@ namespace boost
boost::condition_variable_any cv;
std::vector<registered_waiter> futures;
count_type future_count;
unsigned future_count;
public:
future_waiter():
@@ -456,12 +449,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)
{
@@ -474,7 +467,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);
}
@@ -554,9 +547,6 @@ namespace boost
template<typename Iterator>
typename boost::disable_if<is_future_type<Iterator>,Iterator>::type wait_for_any(Iterator begin,Iterator end)
{
if(begin==end)
return end;
detail::future_waiter waiter;
for(Iterator current=begin;current!=end;++current)
{
@@ -643,7 +633,7 @@ namespace boost
~unique_future()
{}
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
unique_future(unique_future && other)
{
future.swap(other.future);
@@ -778,7 +768,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);
@@ -912,10 +902,10 @@ namespace boost
void lazy_init()
{
if(!atomic_load(&future))
if(!future)
{
future_ptr blank;
atomic_compare_exchange(&future,&blank,future_ptr(new detail::future_object<R>));
future_obtained=false;
future.reset(new detail::future_object<R>);
}
}
@@ -940,19 +930,17 @@ namespace boost
}
// Assignment
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
promise(promise && rhs):
future_obtained(rhs.future_obtained)
{
future.swap(rhs.future);
rhs.future_obtained=false;
}
promise & operator=(promise&& rhs)
{
future.swap(rhs.future);
future_obtained=rhs.future_obtained;
rhs.future.reset();
rhs.future_obtained=false;
return *this;
}
#else
@@ -960,14 +948,12 @@ namespace boost
future(rhs->future),future_obtained(rhs->future_obtained)
{
rhs->future.reset();
rhs->future_obtained=false;
}
promise & operator=(boost::detail::thread_move_t<promise> rhs)
{
future=rhs->future;
future_obtained=rhs->future_obtained;
rhs->future.reset();
rhs->future_obtained=false;
return *this;
}
@@ -1051,10 +1037,10 @@ namespace boost
void lazy_init()
{
if(!atomic_load(&future))
if(!future)
{
future_ptr blank;
atomic_compare_exchange(&future,&blank,future_ptr(new detail::future_object<void>));
future_obtained=false;
future.reset(new detail::future_object<void>);
}
}
public:
@@ -1078,19 +1064,17 @@ namespace boost
}
// Assignment
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
promise(promise && rhs):
future_obtained(rhs.future_obtained)
{
future.swap(rhs.future);
rhs.future_obtained=false;
}
promise & operator=(promise&& rhs)
{
future.swap(rhs.future);
future_obtained=rhs.future_obtained;
rhs.future.reset();
rhs.future_obtained=false;
return *this;
}
#else
@@ -1098,14 +1082,12 @@ namespace boost
future(rhs->future),future_obtained(rhs->future_obtained)
{
rhs->future.reset();
rhs->future_obtained=false;
}
promise & operator=(boost::detail::thread_move_t<promise> rhs)
{
future=rhs->future;
future_obtained=rhs->future_obtained;
rhs->future.reset();
rhs->future_obtained=false;
return *this;
}
@@ -1302,7 +1284,7 @@ namespace boost
}
// assignment
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_HAS_RVALUE_REFS
packaged_task(packaged_task&& other):
future_obtained(other.future_obtained)
{

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));
};
}
@@ -277,7 +214,7 @@ namespace boost
unique_lock& operator=(unique_lock&);
unique_lock& operator=(upgrade_lock<Mutex>& other);
public:
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
#ifdef __SUNPRO_CC
unique_lock(const volatile unique_lock&);
#endif
unique_lock():
@@ -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)
{
@@ -363,7 +300,7 @@ namespace boost
return detail::thread_move_t<unique_lock<Mutex> >(*this);
}
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
#ifdef __SUNPRO_CC
unique_lock& operator=(unique_lock<Mutex> other)
{
swap(other);
@@ -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()
{
@@ -479,42 +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 static_cast<upgrade_lock<Mutex>&&>(ul);
}
template<typename Mutex>
inline upgrade_lock<Mutex>&& move(upgrade_lock<Mutex>& ul)
{
return static_cast<upgrade_lock<Mutex>&&>(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
@@ -615,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
{
@@ -709,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)
{
@@ -753,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(static_cast<upgrade_lock<Mutex>&&>(other));
swap(temp);
return *this;
}
upgrade_lock& operator=(unique_lock<Mutex>&& other)
{
upgrade_lock temp(static_cast<unique_lock<Mutex>&&>(other));
swap(temp);
return *this;
}
#else
upgrade_lock(detail::thread_move_t<upgrade_lock<Mutex> > other):
m(other->m),is_locked(other->is_locked)
{
@@ -828,7 +715,6 @@ namespace boost
swap(temp);
return *this;
}
#endif
void swap(upgrade_lock& other)
{
@@ -889,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)
@@ -933,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))
{
@@ -959,7 +831,6 @@ namespace boost
swap(temp);
return *this;
}
#endif
void swap(upgrade_to_unique_lock& other)
{
std::swap(source,other.source);
@@ -1004,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())
{}
@@ -1047,15 +918,15 @@ namespace boost
return *this;
}
void swap(try_lock_wrapper& other)
{
base::swap(other);
}
void swap(detail::thread_move_t<try_lock_wrapper<Mutex> > other)
{
base::swap(*other);
}
#endif
void swap(try_lock_wrapper& other)
{
base::swap(other);
}
void lock()
{
base::lock();
@@ -1092,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)
{
@@ -1240,7 +1111,7 @@ namespace boost
{
unsigned const lock_count=2;
unsigned lock_first=0;
for(;;)
while(true)
{
switch(lock_first)
{
@@ -1293,7 +1164,7 @@ namespace boost
{
unsigned const lock_count=3;
unsigned lock_first=0;
for(;;)
while(true)
{
switch(lock_first)
{
@@ -1325,7 +1196,7 @@ namespace boost
{
unsigned const lock_count=4;
unsigned lock_first=0;
for(;;)
while(true)
{
switch(lock_first)
{
@@ -1363,7 +1234,7 @@ namespace boost
{
unsigned const lock_count=5;
unsigned lock_first=0;
for(;;)
while(true)
{
switch(lock_first)
{

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"
@@ -14,55 +14,17 @@
namespace boost
{
namespace this_thread
{
void BOOST_THREAD_DECL interruption_point();
}
namespace thread_cv_detail
{
template<typename MutexType>
struct lock_on_exit
{
MutexType* m;
lock_on_exit():
m(0)
{}
void activate(MutexType& m_)
{
m_.unlock();
m=&m_;
}
~lock_on_exit()
{
if(m)
{
m->lock();
}
}
};
}
inline void condition_variable::wait(unique_lock<mutex>& m)
{
thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
guard.activate(m);
int const res=pthread_cond_wait(&cond,&internal_mutex);
BOOST_ASSERT(!res);
this_thread::interruption_point();
detail::interruption_checker check_for_interruption(&cond);
BOOST_VERIFY(!pthread_cond_wait(&cond,m.mutex()->native_handle()));
}
inline bool condition_variable::timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until)
{
thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
guard.activate(m);
detail::interruption_checker check_for_interruption(&cond);
struct timespec const timeout=detail::get_timespec(wait_until);
int const cond_res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
this_thread::interruption_point();
int const cond_res=pthread_cond_timedwait(&cond,m.mutex()->native_handle(),&timeout);
if(cond_res==ETIMEDOUT)
{
return false;
@@ -73,13 +35,11 @@ namespace boost
inline void condition_variable::notify_one()
{
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
BOOST_VERIFY(!pthread_cond_signal(&cond));
}
inline void condition_variable::notify_all()
{
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
BOOST_VERIFY(!pthread_cond_broadcast(&cond));
}
@@ -88,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()
@@ -117,11 +77,13 @@ namespace boost
{
int res=0;
{
thread_cv_detail::lock_on_exit<lock_type> guard;
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
guard.activate(m);
res=pthread_cond_wait(&cond,&internal_mutex);
this_thread::interruption_point();
detail::interruption_checker check_for_interruption(&cond);
{
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
m.unlock();
res=pthread_cond_wait(&cond,&internal_mutex);
}
m.lock();
}
if(res)
{
@@ -141,11 +103,13 @@ namespace boost
struct timespec const timeout=detail::get_timespec(wait_until);
int res=0;
{
thread_cv_detail::lock_on_exit<lock_type> guard;
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
guard.activate(m);
res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
this_thread::interruption_point();
detail::interruption_checker check_for_interruption(&cond);
{
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
m.unlock();
res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
}
m.lock();
}
if(res==ETIMEDOUT)
{

View File

@@ -20,7 +20,6 @@ namespace boost
class condition_variable
{
private:
pthread_mutex_t internal_mutex;
pthread_cond_t cond;
condition_variable(condition_variable&);
@@ -29,21 +28,14 @@ namespace boost
public:
condition_variable()
{
int const res=pthread_mutex_init(&internal_mutex,NULL);
int const res=pthread_cond_init(&cond,NULL);
if(res)
{
boost::throw_exception(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());
}
}
~condition_variable()
{
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
BOOST_VERIFY(!pthread_cond_destroy(&cond));
}
@@ -55,8 +47,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

@@ -27,11 +27,10 @@
namespace boost
{
class mutex
class mutex:
boost::noncopyable
{
private:
mutex(mutex const&);
mutex& operator=(mutex const&);
pthread_mutex_t m;
public:
mutex()
@@ -49,11 +48,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 +59,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 +75,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

View File

@@ -18,25 +18,15 @@ namespace boost
class pthread_mutex_scoped_lock
{
pthread_mutex_t* m;
bool locked;
public:
explicit pthread_mutex_scoped_lock(pthread_mutex_t* m_):
m(m_),locked(true)
m(m_)
{
BOOST_VERIFY(!pthread_mutex_lock(m));
}
void unlock()
{
BOOST_VERIFY(!pthread_mutex_unlock(m));
locked=false;
}
~pthread_mutex_scoped_lock()
{
if(locked)
{
unlock();
}
BOOST_VERIFY(!pthread_mutex_unlock(m));
}
};

View File

@@ -26,30 +26,18 @@
#endif
#endif
#if defined(BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE) && defined(BOOST_PTHREAD_HAS_TIMEDLOCK)
#define BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
#endif
#include <boost/config/abi_prefix.hpp>
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;
#ifndef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE
pthread_cond_t cond;
bool is_locked;
pthread_t owner;
unsigned count;
#endif
public:
recursive_mutex()
{
#ifdef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE
pthread_mutexattr_t attr;
int const init_attr_res=pthread_mutexattr_init(&attr);
@@ -60,42 +48,21 @@ namespace boost
int const set_attr_res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
if(set_attr_res)
{
BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
boost::throw_exception(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());
}
BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
#else
int const res=pthread_mutex_init(&m,NULL);
if(res)
{
boost::throw_exception(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());
}
is_locked=false;
count=0;
#endif
}
~recursive_mutex()
{
BOOST_VERIFY(!pthread_mutex_destroy(&m));
#ifndef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE
BOOST_VERIFY(!pthread_cond_destroy(&cond));
#endif
}
#ifdef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE
void lock()
{
BOOST_VERIFY(!pthread_mutex_lock(&m));
@@ -112,70 +79,25 @@ namespace boost
BOOST_ASSERT(!res || res==EBUSY);
return !res;
}
typedef pthread_mutex_t* native_handle_type;
native_handle_type native_handle()
{
return &m;
}
#else
void lock()
{
boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
if(is_locked && pthread_equal(owner,pthread_self()))
{
++count;
return;
}
while(is_locked)
{
BOOST_VERIFY(!pthread_cond_wait(&cond,&m));
}
is_locked=true;
++count;
owner=pthread_self();
}
void unlock()
{
boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
if(!--count)
{
is_locked=false;
}
BOOST_VERIFY(!pthread_cond_signal(&cond));
}
bool try_lock()
{
boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
if(is_locked && !pthread_equal(owner,pthread_self()))
{
return false;
}
is_locked=true;
++count;
owner=pthread_self();
return true;
}
#endif
typedef unique_lock<recursive_mutex> scoped_lock;
typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock;
};
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_USE_PTHREAD_RECURSIVE_TIMEDLOCK
#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
pthread_cond_t cond;
bool is_locked;
pthread_t owner;
@@ -184,7 +106,7 @@ namespace boost
public:
recursive_timed_mutex()
{
#ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
pthread_mutexattr_t attr;
int const init_attr_res=pthread_mutexattr_init(&attr);
@@ -224,7 +146,7 @@ namespace boost
~recursive_timed_mutex()
{
BOOST_VERIFY(!pthread_mutex_destroy(&m));
#ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
BOOST_VERIFY(!pthread_cond_destroy(&cond));
#endif
}
@@ -235,7 +157,7 @@ namespace boost
return timed_lock(get_system_time()+relative_time);
}
#ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
void lock()
{
BOOST_VERIFY(!pthread_mutex_lock(&m));

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

@@ -12,7 +12,6 @@
#include <boost/thread/mutex.hpp>
#include <boost/optional.hpp>
#include <pthread.h>
#include <boost/assert.hpp>
#include "condition_variable_fwd.hpp"
#include <map>
@@ -56,7 +55,6 @@ namespace boost
std::map<void const*,boost::detail::tss_data_node> tss_data;
bool interrupt_enabled;
bool interrupt_requested;
pthread_mutex_t* cond_mutex;
pthread_cond_t* current_cond;
thread_data_base():
@@ -78,8 +76,6 @@ namespace boost
class interruption_checker
{
thread_data_base* const thread_info;
pthread_mutex_t* m;
bool set;
void check_for_interruption()
{
@@ -92,35 +88,23 @@ namespace boost
void operator=(interruption_checker&);
public:
explicit interruption_checker(pthread_mutex_t* cond_mutex,pthread_cond_t* cond):
thread_info(detail::get_current_thread_data()),m(cond_mutex),
set(thread_info && thread_info->interrupt_enabled)
explicit interruption_checker(pthread_cond_t* cond):
thread_info(detail::get_current_thread_data())
{
if(set)
if(thread_info && thread_info->interrupt_enabled)
{
lock_guard<mutex> guard(thread_info->data_mutex);
check_for_interruption();
thread_info->cond_mutex=cond_mutex;
thread_info->current_cond=cond;
BOOST_VERIFY(!pthread_mutex_lock(m));
}
else
{
BOOST_VERIFY(!pthread_mutex_lock(m));
}
}
~interruption_checker()
{
if(set)
if(thread_info && thread_info->interrupt_enabled)
{
BOOST_VERIFY(!pthread_mutex_unlock(m));
lock_guard<mutex> guard(thread_info->data_mutex);
thread_info->cond_mutex=NULL;
thread_info->current_cond=NULL;
}
else
{
BOOST_VERIFY(!pthread_mutex_unlock(m));
check_for_interruption();
}
}
};

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

@@ -6,7 +6,6 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/date_time/time_clock.hpp>
#include <boost/date_time/microsec_time_clock.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
@@ -18,11 +17,7 @@ namespace boost
inline system_time get_system_time()
{
#if defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
return boost::date_time::microsec_clock<system_time>::universal_time();
#else // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
return boost::date_time::second_clock<system_time>::universal_time();
#endif // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
}
namespace detail

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

@@ -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

@@ -34,85 +34,42 @@ namespace boost
{
long status;
long count;
long throw_count;
void* event_handle;
~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}
#define BOOST_ONCE_INIT {0,0,0,0}
namespace detail
{
#ifdef BOOST_NO_ANSI_APIS
typedef wchar_t once_char_type;
#else
typedef char once_char_type;
#endif
unsigned const once_mutex_name_fixed_length=54;
unsigned const once_mutex_name_length=once_mutex_name_fixed_length+
sizeof(void*)*2+sizeof(unsigned long)*2+1;
template <class I>
void int_to_string(I p, once_char_type* buf)
inline void* allocate_event_handle(void*& handle)
{
for(unsigned i=0; i < sizeof(I)*2; ++i,++buf)
{
#ifdef BOOST_NO_ANSI_APIS
once_char_type const a=L'A';
#else
once_char_type const a='A';
#endif
*buf = a + static_cast<once_char_type>((p >> (i*4)) & 0x0f);
}
*buf = 0;
}
inline void name_once_mutex(once_char_type* mutex_name,void* flag_address)
{
#ifdef BOOST_NO_ANSI_APIS
static const once_char_type fixed_mutex_name[]=L"Local\\{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag";
#else
static const once_char_type fixed_mutex_name[]="Local\\{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag";
#endif
BOOST_STATIC_ASSERT(sizeof(fixed_mutex_name) ==
(sizeof(once_char_type)*(once_mutex_name_fixed_length+1)));
void* const new_handle=::boost::detail::win32::create_anonymous_event(
::boost::detail::win32::manual_reset_event,
::boost::detail::win32::event_initially_reset);
std::memcpy(mutex_name,fixed_mutex_name,sizeof(fixed_mutex_name));
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);
}
inline void* open_once_event(once_char_type* mutex_name,void* flag_address)
{
if(!*mutex_name)
void* event_handle=BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&handle,
new_handle,0);
if(event_handle)
{
name_once_mutex(mutex_name,flag_address);
::boost::detail::win32::CloseHandle(new_handle);
return event_handle;
}
#ifdef BOOST_NO_ANSI_APIS
return ::boost::detail::win32::OpenEventW(
#else
return ::boost::detail::win32::OpenEventA(
#endif
::boost::detail::win32::synchronize |
::boost::detail::win32::event_modify_state,
false,
mutex_name);
}
inline void* create_once_event(once_char_type* mutex_name,void* flag_address)
{
if(!*mutex_name)
{
name_once_mutex(mutex_name,flag_address);
}
#ifdef BOOST_NO_ANSI_APIS
return ::boost::detail::win32::CreateEventW(
#else
return ::boost::detail::win32::CreateEventA(
#endif
0,::boost::detail::win32::manual_reset_event,
::boost::detail::win32::event_initially_reset,
mutex_name);
return new_handle;
}
}
@@ -126,9 +83,8 @@ namespace boost
long const running_value=0x7f0725e3;
long status;
bool counted=false;
detail::win32::handle_manager event_handle;
detail::once_char_type mutex_name[detail::once_mutex_name_length];
mutex_name[0]=0;
void* event_handle=0;
long throw_count=0;
while((status=::boost::detail::interlocked_read_acquire(&flag.status))
!=function_complete_flag_value)
@@ -140,7 +96,7 @@ namespace boost
{
if(!event_handle)
{
event_handle=detail::open_once_event(mutex_name,&flag);
event_handle=::boost::detail::interlocked_read_acquire(&flag.event_handle);
}
if(event_handle)
{
@@ -156,20 +112,25 @@ namespace boost
if(!event_handle &&
(::boost::detail::interlocked_read_acquire(&flag.count)>1))
{
event_handle=detail::create_once_event(mutex_name,&flag);
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=detail::open_once_event(mutex_name,&flag);
event_handle=::boost::detail::interlocked_read_acquire(&flag.event_handle);
}
if(event_handle)
{
@@ -188,15 +149,31 @@ namespace boost
{
break;
}
event_handle=::boost::detail::interlocked_read_acquire(&flag.event_handle);
if(!event_handle)
{
event_handle=detail::create_once_event(mutex_name,&flag);
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);
}
}
}
}
}

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

@@ -87,7 +87,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

@@ -31,18 +31,14 @@ namespace boost
unsigned const infinite=INFINITE;
unsigned const timeout=WAIT_TIMEOUT;
handle const invalid_handle_value=INVALID_HANDLE_VALUE;
unsigned const event_modify_state=EVENT_MODIFY_STATE;
unsigned const synchronize=SYNCHRONIZE;
# ifdef BOOST_NO_ANSI_APIS
using ::CreateMutexW;
using ::CreateEventW;
using ::OpenEventW;
using ::CreateSemaphoreW;
# else
using ::CreateMutexA;
using ::CreateEventA;
using ::OpenEventA;
using ::CreateSemaphoreA;
# endif
using ::CloseHandle;
@@ -104,8 +100,6 @@ namespace boost
unsigned const infinite=~0U;
unsigned const timeout=258U;
handle const invalid_handle_value=(handle)(-1);
unsigned const event_modify_state=2;
unsigned const synchronize=0x100000u;
extern "C"
{
@@ -114,12 +108,10 @@ namespace boost
__declspec(dllimport) void* __stdcall CreateMutexW(_SECURITY_ATTRIBUTES*,int,wchar_t const*);
__declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*);
__declspec(dllimport) void* __stdcall CreateEventW(_SECURITY_ATTRIBUTES*,int,int,wchar_t const*);
__declspec(dllimport) void* __stdcall OpenEventW(unsigned long,int,wchar_t const*);
# else
__declspec(dllimport) void* __stdcall CreateMutexA(_SECURITY_ATTRIBUTES*,int,char const*);
__declspec(dllimport) void* __stdcall CreateSemaphoreA(_SECURITY_ATTRIBUTES*,long,long,char const*);
__declspec(dllimport) void* __stdcall CreateEventA(_SECURITY_ATTRIBUTES*,int,int,char const*);
__declspec(dllimport) void* __stdcall OpenEventA(unsigned long,int,char const*);
# endif
__declspec(dllimport) int __stdcall CloseHandle(void*);
__declspec(dllimport) int __stdcall ReleaseMutex(void*);

View File

@@ -75,7 +75,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);
}
@@ -196,14 +196,15 @@ namespace boost
detach();
}
detail::thread_data_ptr thread::get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const
detail::thread_data_ptr thread::get_thread_info() const
{
lock_guard<mutex> l(thread_info_mutex);
return thread_info;
}
void thread::join()
{
detail::thread_data_ptr const local_thread_info=(get_thread_info)();
detail::thread_data_ptr const local_thread_info=get_thread_info();
if(local_thread_info)
{
bool do_join=false;
@@ -237,6 +238,7 @@ namespace boost
local_thread_info->done_condition.notify_all();
}
lock_guard<mutex> l1(thread_info_mutex);
if(thread_info==local_thread_info)
{
thread_info.reset();
@@ -246,7 +248,7 @@ namespace boost
bool thread::timed_join(system_time const& wait_until)
{
detail::thread_data_ptr const local_thread_info=(get_thread_info)();
detail::thread_data_ptr const local_thread_info=get_thread_info();
if(local_thread_info)
{
bool do_join=false;
@@ -283,6 +285,7 @@ namespace boost
local_thread_info->done_condition.notify_all();
}
lock_guard<mutex> l1(thread_info_mutex);
if(thread_info==local_thread_info)
{
thread_info.reset();
@@ -293,14 +296,17 @@ namespace boost
bool thread::joinable() const
{
return (get_thread_info)();
return get_thread_info();
}
void thread::detach()
{
detail::thread_data_ptr local_thread_info;
thread_info.swap(local_thread_info);
{
lock_guard<mutex> l1(thread_info_mutex);
thread_info.swap(local_thread_info);
}
if(local_thread_info)
{
@@ -375,6 +381,8 @@ 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);
@@ -382,8 +390,6 @@ namespace boost
#elif defined(BOOST_HAS_UNISTD_H) && defined(_SC_NPROCESSORS_ONLN)
int const count=sysconf(_SC_NPROCESSORS_ONLN);
return (count>0)?count:0;
#elif defined(_GNU_SOURCE)
return get_nprocs();
#else
return 0;
#endif
@@ -391,7 +397,7 @@ namespace boost
thread::id thread::get_id() const
{
detail::thread_data_ptr const local_thread_info=(get_thread_info)();
detail::thread_data_ptr const local_thread_info=get_thread_info();
if(local_thread_info)
{
return id(local_thread_info);
@@ -404,14 +410,13 @@ namespace boost
void thread::interrupt()
{
detail::thread_data_ptr const local_thread_info=(get_thread_info)();
detail::thread_data_ptr const local_thread_info=get_thread_info();
if(local_thread_info)
{
lock_guard<mutex> lk(local_thread_info->data_mutex);
local_thread_info->interrupt_requested=true;
if(local_thread_info->current_cond)
{
boost::pthread::pthread_mutex_scoped_lock internal_lock(local_thread_info->cond_mutex);
BOOST_VERIFY(!pthread_cond_broadcast(local_thread_info->current_cond));
}
}
@@ -419,7 +424,7 @@ namespace boost
bool thread::interruption_requested() const
{
detail::thread_data_ptr const local_thread_info=(get_thread_info)();
detail::thread_data_ptr const local_thread_info=get_thread_info();
if(local_thread_info)
{
lock_guard<mutex> lk(local_thread_info->data_mutex);
@@ -433,7 +438,7 @@ namespace boost
thread::native_handle_type thread::native_handle()
{
detail::thread_data_ptr const local_thread_info=(get_thread_info)();
detail::thread_data_ptr const local_thread_info=get_thread_info();
if(local_thread_info)
{
lock_guard<mutex> lk(local_thread_info->data_mutex);
@@ -577,11 +582,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

@@ -8,15 +8,13 @@
#if defined(BOOST_HAS_WINTHREADS) && (defined(BOOST_THREAD_BUILD_LIB) || defined(BOOST_THREAD_TEST) || defined(UNDER_CE)) && (!defined(_MSC_VER) || defined(UNDER_CE))
namespace boost
{
/*
This file is a "null" implementation of tss cleanup; it's
purpose is to to eliminate link errors in cases
where it is known that tss cleanup is not needed.
*/
void tss_cleanup_implemented(void)
extern "C" void tss_cleanup_implemented(void)
{
/*
This function's sole purpose is to cause a link error in cases where
@@ -32,7 +30,5 @@ namespace boost
longer needed and can be removed.
*/
}
}
#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB) && !defined(_MSC_VER)

View File

@@ -244,17 +244,17 @@ namespace boost
thread::id thread::get_id() const
{
return thread::id((get_thread_info)());
return thread::id(get_thread_info());
}
bool thread::joinable() const
{
return (get_thread_info)();
return get_thread_info();
}
void thread::join()
{
detail::thread_data_ptr local_thread_info=(get_thread_info)();
detail::thread_data_ptr local_thread_info=get_thread_info();
if(local_thread_info)
{
this_thread::interruptible_wait(local_thread_info->thread_handle,detail::timeout::sentinel());
@@ -264,7 +264,7 @@ namespace boost
bool thread::timed_join(boost::system_time const& wait_until)
{
detail::thread_data_ptr local_thread_info=(get_thread_info)();
detail::thread_data_ptr local_thread_info=get_thread_info();
if(local_thread_info)
{
if(!this_thread::interruptible_wait(local_thread_info->thread_handle,get_milliseconds_until(wait_until)))
@@ -283,12 +283,13 @@ namespace boost
void thread::release_handle()
{
lock_guard<mutex> l1(thread_info_mutex);
thread_info=0;
}
void thread::interrupt()
{
detail::thread_data_ptr local_thread_info=(get_thread_info)();
detail::thread_data_ptr local_thread_info=get_thread_info();
if(local_thread_info)
{
local_thread_info->interrupt();
@@ -297,25 +298,26 @@ namespace boost
bool thread::interruption_requested() const
{
detail::thread_data_ptr local_thread_info=(get_thread_info)();
detail::thread_data_ptr local_thread_info=get_thread_info();
return local_thread_info.get() && (detail::win32::WaitForSingleObject(local_thread_info->interruption_handle,0)==0);
}
unsigned thread::hardware_concurrency()
{
SYSTEM_INFO info={{0}};
SYSTEM_INFO info={0};
GetSystemInfo(&info);
return info.dwNumberOfProcessors;
}
thread::native_handle_type thread::native_handle()
{
detail::thread_data_ptr local_thread_info=(get_thread_info)();
detail::thread_data_ptr local_thread_info=get_thread_info();
return local_thread_info?(detail::win32::handle)local_thread_info->thread_handle:detail::win32::invalid_handle_value;
}
detail::thread_data_ptr thread::get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const
detail::thread_data_ptr thread::get_thread_info() const
{
boost::mutex::scoped_lock l(thread_info_mutex);
return thread_info;
}
@@ -325,7 +327,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;
@@ -354,23 +356,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;
@@ -591,22 +577,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,24 +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();
}
}
#if (__MINGW32_MAJOR_VERSION >3) || ((__MINGW32_MAJOR_VERSION==3) && (__MINGW32_MINOR_VERSION>=18))
extern "C"
{
PIMAGE_TLS_CALLBACK __crt_xl_tls_callback__ __attribute__ ((section(".CRT$XLB"))) = on_tls_callback;
}
#else
extern "C" {
void (* after_ctors )() __attribute__((section(".ctors"))) = boost::on_process_enter;
void (* before_dtors)() __attribute__((section(".dtors"))) = boost::on_thread_exit;
void (* after_dtors )() __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;
@@ -56,8 +62,10 @@ extern "C" {
PIMAGE_TLS_CALLBACK __crt_xl_start__ __attribute__ ((section(".CRT$XLA"))) = 0;
PIMAGE_TLS_CALLBACK __crt_xl_tls_callback__ __attribute__ ((section(".CRT$XLB"))) = on_tls_callback;
PIMAGE_TLS_CALLBACK __crt_xl_end__ __attribute__ ((section(".CRT$XLZ"))) = 0;
}
extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata$T"))) =
{
(DWORD) &__tls_start__,
@@ -67,7 +75,6 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
(DWORD) 0,
(DWORD) 0
};
#endif
#elif defined(_MSC_VER) && !defined(UNDER_CE)
@@ -82,13 +89,13 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
//Definitions required by implementation
#if (_MSC_VER < 1300) // 1300 == VC++ 7.0
typedef void (__cdecl *_PVFV)();
typedef void (__cdecl *_PVFV)(void);
#define INIRETSUCCESS
#define PVAPI void __cdecl
#define PVAPI void
#else
typedef int (__cdecl *_PVFV)();
typedef int (__cdecl *_PVFV)(void);
#define INIRETSUCCESS 0
#define PVAPI int __cdecl
#define PVAPI int
#endif
typedef void (NTAPI* _TLSCB)(HINSTANCE, DWORD, PVOID);
@@ -105,9 +112,9 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
{
//Forward declarations
static PVAPI on_tls_prepare();
static PVAPI on_process_init();
static PVAPI on_process_term();
static PVAPI on_tls_prepare(void);
static PVAPI on_process_init(void);
static PVAPI on_process_term(void);
static void NTAPI on_tls_callback(HINSTANCE, DWORD, PVOID);
//The .CRT$Xxx information is taken from Codeguru:
@@ -162,7 +169,7 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
#pragma warning(disable:4189)
#endif
PVAPI on_tls_prepare()
PVAPI on_tls_prepare(void)
{
//The following line has an important side effect:
//if the TLS directory is not already there, it will
@@ -203,7 +210,7 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
#pragma warning(pop)
#endif
PVAPI on_process_init()
PVAPI on_process_init(void)
{
//Schedule on_thread_exit() to be called for the main
//thread before destructors of global objects have been
@@ -214,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()
PVAPI on_process_term(void)
{
boost::on_process_exit();
on_process_exit();
return INIRETSUCCESS;
}
@@ -234,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;
}
}
@@ -244,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;
@@ -258,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
@@ -276,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

@@ -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,11 +14,11 @@
#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)
{
return static_cast<typename boost::remove_reference<T>::type&&>(t);
return t;
}
#else
template<typename 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);
@@ -556,7 +556,7 @@ void wait_callback(boost::promise<int>& pi)
}
}
void do_nothing_callback(boost::promise<int>& /*pi*/)
void do_nothing_callback(boost::promise<int>& pi)
{
boost::lock_guard<boost::mutex> lk(callback_mutex);
++callback_called;
@@ -1041,8 +1041,6 @@ void test_wait_for_any_from_range()
}
boost::thread(::cast_to_rval(tasks[i]));
BOOST_CHECK(boost::wait_for_any(futures,futures)==futures);
boost::unique_future<int>* const future=boost::wait_for_any(futures,futures+count);
BOOST_CHECK(future==(futures+i));

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

@@ -138,14 +138,6 @@ void test_can_lock_upgrade_if_currently_locked_shared()
CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,reader_count+1);
}
void test_can_lock_upgrade_to_unique_if_currently_locked_upgrade()
{
boost::shared_mutex mtx;
boost::upgrade_lock<boost::shared_mutex> l(mtx);
boost::upgrade_to_unique_lock<boost::shared_mutex> ul(l);
BOOST_CHECK(ul.owns_lock());
}
void test_if_other_thread_has_write_lock_try_lock_shared_returns_false()
{
@@ -290,7 +282,6 @@ boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
test->add(BOOST_TEST_CASE(&test_only_one_upgrade_lock_permitted));
test->add(BOOST_TEST_CASE(&test_can_lock_upgrade_if_currently_locked_shared));
test->add(BOOST_TEST_CASE(&test_can_lock_upgrade_to_unique_if_currently_locked_upgrade));
test->add(BOOST_TEST_CASE(&test_if_other_thread_has_write_lock_try_lock_shared_returns_false));
test->add(BOOST_TEST_CASE(&test_if_no_thread_has_lock_try_lock_shared_returns_true));
test->add(BOOST_TEST_CASE(&test_if_other_thread_has_shared_lock_try_lock_shared_returns_true));