2
0
mirror of https://github.com/boostorg/thread.git synced 2026-02-05 10:12:09 +00:00

Compare commits

..

110 Commits

Author SHA1 Message Date
Michael Glassford
9f9292e2e3 Fix compile errors: some compilers don't like an enum and the namespace it is in to have the same name; missing typename; _sntprintf not in namespace std for cw. Fix warnings on some compilers. Clean up scheduling algorithms to pass unit tests and hopefully eliminate reported deadlocks. Still needs work, but should be better than before.
[SVN r23859]
2004-07-20 21:33:13 +00:00
Michael Glassford
0a88a53a33 Fix compile errors: some compilers don't like an enum and the namespace it is in to have the same name.
[SVN r23858]
2004-07-20 21:29:39 +00:00
Michael Glassford
0bce1befd9 Remove line-continuation inside #if (cwpro8 seemed not to like it).
[SVN r23857]
2004-07-20 21:24:00 +00:00
Michael Glassford
9f354c98ab Renamed add_thread_exit() to at_thread_exit(), a better name.
[SVN r23856]
2004-07-20 21:22:55 +00:00
Michael Glassford
274b04bcf7 Add hooks for users to provide their own tss cleanup in win32 statically linked builds.
[SVN r23586]
2004-07-15 15:19:08 +00:00
Michael Glassford
539d19468d Add try_lock() method to scoped_timed_lock.
[SVN r23585]
2004-07-15 14:30:42 +00:00
Michael Glassford
fff6d9eddd Changes for WinCE.
[SVN r23584]
2004-07-15 14:27:50 +00:00
Michael Glassford
5472ebdfde Add hooks for users to provide their own tss cleanup in win32 statically linked builds.
[SVN r23583]
2004-07-15 14:26:10 +00:00
Michael Glassford
50c034f650 Fix enum definition.
[SVN r23582]
2004-07-15 14:23:19 +00:00
Michael Glassford
2a5e1a36b5 Add read_lock and write_lock and related classes; modify lock constructors; add promote() that throws exception if it fails; fix enum definition.
[SVN r23581]
2004-07-15 14:21:37 +00:00
Michael Glassford
2e10da00ba Add cancellation guard.
[SVN r23417]
2004-07-09 09:52:39 +00:00
Michael Glassford
af4b2d5d2a Changes for WinCE.
[SVN r23416]
2004-07-09 09:50:44 +00:00
Michael Glassford
a89ec945c0 Apply patch for SGI MIPSpro compiler.
[SVN r23406]
2004-07-08 14:42:04 +00:00
Michael Glassford
08eb9eed48 Add title.
[SVN r23405]
2004-07-08 13:52:15 +00:00
Michael Glassford
7ed1a79ab8 Apply min/max fixes from main branch.
[SVN r23196]
2004-06-25 20:45:38 +00:00
Michael Glassford
18974b3cb4 Remove rw* files that have been renamed to read_write_*
[SVN r23195]
2004-06-25 20:41:54 +00:00
Michael Glassford
c973faf627 Fix enums, constructors; TimedReadWriteLock concept refines TryReadWriteLock; cleanup: always #include <boost/thread/detail/config.hpp> first; eliminate tabs; etc.
[SVN r23194]
2004-06-25 20:40:34 +00:00
Michael Glassford
6ffcde749a Remove HTML files that have been converted to BoostBook format.
[SVN r23193]
2004-06-25 20:40:21 +00:00
Michael Glassford
42840199aa Update release notes.
[SVN r23192]
2004-06-25 20:33:13 +00:00
Michael Glassford
1addb6ad9b Cleanup: always #include <boost/thread/detail/config.hpp> first; eliminate tabs; etc.
[SVN r23188]
2004-06-25 20:04:34 +00:00
Michael Glassford
1dbdb77ed7 Add option to build as static library.
[SVN r23187]
2004-06-25 19:52:44 +00:00
Michael Glassford
430ebf66f9 Apply min/max fixes from main branch.
[SVN r23186]
2004-06-25 19:49:44 +00:00
Michael Glassford
97562928a8 Cleanup: always #include <boost/thread/detail/config.hpp> first; eliminate tabs; etc.
[SVN r23185]
2004-06-25 19:36:47 +00:00
Michael Glassford
45aabefb4d Cleanup: always #include <boost/thread/detail/config.hpp> first.
[SVN r23184]
2004-06-25 19:22:18 +00:00
Michael Glassford
b0e970863b Proofreeding changes.
[SVN r23183]
2004-06-25 19:19:17 +00:00
Michael Glassford
3468fb61bc Convert documentation to BoostBook format.
[SVN r23182]
2004-06-25 19:17:49 +00:00
Michael Glassford
5982a97bdf Renamed from rw_* to read_write*.
[SVN r23161]
2004-06-22 22:17:17 +00:00
Michael Glassford
ffef009696 Renamed from test_rw_mutex.cpp.
[SVN r23160]
2004-06-22 22:16:47 +00:00
Michael Glassford
c8f181e461 Renamed from rw_mutex.cpp.
[SVN r23159]
2004-06-22 22:14:45 +00:00
Michael Glassford
7b84d69915 Renamed from rw_mutex-ref.xml.
[SVN r23158]
2004-06-22 22:06:21 +00:00
Michael Glassford
bbb8efe58f Renamed from rw_lock.hpp.
[SVN r23157]
2004-06-22 21:59:09 +00:00
Michael Glassford
63209e3c69 Renamed from rw_mutex.hpp.
[SVN r23156]
2004-06-22 21:57:38 +00:00
Michael Glassford
2272c322f9 Proofreeding changes.
[SVN r23155]
2004-06-22 21:37:24 +00:00
Michael Glassford
36acb80412 Add read/write mutex and related concepts.
[SVN r23154]
2004-06-22 21:36:32 +00:00
Michael Glassford
b72142cef7 Add entry for "undefined behavior".
[SVN r23153]
2004-06-22 21:35:11 +00:00
Michael Glassford
6dd6f51faa Remove documentation for unreleased thread pool.
[SVN r23152]
2004-06-22 21:33:55 +00:00
Michael Glassford
82630dc9bb Fix inconsistencies found while working on documentation.
[SVN r23151]
2004-06-22 21:28:53 +00:00
Michael Glassford
3402aea7c1 Change enumeration from anonymous to xtime_clock_types and remove unused clock types.
[SVN r23150]
2004-06-22 21:25:58 +00:00
Michael Glassford
5c4bd8e9c9 Finish conversion of documentation to BoostBook format.
[SVN r23122]
2004-06-18 21:30:19 +00:00
Michael Glassford
a11748d187 Finish conversion of documentation to BoostBook format.
[SVN r23048]
2004-06-07 21:45:26 +00:00
Michael Glassford
dc906613dc Finish conversion of documentation to BoostBook format.
[SVN r23047]
2004-06-07 19:04:02 +00:00
Michael Glassford
b69bdd3918 Finish conversion of documentation to BoostBook format.
[SVN r23046]
2004-06-07 16:01:05 +00:00
Michael Glassford
d90ef5eeef Finish conversion of documentation to BoostBook format.
[SVN r23045]
2004-06-07 14:42:24 +00:00
Michael Glassford
641d658a10 Finish conversion of documentation to BoostBook format.
[SVN r23044]
2004-06-07 14:30:36 +00:00
Michael Glassford
fef99d3db2 Finish conversion of documentation to BoostBook format.
[SVN r23021]
2004-06-03 16:36:57 +00:00
Michael Glassford
0fc8d8897d Finish conversion of documentation to BoostBook format.
[SVN r23011]
2004-06-02 19:38:15 +00:00
Michael Glassford
ad9f6244b0 Finish conversion of documentation to BoostBook format.
[SVN r23010]
2004-06-02 19:29:37 +00:00
Michael Glassford
59d082202c Finish conversion of documentation to BoostBook format.
[SVN r23009]
2004-06-02 19:24:03 +00:00
Michael Glassford
b7549a5bae Finish conversion of documentation to BoostBook format.
[SVN r23008]
2004-06-02 19:12:58 +00:00
Michael Glassford
f0dce755bb Finish conversion of documentation to BoostBook format.
[SVN r22957]
2004-05-27 19:43:24 +00:00
Michael Glassford
c1261d6df3 Proofreeding changes.
[SVN r22956]
2004-05-27 19:42:22 +00:00
Michael Glassford
1fb0dac16d Proofreeding changes.
[SVN r22955]
2004-05-27 19:34:39 +00:00
Michael Glassford
424d02fafa Proofreeding changes.
[SVN r22954]
2004-05-27 19:21:12 +00:00
Michael Glassford
52717aaa75 Finish conversion of documentation to BoostBook format.
[SVN r22953]
2004-05-27 15:49:50 +00:00
Michael Glassford
335f85ad5b Allow a mutex to be named, which allows it to be shared between two or more processes; currently implemented only for Win32.
Win32: use critical section instead of mutex whenever possible; abstract common code into functions.


[SVN r22827]
2004-05-15 02:02:43 +00:00
Michael Glassford
7da456edca Restore unintentionallly deleted BOOST_THREAD_DECL.
[SVN r22742]
2004-05-05 02:27:45 +00:00
Michael Glassford
f50176946d * Add lock promotion and demotion.
* Rename to improve consistency and eliminate abbreviations:
* Change try lock & timed lock constructor parameters for consistency.
* Add many assertions to test validity of mutex state and operations.
See change log in file for more details.


[SVN r22741]
2004-05-05 02:17:29 +00:00
Michael Glassford
aeafcbb822 Added MPTasks implementation; added comments to change log.
[SVN r22545]
2004-03-23 17:55:16 +00:00
Michael Glassford
171b890972 Added change log, fixed errors in comments, removed "unused parameter" warning.
[SVN r22544]
2004-03-23 17:47:29 +00:00
Michael Glassford
89a9531d34 Add missing pthread_mutexattr_destroy() to recursive_mutex::recursive_mutex() and recursive_try_mutex::recursive_try_mutex().
[SVN r22527]
2004-03-19 21:24:50 +00:00
Michael Glassford
3259f681a4 Merge fixes from main branch.
[SVN r22321]
2004-02-19 01:10:56 +00:00
Michael Glassford
17f72cf580 Merge minor changes from main branch.
[SVN r22320]
2004-02-19 01:10:07 +00:00
Michael Glassford
e03f0ed008 Merge minor changes from main branch.
[SVN r22319]
2004-02-19 01:00:42 +00:00
Michael Glassford
0804944002 Merge auto link changes from main branch.
[SVN r22318]
2004-02-19 00:57:36 +00:00
Michael Glassford
8e5d5002cd Merge fixes from main branch into thread_dev branch.
[SVN r22306]
2004-02-18 00:45:51 +00:00
Michael Glassford
008aaeaeee Merge fixes from HEAD into thread_dev branch.
[SVN r22238]
2004-02-11 16:02:52 +00:00
William E. Kempf
c1283bb731 Fixed thread join bugs. Fixed mutex creation bugs.
[SVN r18176]
2003-04-03 22:56:50 +00:00
William E. Kempf
46b1a4d1e3 Documented conditions with BoostBook
[SVN r18159]
2003-04-02 21:37:26 +00:00
William E. Kempf
ff6e0df2bc Removed <a> link.
[SVN r18150]
2003-04-01 15:41:51 +00:00
William E. Kempf
9cb9224b3c More BoostBook changes.
[SVN r18149]
2003-04-01 15:29:55 +00:00
William E. Kempf
5ea5494172 Added catalog.xml to .cvsignore.
[SVN r18145]
2003-04-01 01:46:42 +00:00
William E. Kempf
e4c27981d0 Added .cvsignore in doc directory.
[SVN r18144]
2003-04-01 01:45:24 +00:00
William E. Kempf
fe61772d47 Further conversions to DocBook.
[SVN r18143]
2003-04-01 01:44:32 +00:00
William E. Kempf
a437d6d7f6 Started migrating to Boost.Book.
[SVN r18117]
2003-03-27 23:24:44 +00:00
William E. Kempf
c9f52098b9 More changes for named mutexes.
[SVN r18063]
2003-03-22 22:28:57 +00:00
William E. Kempf
a15a35a4b6 Factored out named object support and made mutex a named object.
[SVN r17981]
2003-03-18 23:30:51 +00:00
William E. Kempf
14c8137ba6 Fixed name encoding algorithm.
[SVN r17929]
2003-03-14 22:56:29 +00:00
William E. Kempf
5caf9ed169 Further changes for name mapping in shared_memory.
[SVN r17896]
2003-03-13 18:43:55 +00:00
William E. Kempf
5da4a7b105 Added portable name mapping.
[SVN r17868]
2003-03-12 23:47:36 +00:00
William E. Kempf
91c4af37ad Fixed POSIX issues for shared_memory.
[SVN r17817]
2003-03-11 16:08:51 +00:00
William E. Kempf
5848dc2f56 More shared_memory changes.
[SVN r17816]
2003-03-11 15:47:22 +00:00
William E. Kempf
efa12b1db9 More shared_memory changes.
[SVN r17802]
2003-03-10 23:10:13 +00:00
William E. Kempf
58b6eba0ea Updated shared_memory to compile on Linux.
[SVN r17801]
2003-03-10 20:55:29 +00:00
William E. Kempf
f73253fcf5 Udpated shared_memory.
[SVN r17800]
2003-03-10 20:14:12 +00:00
William E. Kempf
3627dfc3b7 Removed warnings.
[SVN r17606]
2003-02-23 18:09:27 +00:00
William E. Kempf
f8ebb9a127 Added timed_join() and cancelled()
[SVN r17309]
2003-02-10 17:08:04 +00:00
William E. Kempf
2a0f57a8de Reformatted code and updated copyrights
[SVN r17274]
2003-02-07 22:50:55 +00:00
William E. Kempf
da7278acef Removed obsolete files.
[SVN r17273]
2003-02-07 22:22:35 +00:00
William E. Kempf
b17eb23f2e Updated thread_group to use the new thread reference implementation
[SVN r17135]
2003-01-31 21:23:11 +00:00
William E. Kempf
8e01ac5d04 Updated Jamfile
[SVN r17133]
2003-01-31 20:00:27 +00:00
William E. Kempf
5d6a1633e0 merged with thread_bae
[SVN r17100]
2003-01-30 23:05:44 +00:00
William E. Kempf
2e6f9a785e Updated Jamfile
[SVN r17098]
2003-01-30 21:20:28 +00:00
William E. Kempf
4e1acef27e Merged thread_base
[SVN r17096]
2003-01-30 20:51:12 +00:00
William E. Kempf
73e482832d Added bjam.log to .cvsignore
[SVN r17092]
2003-01-30 16:44:15 +00:00
William E. Kempf
949b332337 Removed warning messages
[SVN r17091]
2003-01-30 16:42:39 +00:00
nobody
244cfd3f01 This commit was manufactured by cvs2svn to create branch 'thread_dev'.
[SVN r17055]
2003-01-27 22:44:08 +00:00
William E. Kempf
3239fe0c22 Updated test cases for thread::attributes.
[SVN r17001]
2003-01-22 23:08:26 +00:00
William E. Kempf
ca10110aa7 Updated tests for new thread design
[SVN r16984]
2003-01-21 22:57:30 +00:00
William E. Kempf
fd4c76c7a5 Add cancellation_guard and test cases.
[SVN r16964]
2003-01-20 20:20:21 +00:00
William E. Kempf
60d7c84aa2 Fixed creation bug.
[SVN r16925]
2003-01-17 23:17:54 +00:00
William E. Kempf
c043efa346 Updated exceptions and removed conditional compilation.
[SVN r16897]
2003-01-13 23:05:14 +00:00
William E. Kempf
dab1961b5a Fixed bug in internal id() when pthread_t isn't a pointer type.
[SVN r16844]
2003-01-09 22:51:24 +00:00
William E. Kempf
6f94d26c50 Added full support for 'id' semantics.
[SVN r16842]
2003-01-09 21:17:39 +00:00
William E. Kempf
83baf142f2 Added thread::attributes.
[SVN r16808]
2003-01-08 22:25:15 +00:00
William E. Kempf
88bb39e3ce Fixed bug with cleanup_slots definition order on POSIX implementations.
[SVN r16807]
2003-01-08 22:22:54 +00:00
William E. Kempf
48ad27558a Updated new classes to DLL implementation. Worked out tss issues. Started thread implementation.
[SVN r16791]
2003-01-07 23:16:54 +00:00
William E. Kempf
a0ba7f174c Updated new classes to DLL implementation. Worked out tss issues. Started thread implementation.
[SVN r16789]
2003-01-07 23:08:51 +00:00
William E. Kempf
6e60d33181 Merged thread_development with thread_dev
[SVN r16776]
2003-01-06 23:24:59 +00:00
William E. Kempf
bc69926604 Merged thread_development with thread_dev
[SVN r16775]
2003-01-06 22:47:51 +00:00
nobody
d90825f7f9 This commit was manufactured by cvs2svn to create branch 'thread_dev'.
[SVN r16771]
2003-01-06 16:06:38 +00:00
169 changed files with 12816 additions and 8666 deletions

View File

@@ -1,2 +1,3 @@
bin*
*.pdb
bjam.log

View File

@@ -1,122 +1,132 @@
# Copyright 2006 Roland Schwarz.
# 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)
# Copyright (C) 2001-2003
# William E. Kempf
#
# This work is a reimplementation along the design and ideas
# of William E. Kempf.
# Permission to use, copy, modify, distribute and sell this software
# and its documentation for any purpose is hereby granted without fee,
# provided that the above copyright notice appear in all copies and
# that both that copyright notice and this permission notice appear
# in supporting documentation. William E. Kempf makes no representations
# about the suitability of this software for any purpose.
# It is provided "as is" without express or implied warranty.
#
# Boost.Threads build Jamfile
#
# Additional configuration variables used:
# 1. PTW32 may be used on Win32 platforms to specify that the pthreads-win32
# library should be used instead of "native" threads. This feature is
# mostly used for testing and it's generally recommended you use the
# native threading libraries instead. PTW32 should be set to be a list
# of two strings, the first specifying the installation path of the
# pthreads-win32 library and the second specifying which library
# variant to link against (see the pthreads-win32 documentation).
# Example: jam -sPTW32="c:\pthreads-win32 pthreadVCE.lib"
# Declare the location of this subproject relative to the root.
subproject libs/thread/build ;
# Include threads.jam for Boost.Threads global build information.
# This greatly simplifies the Jam code needed to configure the build
# for the various Win32 build types.
import ./threads ;
# pthreads is compiled on all platforms when available
if [ threads::is-pthread-available ] {
template pthread_base
: ## sources ##
[ threads::cpp_source ../src/pthread :
thread
mutex
recursive_mutex
condition
exceptions
xtime
once
tss
]
: ## requirements ##
threads::lib-pthread
<sysinclude>$(BOOST_ROOT)
<threading>multi
<define>BOOST_THREAD_POSIX
common-variant-tag
<borland><*><cxxflags>-w-8004
<borland><*><cxxflags>-w-8057
;
{
CPP_SOURCES =
barrier
condition
exceptions
mutex
named
once
recursive_mutex
read_write_mutex
shared_memory
thread
threadmon
thread_pool
tss
xtime
;
lib boost_thread_pthread
: <template>pthread_base
: ## requirements ##
<define>BOOST_THREAD_BUILD_LIB=1
;
template boost_thread_lib_base
: ## sources ##
<template>thread_base
../src/$(CPP_SOURCES).cpp
: ## requirements ##
<define>BOOST_THREAD_BUILD_LIB=1
<runtime-link>static
# the common names rule ensures that the library will
# be named according to the rules used by the install
# and auto-link features:
common-variant-tag
: ## default build ##
;
dll boost_thread_pthread
: <template>pthread_base
: ## requirements ##
<runtime-link>dynamic
<define>BOOST_THREAD_BUILD_DLL=1
;
template thread_dll_base
: ## sources ##
<template>thread_base
../src/$(CPP_SOURCES).cpp
: ## requirements ##
<define>BOOST_THREAD_BUILD_DLL=1
<runtime-link>dynamic
# the common names rule ensures that the library will
# be named according to the rules used by the install
# and auto-link features:
common-variant-tag
: ## default build ##
;
stage bin-stage
: <dll>boost_thread_pthread
<lib>boost_thread_pthread
;
lib $(boost_thread_lib_name)
: ## sources ##
<template>boost_thread_lib_base
: ## requirements ##
<define>BOOST_THREAD_LIB_NAME=$(boost_thread_lib_name)
: ## default build ##
;
install thread_pthread lib
: <dll>boost_thread_pthread
<lib>boost_thread_pthread
;
dll $(boost_thread_lib_name)
: ## sources ##
<template>thread_dll_base
: ## requirements ##
<define>BOOST_THREAD_LIB_NAME=$(boost_thread_lib_name)
: ## default build ##
;
# the next is true on platforms where pthreads is native threading lib
if [ threads::is-native-on-build-os pthread ] {
lib boost_thread
: <template>pthread_base
: ## requirements ##
<define>BOOST_THREAD_BUILD_LIB=1
;
stage bin-stage
: <dll>$(boost_thread_lib_name)
<lib>$(boost_thread_lib_name)
;
dll boost_thread
: <template>pthread_base
: ## requirements ##
<runtime-link>dynamic
<define>BOOST_THREAD_BUILD_DLL=1
;
}
install thread lib
: <dll>$(boost_thread_lib_name)
<lib>$(boost_thread_lib_name)
;
if $(boost_thread_lib_settings_ptw32)
{
lib $(boost_thread_lib_name_ptw32)
: ## sources ##
<template>boost_thread_lib_base
: ## requirements ##
<define>BOOST_THREAD_LIB_NAME=$(boost_thread_lib_name_ptw32)
$(pthreads-win32)
;
dll $(boost_thread_lib_name_ptw32)
: ## sources ##
<template>thread_dll_base
: ## requirements ##
<define>BOOST_THREAD_LIB_NAME=$(boost_thread_lib_name_ptw32)
$(pthreads-win32)
;
stage bin-stage
: <dll>$(boost_thread_lib_name_ptw32)
<lib>$(boost_thread_lib_name_ptw32)
;
install thread lib
: <dll>$(boost_thread_lib_name_ptw32)
<lib>$(boost_thread_lib_name_ptw32)
;
}
}
if [ threads::is-native-on-build-os win32 ] {
template win32_base
: ## sources ##
[ threads::cpp_source ../src/win32 :
thread
exceptions
xtime
tss
tss_hooks
tss_dll
tss_pe
]
: ## requirements ##
<sysinclude>$(BOOST_ROOT)
<threading>multi
common-variant-tag
<borland><*><cxxflags>-w-8004
<borland><*><cxxflags>-w-8057
;
lib boost_thread
: <template>win32_base
: ## requirements ##
<define>BOOST_THREAD_BUILD_LIB=1
;
dll boost_thread
: <template>win32_base
: ## requirements ##
<runtime-link>dynamic
<define>BOOST_THREAD_BUILD_DLL=1
;
}
stage bin-stage
: <dll>boost_thread
<lib>boost_thread
;
install thread lib
: <dll>boost_thread
<lib>boost_thread
;

View File

@@ -1,61 +1,12 @@
# Copyright 2006 Roland Schwarz.
# 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)
#
# This work is a reimplementation along the design and ideas
# of William E. Kempf.
import thread ;
# Declare the uses system library
lib pthread : : <name>pthread ;
project boost/thread
: source-location ../src
: requirements <threading>multi
<link>static:<define>BOOST_THREAD_BUILD_LIB=1
<link>shared:<define>BOOST_THREAD_BUILD_DLL=1
: default-build <threading>multi [ thread.default-api ]
: source-location ../src
: usage-requirements <library>pthread
;
# build the pthread based variant
lib boost_thread_pthread
: ## sources ##
pthread/thread.cpp
pthread/mutex.cpp
pthread/recursive_mutex.cpp
pthread/condition.cpp
pthread/exceptions.cpp
pthread/xtime.cpp
pthread/tss.cpp
: ## requirements ##
<define>BOOST_THREAD_POSIX
<thrd-api>pthread
;
# use pthread on platforms where pthread is considered native
lib boost_thread
: ## sources ##
pthread/thread.cpp
pthread/mutex.cpp
pthread/recursive_mutex.cpp
pthread/condition.cpp
pthread/exceptions.cpp
pthread/xtime.cpp
pthread/tss.cpp
: ## requirements ##
<define>BOOST_THREAD_POSIX
<thrd-api>pthread
;
# the win32 native variant
lib boost_thread
: ## sources ##
win32/thread.cpp
win32/exceptions.cpp
win32/xtime.cpp
win32/tss.cpp
win32/tss_hooks.cpp
win32/tss_dll.cpp
win32/tss_pe.cpp
: ## requirements ##
<thrd-api>win32
;
CPP_SOURCES = condition mutex recursive_mutex thread tss xtime once exceptions ;
lib boost_thread : $(CPP_SOURCES).cpp ;

View File

@@ -1,70 +0,0 @@
# Copyright 2006 Roland Schwarz.
# 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)
#
# This work is a reimplementation along the design and ideas
# of William E. Kempf.
import modules ;
import os ;
import feature ;
import property ;
# supported threading api's
feature.feature thrd-api : pthread win32 : symmetric ;
# save a reference to the original lib rule
IMPORT : lib : $(__name__) : type.lib ;
# local override of the global lib rule
rule lib ( name : sources * : requirements * : default-build * : usage-requirements * )
{
if <thrd-api>pthread in $(requirements)
{
if [ os.name ] = "NT"
{
local PTW32_INCLUDE = [ modules.peek : PTW32_INCLUDE ] ;
local PTW32_LIB = [ modules.peek : PTW32_LIB ] ;
if $(PTW32_INCLUDE) && $(PTW32_LIB)
{
requirements =
[ property.refine $(requirements) :
<define>BOOST_HAS_PTHREADS
<include>$(PTW32_INCLUDE)
<library>$(PTW32_LIB)
] ;
}
else
{
requirements += <build>no ;
# it would be nice if this message appears only once ...
# but I cannot figure out how to detectd the second phase.
echo "******************************************************" ;
echo "Building Boost.Thread without pthread support" ;
echo "If you need pthread you should specify the paths." ;
echo "For example:" ;
echo "PTW32_INCLUDE=C:\\Program Files\\ptw32\\Pre-built2\\include" ;
echo "PTW32_LIB=C:\\Program Files\\ptw32\\Pre-built2\\lib\\pthreadVC2.lib" ;
echo "******************************************************" ;
}
}
}
return [ type.lib $(name) : $(sources) : $(requirements) : $(default-build) : $(usage-requirements) ] ;
}
# auto export of rule lib to calling module only
IMPORT $(__name__) : lib : [ CALLER_MODULE 1 ] : lib ;
rule default-api
{
if [ os.name ] = "NT"
{
return <thrd-api>win32 ;
}
else
{
return <thrd-api>pthread ;
}
}

View File

@@ -1,65 +1,45 @@
# Copyright 2006 Roland Schwarz.
# 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)
# Copyright (C) 2001-2003
# William E. Kempf
#
# This work is a reimplementation along the design and ideas
# of William E. Kempf.
# Permission to use, copy, modify, distribute and sell this software
# and its documentation for any purpose is hereby granted without fee,
# provided that the above copyright notice appear in all copies and
# that both that copyright notice and this permission notice appear
# in supporting documentation. William E. Kempf makes no representations
# about the suitability of this software for any purpose.
# It is provided "as is" without express or implied warranty.
# find out if pthread is available on current build platform
rule threads::is-pthread-available
# Do some OS-specific setup
{
if $(OS) = "NT" {
if $(PTW32_INCLUDE) && $(PTW32_LIB) {
return true ;
}
else {
ECHO "******************************************************" ;
ECHO "Building Boost.Thread without pthread support" ;
ECHO "If you need pthread you should specify the paths." ;
ECHO "For example:" ;
ECHO "PTW32_INCLUDE=C:\\Program Files\\ptw32\\Pre-built2\\include" ;
ECHO "PTW32_LIB=C:\\Program Files\\ptw32\\Pre-built2\\lib\\pthreadVC2.lib" ;
ECHO "******************************************************" ;
}
}
else if $(OS) = "LINUX" {
return true ;
}
else { ## assume pthread is available on unknown os for now
return true ;
}
}
# find the native library variant for current build os
rule threads::is-native-on-build-os ( libvariant )
{
if $(OS) = "NT" {
if $(libvariant) = win32 { return true ; }
}
else if $(OS) = "LINUX" {
if $(libvariant) = pthread { return true ; }
}
else { ## assume pthread is native on others for now
if $(libvariant) = pthread { return true ; }
}
}
# utility to prepend the source path to the cpp sources
rule threads::cpp_source ( path : sources * )
{
return $(path)/$(sources).cpp ;
}
# impose the pthread library and include path on the requirements
rule threads::lib-pthread ( toolset variant : subvariant-path properties * )
{
if $(OS) = "NT" && $(PTW32_INCLUDE) && $(PTW32_LIB) {
properties = [ impose-requirements $(properties) :
<define>BOOST_HAS_PTHREADS
<include>$(PTW32_INCLUDE)
<library-file>$(PTW32_LIB) ] ;
#thread library name
boost_thread_lib_name = boost_thread ;
#thread library name with "pthreads-win32" library
boost_thread_lib_name_ptw32 = boost_thread_ptw32 ;
if $(NT)
{
if $(PTW32_DIR)
{
if $(PTW32_LIB)
{
boost_thread_lib_settings_ptw32 =
<define>BOOST_HAS_PTHREADS
<define>PtW32NoCatchWarn
<include>$(PTW32_DIR)/pre-built/include
<library-file>$(PTW32_DIR)/pre-built/lib/$(PTW32_LIB)
;
}
}
return $(subvariant-path) $(properties) ;
}
template thread_base
: ## sources ##
: ## requirements ##
<sysinclude>$(BOOST_ROOT)
<threading>multi
<borland><*><cxxflags>-w-8004
<borland><*><cxxflags>-w-8057
: ## default build ##
;
}

BIN
build/threads.mcp Normal file

Binary file not shown.

3
doc/.cvsignore Normal file
View File

@@ -0,0 +1,3 @@
bin
html
catalog.xml

View File

@@ -1,6 +1,5 @@
project boost/doc ;
import boostbook : boostbook ;
import toolset ;
toolset.using doxygen ;
boostbook thread : thread.xml ;
boostbook doc : thread.xml ;

View File

@@ -75,4 +75,4 @@
</method-group>
</class>
</namespace>
</header>
</header>

View File

@@ -54,7 +54,7 @@ last-revision="$Date$">
<title>ACM Computing Surveys</title>
<volumenum>Vol. 5</volumenum>
<issuenum>No. 4</issuenum>
<date>December, 1973</date>
<date>December, 1983</date>
</biblioset>
<biblioset relation="article">
<author>0-201-63392-2

View File

@@ -55,4 +55,4 @@
<programlisting>bjam -sTOOLS=<emphasis>toolset</emphasis> test</programlisting>
</para>
</section>
</section>
</section>

View File

@@ -18,12 +18,6 @@
<section id="threads.concepts.mutexes">
<title>Mutexes</title>
<note>Certain changes to the mutexes and lock concepts are
currently under discussion. In particular, the combination of
the multiple lock concepts into a single lock concept
is likely, and the combination of the multiple mutex
concepts into a single mutex concept is also possible.</note>
<para>A mutex (short for mutual-exclusion) object is used to serialize
access to a resource shared between multiple threads. The
@@ -195,7 +189,7 @@
and constructed for the Mutex object.</para>
<para>A Mutex is
<ulink url="../../libs/utility/utility.htm#Class%20noncopyable">
<ulink url="../../utility/utility.htm#Class%20noncopyable">
NonCopyable</ulink>.</para>
<para>For a Mutex type <code>M</code>
and an object <code>m</code> of that type,
@@ -735,11 +729,6 @@
<section id="threads.concepts.read-write-mutexes">
<title>Read/Write Mutexes</title>
<note>Since the read/write mutex and related classes are new,
both interface and implementation are liable to change
in future releases of &Boost.Threads;.
The lock concepts and lock promotion and demotion in particular
are still under discussion and very likely to change.</note>
<para>A read/write mutex (short for reader/writer mutual-exclusion) object
is used to serialize access to a resource shared between multiple
@@ -1097,9 +1086,12 @@
both threads will be waiting for the other to release their read-lock.
</para>
<para>Currently, &Boost.Threads; supports lock promotion
through <code>promote()</code>, <code>try_promote()</code>,
and <code>timed_promote()</code> operations.</para>
<para>Currently, &Boost.Threads; supports lock promotion only
through <code>try_promote()</code> and <code>timed_promote()</code>
operations. <note>Note that, with <code>timed_promote()</code>,
temporary deadlock can still occur, but since the promotion
attempt will eventually time out the deadlock will eventually
end.</note></para>
</section>
<section id="threads.concepts.read-write-locking-strategies.demotion">
@@ -1180,7 +1172,7 @@
the specified time, if any). A
read-lock will be granted to all pending readers
before any other thread can acquire a write-lock.
<para>TODO: try-lock, timed-lock.</para>
<p>TODO: try-lock, timed-lock.</p>
</entry>
</row>
<row>
@@ -1188,7 +1180,7 @@
<entry>write-lock</entry>
<entry>Grant the write-lock immediately, if and
only if there are no pending read-lock requests.
<para>TODO: try-lock, timed-lock.</para>
<p>TODO: try-lock, timed-lock.</p>
</entry>
</row>
<row>
@@ -1200,7 +1192,7 @@
for read-locks exist. If other write-lock
requests exist, the lock is granted in accordance
with the intra-class scheduling policy.
<para>TODO: try-lock, timed-lock.</para>
<p>TODO: try-lock, timed-lock.</p>
</entry>
</row>
<row>
@@ -1212,18 +1204,18 @@
for read-locks exist. If other write-lock
requests exist, the lock is granted in accordance
with the intra-class scheduling policy.
<para>TODO: try-lock, timed-lock.</para>
<p>TODO: try-lock, timed-lock.</p>
</entry>
</row>
<row>
<entry>read-locked</entry>
<entry>promote</entry>
<entry><para>TODO</para></entry>
<entry><p>TODO</p></entry>
</row>
<row>
<entry>write-locked</entry>
<entry>demote</entry>
<entry><para>TODO</para></entry>
<entry><p>TODO</p></entry>
</row>
</tbody>
</tgroup>
@@ -1261,7 +1253,7 @@
<entry>Grant the additional read-lock immediately,
<emphasis role="bold">IF</emphasis> no outstanding
requests for a write-lock exist; otherwise TODO.
<para>TODO: try-lock, timed-lock.</para>
<p>TODO: try-lock, timed-lock.</p>
</entry>
</row>
<row>
@@ -1272,7 +1264,7 @@
releases its lock. The read lock will be granted
once no other outstanding write-lock requests
exist.
<para>TODO: try-lock, timed-lock.</para>
<p>TODO: try-lock, timed-lock.</p>
</entry>
</row>
<row>
@@ -1289,7 +1281,7 @@
is granted in accordance with the intra-class
scheduling policy. This request will be granted
before any new read-lock requests are granted.
<para>TODO: try-lock, timed-lock.</para>
<p>TODO: try-lock, timed-lock.</p>
</entry>
</row>
<row>
@@ -1301,18 +1293,18 @@
granted in accordance with the intra-class
scheduling policy. This request will be granted
before any new read-lock requests are granted.
<para>TODO: try-lock, timed-lock.</para>
<p>TODO: try-lock, timed-lock.</p>
</entry>
</row>
<row>
<entry>read-locked</entry>
<entry>promote</entry>
<entry><para>TODO</para></entry>
<entry><p>TODO</p></entry>
</row>
<row>
<entry>write-locked</entry>
<entry>demote</entry>
<entry><para>TODO</para></entry>
<entry><p>TODO</p></entry>
</row>
</tbody>
</tgroup>
@@ -1355,7 +1347,7 @@
write-locks is granted and released. If other
read-lock requests exist, all read-locks will be
granted as a group.
<para>TODO: try-lock, timed-lock.</para>
<p>TODO: try-lock, timed-lock.</p>
</entry>
</row>
<row>
@@ -1366,7 +1358,7 @@
outstanding write-lock requests exist, they will
have to wait until all current read-lock requests
are serviced.
<para>TODO: try-lock, timed-lock.</para>
<p>TODO: try-lock, timed-lock.</p>
</entry>
</row>
<row>
@@ -1385,7 +1377,7 @@
lock will be granted to one of them in accordance
with the intra-class scheduling policy.</para>
<para>TODO: try-lock, timed-lock.</para>
<p>TODO: try-lock, timed-lock.</p>
</entry>
</row>
<row>
@@ -1399,18 +1391,18 @@
released. If other write-lock requests exist,
this lock will be granted in accordance with the
intra-class scheduling policy.
<para>TODO: try-lock, timed-lock.</para>
<p>TODO: try-lock, timed-lock.</p>
</entry>
</row>
<row>
<entry>read-locked</entry>
<entry>promote</entry>
<entry><para>TODO</para></entry>
<entry><p>TODO</p></entry>
</row>
<row>
<entry>write-locked</entry>
<entry>demote</entry>
<entry><para>TODO</para></entry>
<entry><p>TODO</p></entry>
</row>
</tbody>
</tgroup>
@@ -1451,7 +1443,7 @@
write-lock requests exist, this lock will not
be granted until at least one of the write-locks
is granted and released.
<para>TODO: try-lock, timed-lock.</para>
<p>TODO: try-lock, timed-lock.</p>
</entry>
</row>
<row>
@@ -1464,7 +1456,7 @@
exist, exactly one read-lock request will be
granted before the next write-lock is granted.
</para>
<para>TODO: try-lock, timed-lock.</para>
<p>TODO: try-lock, timed-lock.</p>
</entry>
</row>
<row>
@@ -1485,7 +1477,7 @@
in accordance with the intra-class
scheduling policy.</para></entry>
<para>TODO: try-lock, timed-lock.</para>
<p>TODO: try-lock, timed-lock.</p>
</row>
<row>
<entry>write-locked</entry>
@@ -1498,18 +1490,18 @@
released. If other write-lock requests exist,
this lock will be granted in accordance with
the intra-class scheduling policy.
<para>TODO: try-lock, timed-lock.</para>
<p>TODO: try-lock, timed-lock.</p>
</entry>
</row>
<row>
<entry>read-locked</entry>
<entry>promote</entry>
<entry><para>TODO</para></entry>
<entry><p>TODO</p></entry>
</row>
<row>
<entry>write-locked</entry>
<entry>demote</entry>
<entry><para>TODO</para></entry>
<entry><p>TODO</p></entry>
</row>
</tbody>
</tgroup>
@@ -1553,7 +1545,7 @@
requirements and constructed for the ReadWriteMutex object.</para>
<para>A ReadWriteMutex is
<ulink url="../../libs/utility/utility.htm#Class%20noncopyable">NonCopyable</ulink>.
<ulink url="../../utility/utility.htm#Class%20noncopyable">NonCopyable</ulink>.
</para>
<para>For a ReadWriteMutex type <code>M</code>,
@@ -1585,21 +1577,9 @@
</entry>
</row>
<row>
<entry><code>M::scoped_read_write_lock</code></entry>
<entry><code>M::scoped_lock</code></entry>
<entry>A type meeting the
<link linkend="threads.concepts.ScopedReadWriteLock">ScopedReadWriteLock</link>
requirements. </entry>
</row>
<row>
<entry><code>M::scoped_read_lock</code></entry>
<entry>A type meeting the
<link linkend="threads.concepts.ScopedLock">ScopedLock</link>
requirements. </entry>
</row>
<row>
<entry><code>M::scoped_write_lock</code></entry>
<entry>A type meeting the
<link linkend="threads.concepts.ScopedLock">ScopedLock</link>
<link linkend="threads.concepts.ScopedReadWriteMutex">ScopedReadWriteLock</link>
requirements. </entry>
</row>
</tbody>
@@ -1630,21 +1610,9 @@
<tbody>
<row>
<entry><code>M::scoped_try_read_write_lock</code></entry>
<entry><code>M::scoped_try_lock</code></entry>
<entry>A type meeting the
<link linkend="threads.concepts.ScopedTryReadWriteLock">ScopedTryReadWriteLock</link>
requirements.</entry>
</row>
<row>
<entry><code>M::scoped_try_read_lock</code></entry>
<entry>A type meeting the
<link linkend="threads.concepts.ScopedTryLock">ScopedTryLock</link>
requirements.</entry>
</row>
<row>
<entry><code>M::scoped_try_write_lock</code></entry>
<entry>A type meeting the
<link linkend="threads.concepts.ScopedTryLock">ScopedTryLock</link>
<link linkend="threads.concepts.ScopedReadWriteMutex">ScopedTryReadWriteLock</link>
requirements.</entry>
</row>
</tbody>
@@ -1675,21 +1643,9 @@
<tbody>
<row>
<entry><code>M::scoped_timed_read_write_lock</code></entry>
<entry><code>M::scoped_timed_lock</code></entry>
<entry>A type meeting the
<link linkend="threads.concepts.ScopedTimedReadWriteLock">ScopedTimedReadWriteLock</link>
requirements.</entry>
</row>
<row>
<entry><code>M::scoped_timed_read_lock</code></entry>
<entry>A type meeting the
<link linkend="threads.concepts.ScopedTimedLock">ScopedTimedLock</link>
requirements.</entry>
</row>
<row>
<entry><code>M::scoped_timed_write_lock</code></entry>
<entry>A type meeting the
<link linkend="threads.concepts.ScopedTimedLock">ScopedTimedLock</link>
<link linkend="threads.concepts.ScopedReadWriteMutex">ScopedTimedReadWriteLock</link>
requirements.</entry>
</row>
</tbody>
@@ -1907,19 +1863,6 @@
<para>Postcondition: <code>state() == read_write_lock_state::read_locked</code></para>
</entry>
</row>
<row>
<entry><code>lk.promote()</code></entry>
<entry>
<para>Throws <classname>boost::lock_error</classname>
if <code>state() != read_write_lock_state::read_locked</code>
or if the lock cannot be promoted because another lock
on the same mutex is already waiting to be promoted.</para>
<para>Makes a blocking attempt to convert the lock held on the associated
read/write mutex object from a read-lock to a write-lock without releasing
the lock.</para>
</entry>
</row>
<row>
<entry><code>lk.unlock()</code></entry>
<entry>
@@ -2248,9 +2191,9 @@
<entry><link linkend="threads.concepts.ScopedReadWriteLock">ScopedReadWriteLock</link></entry>
<entry><link linkend="threads.concepts.ReadWriteLock">ReadWriteLock</link></entry>
<entry>
<para><classname>boost::read_write_mutex::scoped_read_write_lock</classname></para>
<para><classname>boost::try_read_write_mutex::scoped_read_write_lock</classname></para>
<para><classname>boost::timed_read_write_mutex::scoped_read_write_lock</classname></para>
<para><classname>boost::read_write_mutex::scoped_lock</classname></para>
<para><classname>boost::try_read_write_mutex::scoped_lock</classname></para>
<para><classname>boost::timed_read_write_mutex::scoped_lock</classname></para>
</entry>
</row>
<row>
@@ -2262,8 +2205,8 @@
<entry><link linkend="threads.concepts.ScopedTryReadWriteLock">ScopedTryReadWriteLock</link></entry>
<entry><link linkend="threads.concepts.TryReadWriteLock">TryReadWriteLock</link></entry>
<entry>
<para><classname>boost::try_read_write_mutex::scoped_try_read_write_lock</classname></para>
<para><classname>boost::timed_read_write_mutex::scoped_try_read_write_lock</classname></para>
<para><classname>boost::try_read_write_mutex::scoped_try_lock</classname></para>
<para><classname>boost::timed_read_write_mutex::scoped_try_lock</classname></para>
</entry>
</row>
<row>
@@ -2275,7 +2218,7 @@
<entry><link linkend="threads.concepts.ScopedTimedReadWriteLock">ScopedTimedReadWriteLock</link></entry>
<entry><link linkend="threads.concepts.TimedReadWriteLock">TimedReadWriteLock</link></entry>
<entry>
<para><classname>boost::timed_read_write_mutex::scoped_timed_read_write_lock</classname></para>
<para><classname>boost::timed_read_write_mutex::scoped_timed_lock</classname></para>
</entry>
</row>
</tbody>
@@ -2283,4 +2226,4 @@
</table>
</section>
</section>
</section>
</section>

View File

@@ -89,4 +89,4 @@
</tgroup>
</informaltable>
</section>
</section>
</section>

View File

@@ -55,4 +55,4 @@
</constructor>
</class>
</namespace>
</header>
</header>

View File

@@ -1,8 +0,0 @@
<html>
<head>
<meta http-equiv="refresh" content="0; URL=../../../doc/html/threads.html">
</head>
<body>
Automatic redirection failed, please go to <a href="../../../doc/html/threads.html">../../../doc/html/threads.html</a>
</body>
</html>

View File

@@ -33,6 +33,7 @@
the specified locking strategy:
<informaltable>
<title>Supported Lock Types</title>
<tgroup cols="2" align="left">
<thead>
<row>
@@ -123,6 +124,7 @@
the specified locking strategies:
<informaltable>
<title>Supported Lock Types</title>
<tgroup cols="2" align="left">
<thead>
<row>
@@ -222,6 +224,7 @@
the specified locking strategies:
<informaltable>
<title>Supported Lock Types</title>
<tgroup cols="2" align="left">
<thead>
<row>
@@ -302,4 +305,4 @@
</destructor>
</class>
</namespace>
</header>
</header>

View File

@@ -83,4 +83,4 @@ void thread_proc()
</postconditions>
</function>
</namespace>
</header>
</header>

View File

@@ -431,4 +431,4 @@
and will be less likely to contain latent defects.</para>
<para>[Rationale provided by Beman Dawes]</para>
</section>
</section>
</section>

View File

@@ -45,9 +45,9 @@
<para>For classes that model related mutex concepts, see
<classname>try_read_write_mutex</classname> and <classname>timed_read_write_mutex</classname>.</para>
<para>The <classname>read_write_mutex</classname> class supplies the following typedefs,
which <link linkend="threads.concepts.read-write-lock-models">model</link>
the specified locking strategies:
<para>The <classname>read_write_mutex</classname> class supplies the following typedef,
which <link linkend="threads.concepts.read-write-lock-models">models</link>
the specified locking strategy:
<informaltable>
<tgroup cols="2" align="left">
@@ -59,17 +59,9 @@
</thead>
<tbody>
<row>
<entry>scoped_read_write_lock</entry>
<entry>scoped_lock</entry>
<entry><link linkend="threads.concepts.ScopedReadWriteLock">ScopedReadWriteLock</link></entry>
</row>
<row>
<entry>scoped_read_lock</entry>
<entry><link linkend="threads.concepts.ScopedLock">ScopedLock</link></entry>
</row>
<row>
<entry>scoped_write_lock</entry>
<entry><link linkend="threads.concepts.ScopedLock">ScopedLock</link></entry>
</row>
</tbody>
</tgroup>
</informaltable>
@@ -117,15 +109,7 @@
<purpose>Exposition only</purpose>
</inherit>
<typedef name="scoped_read_write_lock">
<type><emphasis>implementation-defined</emphasis></type>
</typedef>
<typedef name="scoped_read_lock">
<type><emphasis>implementation-defined</emphasis></type>
</typedef>
<typedef name="scoped_write_lock">
<typedef name="scoped_lock">
<type><emphasis>implementation-defined</emphasis></type>
</typedef>
@@ -170,7 +154,7 @@
<para>The <classname>try_read_write_mutex</classname> class supplies the following typedefs,
which <link linkend="threads.concepts.read-write-lock-models">model</link>
the specified locking strategies:
the specified locking strategy:
<informaltable>
<tgroup cols="2" align="left">
@@ -182,29 +166,13 @@
</thead>
<tbody>
<row>
<entry>scoped_read_write_lock</entry>
<entry>scoped_lock</entry>
<entry><link linkend="threads.concepts.ScopedReadWriteLock">ScopedReadWriteLock</link></entry>
</row>
<row>
<entry>scoped_try_read_write_lock</entry>
<entry>scoped_try_lock</entry>
<entry><link linkend="threads.concepts.ScopedTryReadWriteLock">ScopedTryReadWriteLock</link></entry>
</row>
<row>
<entry>scoped_read_lock</entry>
<entry><link linkend="threads.concepts.ScopedLock">ScopedLock</link></entry>
</row>
<row>
<entry>scoped_try_read_lock</entry>
<entry><link linkend="threads.concepts.ScopedTryLock">ScopedTryLock</link></entry>
</row>
<row>
<entry>scoped_write_lock</entry>
<entry><link linkend="threads.concepts.ScopedLock">ScopedLock</link></entry>
</row>
<row>
<entry>scoped_try_write_lock</entry>
<entry><link linkend="threads.concepts.ScopedTryLock">ScopedTryLock</link></entry>
</row>
</tbody>
</tgroup>
</informaltable>
@@ -247,27 +215,11 @@
<purpose>Exposition only</purpose>
</inherit>
<typedef name="scoped_read_write_lock">
<typedef name="scoped_lock">
<type><emphasis>implementation-defined</emphasis></type>
</typedef>
<typedef name="scoped_try_read_write_lock">
<type><emphasis>implementation-defined</emphasis></type>
</typedef>
<typedef name="scoped_read_lock">
<type><emphasis>implementation-defined</emphasis></type>
</typedef>
<typedef name="scoped_try_read_lock">
<type><emphasis>implementation-defined</emphasis></type>
</typedef>
<typedef name="scoped_write_lock">
<type><emphasis>implementation-defined</emphasis></type>
</typedef>
<typedef name="scoped_try_write_lock">
<typedef name="scoped_try_lock">
<type><emphasis>implementation-defined</emphasis></type>
</typedef>
@@ -312,7 +264,7 @@
<para>The <classname>timed_read_write_mutex</classname> class supplies the following typedefs,
which <link linkend="threads.concepts.read-write-lock-models">model</link>
the specified locking strategies:
the specified locking strategy:
<informaltable>
<tgroup cols="2" align="left">
@@ -324,41 +276,17 @@
</thead>
<tbody>
<row>
<entry>scoped_read_write_lock</entry>
<entry>scoped_lock</entry>
<entry><link linkend="threads.concepts.ScopedReadWriteLock">ScopedReadWriteLock</link></entry>
</row>
<row>
<entry>scoped_try_read_write_lock</entry>
<entry>scoped_try_lock</entry>
<entry><link linkend="threads.concepts.ScopedTryReadWriteLock">ScopedTryReadWriteLock</link></entry>
</row>
<row>
<entry>scoped_timed_read_write_lock</entry>
<entry>scoped_timed_lock</entry>
<entry><link linkend="threads.concepts.ScopedTimedReadWriteLock">ScopedTimedReadWriteLock</link></entry>
</row>
<row>
<entry>scoped_read_lock</entry>
<entry><link linkend="threads.concepts.ScopedLock">ScopedLock</link></entry>
</row>
<row>
<entry>scoped_try_read_lock</entry>
<entry><link linkend="threads.concepts.ScopedTryLock">ScopedTryLock</link></entry>
</row>
<row>
<entry>scoped_timed_read_lock</entry>
<entry><link linkend="threads.concepts.ScopedTimedLock">ScopedTimedLock</link></entry>
</row>
<row>
<entry>scoped_write_lock</entry>
<entry><link linkend="threads.concepts.ScopedLock">ScopedLock</link></entry>
</row>
<row>
<entry>scoped_try_write_lock</entry>
<entry><link linkend="threads.concepts.ScopedTryLock">ScopedTryLock</link></entry>
</row>
<row>
<entry>scoped_timed_write_lock</entry>
<entry><link linkend="threads.concepts.ScopedTimedLock">ScopedTimedLock</link></entry>
</row>
</tbody>
</tgroup>
</informaltable>
@@ -396,39 +324,15 @@
unless all locks are read-locks (but see below)</note>
</description>
<typedef name="scoped_read_write_lock">
<typedef name="scoped_lock">
<type><emphasis>implementation-defined</emphasis></type>
</typedef>
<typedef name="scoped_try_read_write_lock">
<typedef name="scoped_try_lock">
<type><emphasis>implementation-defined</emphasis></type>
</typedef>
<typedef name="scoped_timed_read_write_lock">
<type><emphasis>implementation-defined</emphasis></type>
</typedef>
<typedef name="scoped_read_lock">
<type><emphasis>implementation-defined</emphasis></type>
</typedef>
<typedef name="scoped_try_read_lock">
<type><emphasis>implementation-defined</emphasis></type>
</typedef>
<typedef name="scoped_timed_read_lock">
<type><emphasis>implementation-defined</emphasis></type>
</typedef>
<typedef name="scoped_write_lock">
<type><emphasis>implementation-defined</emphasis></type>
</typedef>
<typedef name="scoped_try_write_lock">
<type><emphasis>implementation-defined</emphasis></type>
</typedef>
<typedef name="scoped_timed_write_lock">
<typedef name="scoped_timed_lock">
<type><emphasis>implementation-defined</emphasis></type>
</typedef>
@@ -455,4 +359,4 @@
</destructor>
</class>
</namespace>
</header>
</header>

View File

@@ -299,4 +299,4 @@
</destructor>
</class>
</namespace>
</header>
</header>

View File

@@ -21,57 +21,38 @@
</section>
<section id="threads.release_notes.boost_1_32_0.change_log.static_link">
<title>Statically-link build option added</title>
<title>Static-link build option added</title>
<para>The option to link &Boost.Threads; as a static
library has been added (with some limitations on Win32 platforms).
This feature was originally removed from an earlier version
of Boost because <classname>boost::thread_specific_ptr</classname>
required that &Boost.Threads; be dynamically linked in order
for its cleanup functionality to work on Win32 platforms.
Because this limitation never applied to non-Win32 platforms,
because significant progress has been made in removing
the limitation on Win32 platforms (many thanks to
Aaron LaFramboise and Roland Scwarz!), and because the lack
of static linking is one of the most common complaints of
&Boost.Threads; users, this decision was reversed.</para>
<para>On non-Win32 platforms:
To choose the dynamically linked version of &Boost.Threads;
using Boost's auto-linking feature, #define BOOST_THREAD_USE_DLL;
to choose the statically linked version,
#define BOOST_THREAD_USE_LIB.
If neither symbols is #defined, the default will be chosen.
Currently the default is the statically linked version.</para>
<para>On Win32 platforms using VC++:
Use the same #defines as for non-Win32 platforms
(BOOST_THREAD_USE_DLL and BOOST_THREAD_USE_LIB).
If neither is #defined, the default will be chosen.
Currently the default is the statically linked version
if the VC++ run-time library is set to
"Multi-threaded" or "Multi-threaded Debug", and
the dynamically linked version
if the VC++ run-time library is set to
"Multi-threaded DLL" or "Multi-threaded Debug DLL".</para>
<para>On Win32 platforms using compilers other than VC++:
Use the same #defines as for non-Win32 platforms
(BOOST_THREAD_USE_DLL and BOOST_THREAD_USE_LIB).
If neither is #defined, the default will be chosen.
Currently the default is the dynamically linked version
because it has not yet been possible to implement automatic
tss cleanup in the statically linked version for compilers
other than VC++, although it is hoped that this will be
possible in a future version of &Boost.Threads;.
Note for advanced users: &Boost.Threads; provides several "hook"
functions to allow users to experiment with the statically
linked version on Win32 with compilers other than VC++.
These functions are on_process_enter(), on_process_exit(),
on_thread_enter(), and on_thread_exit(), and are defined
in tls_hooks.cpp. See the comments in that file for more
information.</para>
library has been added back with some limitations.
This feature was originally removed because
<classname>boost::thread_specific_ptr</classname> required
that &Boost.Threads; be dynamically linked in order for its
cleanup functionality to work on Win32 platforms.
Several options are currently being explored to resolve
this issue. In the meantime, the ability to link
&Boost.Threads; statically has been added back
<emphasis>with <classname>boost::thread_specific_ptr</classname>
support removed</emphasis> from the statically linked version.
The decision to add it back was made because its lack is
one of the most frequent complaints about &Boost.Threads;
and because the other approaches that are being investigated
to deal with <classname>boost::thread_specific_ptr</classname>
cleanup look fairly promising.
<note>&Boost.Threads; is still dynamically linked by default.
In order to force it to be statically linked, it is necessary to
#define BOOST_THREAD_USE_LIB before any of the &Boost.Threads;
header files are #included.</note>
<note>If the <classname>boost::thread_specific_ptr</classname> cleanup
issue cannot be resolved by some other means, it is highly
likely that the option to statically link &Boost.Threads;
will be removed again in a future version of Boost, at least
for Win32 platforms. This is because the
<classname>boost::thread_specific_ptr</classname> functionality
will be increasingly used by &Boost.Threads; itself,
so that proper cleanup will become essential
in future versions of &Boost.Threads;.</note>
</para>
</section>
<section id="threads.release_notes.boost_1_32_0.change_log.barrier">
@@ -87,14 +68,7 @@
<classname>boost::read_write_mutex</classname>,
<classname>boost::try_read_write_mutex</classname>, and
<classname>boost::timed_read_write_mutex</classname>
were added.
<note>Since the read/write mutex and related classes are new,
both interface and implementation are liable to change
in future releases of &Boost.Threads;.
The lock concepts and lock promotion in particular are
still under discussion and very likely to change.</note>
</para>
were added.</para>
</section>
<section id="threads.release_notes.boost_1_32_0.change_log.thread_specific_ptr">
@@ -134,11 +108,5 @@
<classname>boost::timed_mutex</classname> and
<classname>boost::recursive_timed_mutex</classname> use a Win32 mutex.</para>
</section>
<section id="threads.release_notes.boost_1_32_0.change_log.wince">
<title>Windows CE support improved</title>
<para>Minor changes were made to make Boost.Threads work on Windows CE.</para>
</section>
</section>
</section>

View File

@@ -263,4 +263,4 @@
</method-group>
</class>
</namespace>
</header>
</header>

View File

@@ -13,12 +13,14 @@ xmlns:xi="http://www.w3.org/2001/XInclude">
<othername>E.</othername>
<surname>Kempf</surname>
</author>
<copyright>
<year>2001</year>
<year>2002</year>
<year>2003</year>
<holder>William E. Kempf</holder>
</copyright>
<legalnotice>
<para>Permission to use, copy, modify, distribute and sell this
software and its documentation for any purpose is hereby granted
@@ -28,11 +30,14 @@ xmlns:xi="http://www.w3.org/2001/XInclude">
representations about the suitability of this software for any purpose.
It is provided "as is" without express or implied warranty.</para>
</legalnotice>
<librarypurpose>Portable C++ multi-threading</librarypurpose>
<librarycategory name="category:concurrent" />
<title>Boost.Threads</title>
</libraryinfo>
<title>Boost.Threads</title>
<title>&Boost.Threads;</title>
<xi:include href="overview.xml"/>
<xi:include href="design.xml"/>
<xi:include href="concepts.xml"/>

13
doc/thread_pool-ref.xml Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % threads.entities SYSTEM "entities.xml">
%threads.entities;
]>
<header name="boost/thread/thread_pool.hpp"
last-revision="$Date$">
<namespace name="boost">
<class name="thread_pool">
</class>
</namespace>
</header>

207
doc/thread_pool.html Normal file
View File

@@ -0,0 +1,207 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<title>Boost.Threads - Header &lt;boost/thread/thread_pool.hpp&gt;</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Threads</h1>
<h2 align="center">Header &lt;<a href="../../../boost/thread/thread_pool.hpp">boost/thread/thread_pool.hpp</a>&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dl class="page-index">
<dt><a href="#class-thread_pool">Class <code>thread_pool</code></a></dt>
<dl class="page-index">
<dt><a href="#class-thread_pool-synopsis">Class <code>thread_pool</code> synopsis</a></dt>
<dt><a href="#class-thread_pool-ctors">Class <code>thread_pool</code> constructors and destructor</a></dt>
<dt><a href="#class-thread_pool-modifiers">Class <code>thread_pool</code> modifier functions</a></dt>
</dl>
</dl>
<dt><a href="#examples">Example(s)</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p>Include the header &lt;<a href="../../../boost/thread/thread_pool.hpp">boost/thread/thread_pool.hpp</a>&gt;
to define the <a href="#class-thread_pool">thread_pool</a> class.</p>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="class-thread_pool"></a>Class <code>thread_pool</code></h3>
<p>The <tt>thread_pool</tt> class provides&nbsp;an interface for&nbsp;running
jobs on a dynamically managed set&nbsp;of worker threads called a pool.&nbsp;
When a job is added, it can execute on any&nbsp;available thread in the pool.&nbsp;
This class controls&nbsp;both the maximum and minimum number of threads&nbsp;in
the pool.&nbsp; If a thread in the pool is sitting idle&nbsp;for a period&nbsp;of
time, it&nbsp;will exit unless by exiting the number of threads would dip below
the minimum. Thread pools provide an optimization over creating a new thread
for each job since the pool can often remove the overhead of thread creation.</p>
<h4><a name="class-thread_pool-synopsis"></a>Class <code>thread_pool</code> synopsis</h4>
<pre>
namespace boost
{
class thread_pool : <a href="../../utility/utility.htm#Class noncopyable">boost::noncopyable</a> // Exposition only.
// Class thread meets the <a href="overview.html#non-copyable">NonCopyable</a> requirement.
{
public:
thread_pool(int max_threads=std::numeric_limits&lt;int&gt;::max(),
int min_threads=0,
int timeout_secs=5);
~thread_pool();
void add(const boost::function0&lt;void&gt; &amp;job);
void join();
void cancel();
void detach();
};
};
</pre>
<h4><a name="class-spec-ctors"></a>Class <code>thread_pool</code> constructors and destructor</h4>
<pre>
thread_pool(int max_threads=std::numeric_limits&lt;int&gt;::max(),
int min_threads=0,
int timeout_secs=5);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Constructs a thread pool object and starts min_threads threads
running in the pool.</dt>
</dl>
<pre>
~thread_pool();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Calls join() if neither join() nor detach() were called
previously for this thread_pool.&nbsp; If detach() was not called, destroys all
resources associated with the threads in the pool and with the queue of jobs
still waiting to be executed.</dt>
</dl>
<h4><a name="class-spec-modifiers"></a>Class <code>thread_pool</code> modifier
functions</h4>
<pre>
void add(const boost::function0&lt;void&gt;&amp; job);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Adds <tt>job</tt> to the <tt>thread_pool</tt> object's list of
jobs waiting to be executed.&nbsp; If any threads in the pool are idle, the job
will be execute as soon as the idle thread is scheduled by the operating
system.&nbsp; If no threads are idle and the number of threads in the pool is
less than the maximum number provided to the constructor, an additional thread
is created and added to the pool.&nbsp; That new thread will execute this job
as soon as it is scheduled by the operating system.&nbsp; If no threads are
idle and&nbsp;the thread count is at the maximum, this job will be queued until
a thread becomes available.&nbsp; Currently, queued jobs are processed in FIFO
order.</dt>
<dt><b>Throws:</b> std::runtime_error if join() or detach() have
previously been called for this thread_pool object.</dt>
</dl>
<pre>
void detach();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Relinquishes control of the pool of threads by this thread_pool
object.&nbsp; Any threads in the pool will continue to run and continue to
process any queued jobs, but no new threads will be created, and any subsequent
attempts to add new jobs will result in an exception.</dt>
<dt><b>Throws:</b> std::runtime_error if join()&nbsp;has previously
been called for this thread_pool object.</dt>
</dl>
<pre>
void cancel();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Removes all queued jobs from the thread_pool's internal queue,
and calls cancel() on all boost::thread objects in the pool.&nbsp; The specific
behavior of those threads will be dictated by their cancellation behavior - the
pool threads may be executing a user's job that deferrs cancellation, for
example.</dt>
<dt><b>Throws:</b> std::runtime_error if join() or detach() have
previously been called for this thread_pool object.</dt>
<dt><b>Note:</b> for the current version (1.27.0) of Boost.Threads, thread::cancel() is
not provided.&nbsp; This function -will- clear out all queued jobs, but any
currently executing jobs will not be cancelled.</dt>
</dl>
<pre>
void join();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Waits until all queued jobs are completed by the thread pool,
and then join()s will all of the threads in the pool.&nbsp; When join()
returns, no running threads will remain in the pool, and this object is invalid
for anything except destruction.&nbsp; Any calls to cancel(), join(), detach(),
or add() will result in an exception.</dt>
</dl>
<h2><a name="examples"></a>Example(s)</h2>
<pre>
#include &lt;boost/thread/thread_pool.hpp&gt;
#include &lt;boost/thread/mutex.hpp&gt;
#include &lt;iostream&gt;
boost::mutex io_mutex;
class job_adapter {
public:
job_adapter(void (*func)(int), int param) :
_func(func), _param(param){ }
void operator()() const { _func(_param); }
private:
void (*_func)(int);
int _param;
};
void simple_job(int param)
{
boost::mutex::scoped_lock l(io_mutex);
std::cout &lt;&lt; param &lt;&lt; " squared is " &lt;&lt; (param*param) &lt;&lt; "\n";
}
int main(int argc, char* argv[])
{
boost::thread_pool tp;
for (int i = 1; i &lt;= 10; ++i)
tp.add(simple_job);
tp.join();
return 0;
}
</pre>
<p>Typical output would be:</p>
<pre>
1 squared is 1
2 squared is 4
3 squared is 9
4 squared is 16
5 squared is 25
7 squared is 49
6 squared is 36
8 squared is 64
10 squared is 100
9 squared is 81
</pre>
<P>While the jobs are dispatched in the order they are received, the scheduling of
the individual threads in the pool is platform-dependent.</P>
<P>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 November, 2001
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="mailto:wekempf@cox.net">William E. Kempf</a>, David Moore 2001-2002.
All Rights Reserved.</i></p>
<p>Permission to use, copy, modify, distribute and sell this software and its
documentation for any purpose is hereby granted without fee, provided that the
above copyright notice appear in all copies and that both that copyright notice
and this permission notice appear in supporting documentation. William E. Kempf
makes no representations about the suitability of this software for any purpose.
It is provided &quot;as is&quot; without express or implied warranty.</p>
</body>
</html>

View File

@@ -199,4 +199,4 @@
</method-group>
</class>
</namespace>
</header>
</header>

View File

@@ -75,4 +75,4 @@
</data-member>
</struct>
</namespace>
</header>
</header>

View File

@@ -1,2 +1,2 @@
bin
*.pdb
*.pdb

View File

@@ -1,52 +1,54 @@
# Copyright (C) 2006 Roland Schwarz.
# 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)
# Copyright (C) 2001-2003
# William E. Kempf
#
# This work is a reimplementation along the design and ideas
# of William E. Kempf.
# Permission to use, copy, modify, distribute and sell this software
# and its documentation for any purpose is hereby granted without fee,
# provided that the above copyright notice appear in all copies and
# that both that copyright notice and this permission notice appear
# in supporting documentation. William E. Kempf makes no representations
# about the suitability of this software for any purpose.
# It is provided "as is" without express or implied warranty.
#
# Boost.Threads example Jamfile
#
# Additional configuration variables used:
# 1. PTW32 may be used on Win32 platforms to specify that the pthreads-win32
# library should be used instead of "native" threads. This feature is
# mostly used for testing and it's generally recommended you use the
# native threading libraries instead. PTW32 should be set to be a list
# of two strings, the first specifying the installation path of the
# pthreads-win32 library and the second specifying which library
# variant to link against (see the pthreads-win32 documentation).
# Example: jam -sPTW32="c:\pthreads-win32 pthreadVCE.lib"
# The threading library is available in two versions.
# Native to the environment or based ontop pthread.
# To select which version to use you need to define
# BOOST_THREAD_POSIX when compiling your sources.
# If BOOST_THREAD_POSIX is defined this will choose
# pthread implementation.
# You also need to specify the correct library version by
# specifying the the <lib> or <dll> tags.
# <lib>@boost/libs/thread/build/boost_thread for static native and
# <lib>@boost/libs/thread/build/boost_thread_pthread static pthread.
# If your compiler does not have the pthread lib in a standard
# include path, you need to specify that too, with <include> and
# <library-file>.
# Declare the location of this subproject relative to the root.
subproject libs/thread/example ;
project-root ;
# Include threads.jam for Boost.Threads global build information.
# This greatly simplifies the Jam code needed to configure the build
# for the various Win32 build types.
import ../build/threads ;
template example
: ## sources ##
<lib>@boost/libs/thread/build/boost_thread
#<lib>@boost/libs/thread/build/boost_thread_pthread
#<dll>@boost/libs/thread/build/boost_thread
#<dll>@boost/libs/thread/build/boost_thread_pthread
: ## requirements ##
<include>$(BOOST_ROOT)
# uncomment below to get pthread on windows
#<define>BOOST_THREAD_POSIX
#<include>$(PTW32_INCLUDE)
#<library-file>$(PTW32_LIB)
: ## default build ##
<threading>multi
;
{
template example
## sources ##
: <template>thread_base
<dll>../build/boost_thread
## requirements ##
:
## default build ##
:
;
exe monitor : <template>example monitor.cpp ;
exe starvephil : <template>example starvephil.cpp ;
exe tennis : <template>example tennis.cpp ;
exe condition : <template>example condition.cpp ;
exe mutex : <template>example mutex.cpp ;
exe once : <template>example once.cpp ;
exe recursive_mutex : <template>example recursive_mutex.cpp ;
exe thread : <template>example thread.cpp ;
exe thread_group : <template>example thread_group.cpp ;
exe tss : <template>example tss.cpp ;
exe xtime : <template>example xtime.cpp ;
exe monitor : <template>example monitor.cpp ;
exe starvephil : <template>example starvephil.cpp ;
exe tennis : <template>example tennis.cpp ;
exe condition : <template>example condition.cpp ;
exe mutex : <template>example mutex.cpp ;
exe once : <template>example once.cpp ;
exe recursive_mutex : <template>example recursive_mutex.cpp ;
exe thread : <template>example thread.cpp ;
exe thread_group : <template>example thread_group.cpp ;
exe tss : <template>example tss.cpp ;
exe xtime : <template>example xtime.cpp ;
}

View File

@@ -1,53 +0,0 @@
# Copyright 2003 William E. Kempf
# Copyright 2006 Roland Schwarz
# 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)
#
# This work is a reimplementation along the design and ideas
# of William E. Kempf.
project example ;
# If you move this example from its place in the Boost tree, edit this
# path to point at the root directory of your Boost installation (the
# one containing a subdirectory called "boost/".
path-global BOOST_ROOT : ../../.. ;
# Makes a project id for boost so that other Boost.Build projects can
# refer to it by name.
#
project boost : $(BOOST_ROOT) ;
# Attn: path-global was broken in my version of bbv1, which prevented specifying
# BOOST_ROOT as a relative path. So I needed to apply
# the below fix in allyourbase.jam as shown below:
#
#rule project ( name : location ? )
#{
# if ! $(location)
# {
# gPROJECT($(name)) = $(gPROJECT($(PROJECT))) ;
# PROJECT($(gPROJECT($(name)))) = $(name) ;
# PROJECT = $(name) ;
# }
# else
# {
# gPROJECT($(name)) = [ root-paths $(location) : [ root-paths $($(gTOP)) : [ PWD ] ] ] ;
# # speedsnail
# # Root the path globals to fix a bug which prevented to use them from an external
# # project. The fix is as as uninvasive as possible, as it will only trigger when
# # an external project is declared. So it will not interfere with the build of the
# # boost library. I took this route, as at the time of this fix, the bbv1 is expected
# # to be retired soon.
# # N.B.: The path-globals rule is expected to be invoked from Jamrules files only.
# local val ;
# for val in $(gPATH_GLOBALS) {
# gPATH_GLOBAL_VALUE($(val)) = [ root-paths $(gPATH_GLOBAL_VALUE($(val))) :
# [ root-paths $($(gTOP)) : [ PWD ] ]
# ] ;
# }
# local [ protect-subproject ] ;
# enter-subproject @$(name) ;
# }
#}

View File

@@ -1,22 +0,0 @@
# Copyright 2006 Roland Schwarz.
# 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)
#
# This work is a reimplementation along the design and ideas
# of William E. Kempf.
#
# Edit this path to point at the tools/build/v1 subdirectory of your
# Boost installation.
if --v2 in $(ARGV)
{
JAMFILE = [Bb]uild.jam [Jj]amfile.v2 ;
boost-build ../../../tools/build/v2 ;
}
else
{
boost-build ../../../tools/build/v1 ;
}

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 William E. Kempf
// 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
// Copyright (C) 2001-2003
// William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <iostream>
#include <vector>
@@ -38,8 +43,7 @@ public:
}
private:
int begin, end;
std::vector<int>::size_type buffered;
int begin, end, buffered;
std::vector<int> circular_buf;
boost::condition buffer_not_full, buffer_not_empty;
boost::mutex monitor;

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 William E. Kempf
// 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
// Copyright (C) 2001-2003
// William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <vector>
#include <iostream>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 William E. Kempf
// 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
// Copyright (C) 2001-2003
// William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 William E. Kempf
// 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
// Copyright (C) 2001-2003
// William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/thread.hpp>
#include <boost/thread/once.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 William E. Kempf
// 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
// Copyright (C) 2001-2003
// William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/recursive_mutex.hpp>
#include <boost/thread/thread.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 William E. Kempf
// 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
// Copyright (C) 2001-2003
// William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
@@ -14,7 +19,7 @@
namespace
{
boost::mutex iomx;
} // namespace
}
class canteen
{

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 William E. Kempf
// 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
// Copyright (C) 2001-2003
// William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>

View File

@@ -1,9 +1,13 @@
// Copyright (C) 2001-2003 William E. Kempf
// 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
// Copyright (C) 2001-2003
// William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/thread.hpp>
#include <iostream>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 William E. Kempf
// 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
// Copyright (C) 2001-2003
// William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/thread.hpp>
#include <boost/thread/tss.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 William E. Kempf
// 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
// Copyright (C) 2001-2003
// William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>

View File

@@ -1,64 +1,40 @@
#ifndef BOOST_THREAD_BARRIER_HPP
#define BOOST_THREAD_BARRIER_HPP
// barrier.hpp
// Copyright (C) 2002-2003
// David Moore, William E. Kempf
//
// (C) Copyright 2006 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_BARRIER_JDM030602_HPP
#define BOOST_BARRIER_JDM030602_HPP
#include <boost/thread/detail/config.hpp>
#include <cstddef>
#include <stdexcept>
#include <boost/thread/detail/platform.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std
{
using ::size_t;
}
#endif
namespace boost {
namespace boost
class BOOST_THREAD_DECL barrier
{
class barrier
{
boost::mutex m;
boost::condition cond;
const std::size_t max_count;
std::size_t current_count;
public:
barrier(std::size_t count):
max_count(count),current_count(0)
{
if(!max_count)
{
throw std::invalid_argument("You must specify a non-zero count");
}
}
bool wait()
{
boost::mutex::scoped_lock lock(m);
if(++current_count==max_count)
{
current_count=0;
cond.notify_all();
return true;
}
else
{
cond.wait(lock);
return false;
}
}
};
}
public:
barrier(unsigned int count);
~barrier();
bool wait();
private:
mutex m_mutex;
condition m_cond;
unsigned int m_threshold;
unsigned int m_count;
unsigned int m_generation;
};
} // namespace boost
#endif

View File

@@ -1,16 +1,198 @@
// Copyright 2006 Roland Schwarz.
// 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)
// Copyright (C) 2001-2003
// William E. Kempf
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_THREAD_RS06040706_HPP
#define BOOST_THREAD_RS06040706_HPP
#ifndef BOOST_CONDITION_WEK070601_HPP
#define BOOST_CONDITION_WEK070601_HPP
#include <boost/thread/detail/platform.hpp>
#include BOOST_THREAD_PLATFORM(condition.hpp)
#include <boost/thread/detail/config.hpp>
#endif // BOOST_THREAD_RS06040706_HPP
#include <boost/thread/exceptions.hpp>
#include <boost/utility.hpp>
#include <boost/thread/detail/lock.hpp>
#if defined(BOOST_HAS_PTHREADS)
# include <pthread.h>
#elif defined(BOOST_HAS_MPTASKS)
# include "scoped_critical_region.hpp"
#endif
namespace boost {
struct xtime;
namespace detail {
class BOOST_THREAD_DECL condition_impl : private noncopyable
{
friend class condition;
public:
condition_impl();
~condition_impl();
void notify_one();
void notify_all();
#if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
void enter_wait();
void do_wait();
bool do_timed_wait(const xtime& xt);
#elif defined(BOOST_HAS_PTHREADS)
void do_wait(pthread_mutex_t* pmutex);
bool do_timed_wait(const xtime& xt, pthread_mutex_t* pmutex);
#endif
#if defined(BOOST_HAS_WINTHREADS)
void* m_gate;
void* m_queue;
void* m_mutex;
unsigned m_gone; // # threads that timed out and never made it to m_queue
unsigned long m_blocked; // # threads blocked on the condition
unsigned m_waiting; // # threads no longer waiting for the condition but
// still waiting to be removed from m_queue
#elif defined(BOOST_HAS_PTHREADS)
pthread_cond_t m_condition;
#elif defined(BOOST_HAS_MPTASKS)
MPSemaphoreID m_gate;
MPSemaphoreID m_queue;
threads::mac::detail::scoped_critical_region m_mutex;
threads::mac::detail::scoped_critical_region m_mutex_mutex;
unsigned m_gone; // # threads that timed out and never made it to m_queue
unsigned long m_blocked; // # threads blocked on the condition
unsigned m_waiting; // # threads no longer waiting for the condition but
// still waiting to be removed from m_queue
#endif
};
} // namespace detail
class condition : private noncopyable
{
public:
condition() { }
~condition() { }
void notify_one() { m_impl.notify_one(); }
void notify_all() { m_impl.notify_all(); }
template <typename L>
void wait(L& lock)
{
if (!lock)
throw lock_error();
do_wait(lock.m_mutex);
}
template <typename L, typename Pr>
void wait(L& lock, Pr pred)
{
if (!lock)
throw lock_error();
while (!pred())
do_wait(lock.m_mutex);
}
template <typename L>
bool timed_wait(L& lock, const xtime& xt)
{
if (!lock)
throw lock_error();
return do_timed_wait(lock.m_mutex, xt);
}
template <typename L, typename Pr>
bool timed_wait(L& lock, const xtime& xt, Pr pred)
{
if (!lock)
throw lock_error();
while (!pred())
{
if (!do_timed_wait(lock.m_mutex, xt))
return false;
}
return true;
}
private:
detail::condition_impl m_impl;
template <typename M>
void do_wait(M& mutex)
{
#if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
m_impl.enter_wait();
#endif
typedef detail::thread::lock_ops<M>
#if defined(__HP_aCC) && __HP_aCC <= 33900 && !defined(BOOST_STRICT_CONFIG)
# define lock_ops lock_ops_ // HP confuses lock_ops witht the template
#endif
lock_ops;
typename lock_ops::lock_state state;
lock_ops::unlock(mutex, state);
#if defined(BOOST_HAS_PTHREADS)
m_impl.do_wait(state.pmutex);
#elif (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
m_impl.do_wait();
#endif
lock_ops::lock(mutex, state);
#undef lock_ops
}
template <typename M>
bool do_timed_wait(M& mutex, const xtime& xt)
{
#if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
m_impl.enter_wait();
#endif
typedef detail::thread::lock_ops<M>
#if defined(__HP_aCC) && __HP_aCC <= 33900 && !defined(BOOST_STRICT_CONFIG)
# define lock_ops lock_ops_ // HP confuses lock_ops witht the template
#endif
lock_ops;
typename lock_ops::lock_state state;
lock_ops::unlock(mutex, state);
bool ret = false;
#if defined(BOOST_HAS_PTHREADS)
ret = m_impl.do_timed_wait(xt, state.pmutex);
#elif (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
ret = m_impl.do_timed_wait(xt);
#endif
lock_ops::lock(mutex, state);
#undef lock_ops
return ret;
}
};
} // namespace boost
// Change Log:
// 8 Feb 01 WEKEMPF Initial version.
// 22 May 01 WEKEMPF Modified to use xtime for time outs.
// 23 May 01 WEKEMPF Removed "duration" timed_waits, as they are too
// difficult to use with spurious wakeups.
// 3 Jan 03 WEKEMPF Modified for DLL implementation.
#endif // BOOST_CONDITION_WEK070601_HPP

View File

@@ -0,0 +1,60 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_THREAD_CONFIG_WEK01032003_HPP
#define BOOST_THREAD_CONFIG_WEK01032003_HPP
#include <boost/config.hpp>
// insist on threading support being available:
#include <boost/config/requires_threads.hpp>
#if defined(BOOST_HAS_WINTHREADS)
# if defined(BOOST_THREAD_BUILD_DLL) //Build dll
# define BOOST_THREAD_DECL __declspec(dllexport)
# elif defined(BOOST_THREAD_BUILD_LIB) //Build lib
# define BOOST_THREAD_DECL
# elif defined(BOOST_THREAD_USE_LIB) //Use lib
# define BOOST_THREAD_DECL
# else //Use dll
# define BOOST_THREAD_DECL __declspec(dllimport)
# define BOOST_DYN_LINK
# endif
#else
# define BOOST_THREAD_DECL
# if defined(BOOST_THREAD_USE_LIB) //Use lib
# else //Use dll
# define BOOST_DYN_LINK
# endif
#endif // BOOST_HAS_WINTHREADS
//
// Automatically link to the correct build variant where possible.
//
#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_THREAD_NO_LIB) && !defined(BOOST_THREAD_BUILD_DLL) && !defined(BOOST_THREAD_BUILD_LIB)
//
// Set the name of our library, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#if defined(BOOST_THREAD_LIB_NAME)
# define BOOST_LIB_NAME BOOST_THREAD_LIB_NAME
#else
# define BOOST_LIB_NAME boost_thread
#endif
//
// If we're importing code from a dll, then tell auto_link.hpp about it:
//
// And include the header that does the work:
//
#include <boost/config/auto_link.hpp>
#endif // auto-linking disabled
#endif // BOOST_THREAD_CONFIG_WEK1032003_HPP

View File

@@ -0,0 +1,43 @@
// Copyright (C) 2001-2003
// Mac Murrett
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. Mac Murrett makes no representations
// about the suitability of this software for any purpose. It is
// provided "as is" without express or implied warranty.
//
// See http://www.boost.org for most recent version including documentation.
#ifndef BOOST_FORCE_CAST_MJM012402_HPP
#define BOOST_FORCE_CAST_MJM012402_HPP
#include <boost/thread/detail/config.hpp>
namespace boost {
namespace detail {
namespace thread {
// force_cast will convert anything to anything.
// general case
template<class Return_Type, class Argument_Type>
inline Return_Type &force_cast(Argument_Type &rSrc)
{
return(*reinterpret_cast<Return_Type *>(&rSrc));
}
// specialization for const
template<class Return_Type, class Argument_Type>
inline const Return_Type &force_cast(const Argument_Type &rSrc)
{
return(*reinterpret_cast<const Return_Type *>(&rSrc));
}
} // namespace thread
} // namespace detail
} // namespace boost
#endif // BOOST_FORCE_CAST_MJM012402_HPP

View File

@@ -1,18 +1,21 @@
// Copyright 2006 Roland Schwarz.
// 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)
// Copyright (C) 2001-2003
// William E. Kempf
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_THREAD_RS06040708_HPP
#define BOOST_THREAD_RS06040708_HPP
#ifndef BOOST_XLOCK_WEK070601_HPP
#define BOOST_XLOCK_WEK070601_HPP
#include <boost/thread/pthread/config.hpp>
#include <boost/thread/detail/config.hpp>
#include <boost/utility.hpp>
#include <boost/thread/pthread/exceptions.hpp>
#include <boost/thread/exceptions.hpp>
namespace boost {
@@ -202,4 +205,10 @@ private:
} // namespace detail
} // namespace boost
#endif // BOOST_THREAD_RS06040708_HPP
#endif // BOOST_XLOCK_WEK070601_HPP
// Change Log:
// 8 Feb 01 WEKEMPF Initial version.
// 22 May 01 WEKEMPF Modified to use xtime for time outs.
// 30 Jul 01 WEKEMPF Moved lock types into boost::detail::thread. Renamed
// some types. Added locked() methods.

View File

@@ -9,16 +9,30 @@
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#if !defined(BOOST_THREAD_WEK01082003_HPP)
#define BOOST_THREAD_WEK01082003_HPP
#ifndef BOOST_NAMED_WEK031703_HPP
#define BOOST_NAMED_WEK031703_HPP
#include <boost/thread/thread.hpp>
#include <boost/thread/condition.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/once.hpp>
#include <boost/thread/recursive_mutex.hpp>
#include <boost/thread/tss.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/thread/detail/config.hpp>
#endif
namespace boost {
namespace detail {
class named_object
{
protected:
named_object(const char* name=0);
~named_object();
public:
const char* name() const;
const char* effective_name() const;
protected:
char* m_name;
char* m_ename;
};
} // namespace detail
} // namespace boost
#endif // BOOST_NAMED_WEK031703_HPP

View File

@@ -1,72 +0,0 @@
// Copyright 2006 Roland Schwarz.
// 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)
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
#ifndef BOOST_THREAD_RS06040501_HPP
#define BOOST_THREAD_RS06040501_HPP
// fetch compiler and platform configuration
#include <boost/config.hpp>
// insist on threading support being available:
#include <boost/config/requires_threads.hpp>
// choose platform
#if defined(linux) || defined(__linux) || defined(__linux__)
# define BOOST_THREAD_LINUX
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
# define BOOST_THREAD_BSD
#elif defined(sun) || defined(__sun)
# define BOOST_THREAD_SOLARIS
#elif defined(__sgi)
# define BOOST_THREAD_IRIX
#elif defined(__hpux)
# define BOOST_THREAD_HPUX
#elif defined(__CYGWIN__)
# define BOOST_THREAD_CYGWIN
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
# define BOOST_THREAD_WIN32
#elif defined(__BEOS__)
# define BOOST_THREAD_BEOS
#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
# define BOOST_THREAD_MACOS
#elif defined(__IBMCPP__) || defined(_AIX)
# define BOOST_THREAD_AIX
#elif defined(__amigaos__)
# define BOOST_THREAD_AMIGAOS
#elif defined(__QNXNTO__)
# define BOOST_THREAD_QNXNTO
#elif defined(unix) || defined(__unix) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE)
# if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_THREAD_POSIX)
# define BOOST_THREAD_POSIX
# endif
#endif
// For every supported platform add a new entry into the dispatch table below.
// BOOST_THREAD_POSIX is tested first, so on platforms where posix and native
// threading is available, the user may choose, by defining BOOST_THREAD_POSIX
// in her source. If a platform is known to support pthreads and no native
// port of boost_thread is available just specify "pthread" in the
// dispatcher table. If there is no entry for a platform but pthreads is
// available on the platform, pthread is choosen as default. If nothing is
// available the preprocessor will fail with a diagnostic message.
#if defined(BOOST_THREAD_POSIX)
# define BOOST_THREAD_PPFX pthread
#else
# if defined(BOOST_THREAD_WIN32)
# define BOOST_THREAD_PPFX win32
# elif defined(BOOST_HAS_PTHREADS)
# define BOOST_THREAD_PPFX pthread
# else
# error "Sorry, no boost threads are available for this platform."
# endif
#endif
#define BOOST_THREAD_PLATFORM(header) <boost/thread/BOOST_THREAD_PPFX/header>
#endif // BOOST_THREAD_RS06040501_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,63 @@
// Copyright (C) 2001-2003
// Mac Murrett
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. Mac Murrett makes no representations
// about the suitability of this software for any purpose. It is
// provided "as is" without express or implied warranty.
//
// See http://www.boost.org for most recent version including documentation.
#ifndef BOOST_SINGLETON_MJM012402_HPP
#define BOOST_SINGLETON_MJM012402_HPP
#include <boost/thread/detail/config.hpp>
namespace boost {
namespace detail {
namespace thread {
// class singleton has the same goal as all singletons: create one instance of
// a class on demand, then dish it out as requested.
template <class T>
class singleton : private T
{
private:
singleton();
~singleton();
public:
static T &instance();
};
template <class T>
inline singleton<T>::singleton()
{
/* no-op */
}
template <class T>
inline singleton<T>::~singleton()
{
/* no-op */
}
template <class T>
/*static*/ T &singleton<T>::instance()
{
// function-local static to force this to work correctly at static
// initialization time.
static singleton<T> s_oT;
return(s_oT);
}
} // namespace thread
} // namespace detail
} // namespace boost
#endif // BOOST_SINGLETON_MJM012402_HPP

View File

@@ -0,0 +1,35 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_THREADMON_WEK062504_HPP
#define BOOST_THREADMON_WEK062504_HPP
#include <boost/thread/detail/config.hpp>
#ifdef BOOST_HAS_WINTHREADS
extern "C" BOOST_THREAD_DECL int at_thread_exit(void (__cdecl * func)(void));
//Add a function to the list of thread-exit functions
extern "C" BOOST_THREAD_DECL void on_process_enter(void);
//To be called when the process starts, when the dll is loaded, etc.
//Called automatically by Boost.Thread when possible
extern "C" BOOST_THREAD_DECL void on_thread_exit(void);
//To be called for each thread when it exits
//Must be called in the context of the thread that is exiting
//Called automatically by Boost.Thread when possible
extern "C" BOOST_THREAD_DECL void on_process_exit(void);
//To be called when the process exits, when the dll is unloaded, etc.
//Called automatically by Boost.Thread when possible
#endif // BOOST_HAS_WINTHREADS
#endif // BOOST_THREADMON_WEK062504_HPP

View File

@@ -1,16 +1,100 @@
// Copyright 2006 Roland Schwarz.
// 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)
// Copyright (C) 2001-2003
// William E. Kempf
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_THREAD_RS06040710_HPP
#define BOOST_THREAD_RS06040710_HPP
#ifndef BOOST_THREAD_EXCEPTIONS_PDM070801_H
#define BOOST_THREAD_EXCEPTIONS_PDM070801_H
#include <boost/thread/detail/platform.hpp>
#include BOOST_THREAD_PLATFORM(exceptions.hpp)
#include <boost/thread/detail/config.hpp>
#endif // BOOST_THREAD_RS06040710_HPP
// pdm: Sorry, but this class is used all over the place & I end up
// with recursive headers if I don't separate it
// wek: Not sure why recursive headers would cause compilation problems
// given the include guards, but regardless it makes sense to
// seperate this out any way.
#include <stdexcept>
namespace boost {
class BOOST_THREAD_DECL thread_exception : public std::exception
{
protected:
thread_exception();
thread_exception(int sys_err_code);
public:
~thread_exception() throw();
int native_error() const { return m_sys_err; }
const char* message() const;
private:
int m_sys_err;
};
class BOOST_THREAD_DECL lock_error : public thread_exception
{
public:
lock_error();
lock_error(int sys_err_code);
~lock_error() throw();
virtual const char* what() const throw();
};
class BOOST_THREAD_DECL thread_resource_error : public thread_exception
{
public:
thread_resource_error();
thread_resource_error(int sys_err_code);
~thread_resource_error() throw();
virtual const char* what() const throw();
};
class BOOST_THREAD_DECL unsupported_thread_option : public thread_exception
{
public:
unsupported_thread_option();
unsupported_thread_option(int sys_err_code);
~unsupported_thread_option() throw();
virtual const char* what() const throw();
};
class BOOST_THREAD_DECL invalid_thread_argument : public thread_exception
{
public:
invalid_thread_argument();
invalid_thread_argument(int sys_err_code);
~invalid_thread_argument() throw();
virtual const char* what() const throw();
};
class BOOST_THREAD_DECL thread_permission_error : public thread_exception
{
public:
thread_permission_error();
thread_permission_error(int sys_err_code);
~thread_permission_error() throw();
virtual const char* what() const throw();
};
} // namespace boost
#endif // BOOST_THREAD_CONFIG_PDM070801_H
// Change log:
// 3 Jan 03 WEKEMPF Modified for DLL implementation.

View File

@@ -1,16 +1,171 @@
// Copyright 2006 Roland Schwarz.
// 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)
// Copyright (C) 2001-2003
// William E. Kempf
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_THREAD_RS06040704_HPP
#define BOOST_THREAD_RS06040704_HPP
#ifndef BOOST_MUTEX_WEK070601_HPP
#define BOOST_MUTEX_WEK070601_HPP
#include <boost/thread/detail/platform.hpp>
#include BOOST_THREAD_PLATFORM(mutex.hpp)
#include <boost/thread/detail/config.hpp>
#endif // BOOST_THREAD_RS06040704_HPP
#include <boost/utility.hpp>
#include <boost/thread/detail/lock.hpp>
#include <boost/thread/detail/named.hpp>
#if defined(BOOST_HAS_PTHREADS)
# include <pthread.h>
#endif
#if defined(BOOST_HAS_MPTASKS)
# include "scoped_critical_region.hpp"
#endif
namespace boost {
struct xtime;
class BOOST_THREAD_DECL mutex
: private noncopyable
, public boost::detail::named_object
{
public:
friend class detail::thread::lock_ops<mutex>;
typedef detail::thread::scoped_lock<mutex> scoped_lock;
mutex(const char* name=0);
~mutex();
private:
#if defined(BOOST_HAS_WINTHREADS)
typedef void* cv_state;
#elif defined(BOOST_HAS_PTHREADS)
struct cv_state
{
pthread_mutex_t* pmutex;
};
#elif defined(BOOST_HAS_MPTASKS)
struct cv_state
{
};
#endif
void do_lock();
void do_unlock();
void do_lock(cv_state& state);
void do_unlock(cv_state& state);
#if defined(BOOST_HAS_WINTHREADS)
void* m_mutex;
bool m_critical_section;
#elif defined(BOOST_HAS_PTHREADS)
pthread_mutex_t m_mutex;
#elif defined(BOOST_HAS_MPTASKS)
threads::mac::detail::scoped_critical_region m_mutex;
threads::mac::detail::scoped_critical_region m_mutex_mutex;
#endif
};
class BOOST_THREAD_DECL try_mutex
: private noncopyable
, public boost::detail::named_object
{
public:
friend class detail::thread::lock_ops<try_mutex>;
typedef detail::thread::scoped_lock<try_mutex> scoped_lock;
typedef detail::thread::scoped_try_lock<try_mutex> scoped_try_lock;
try_mutex(const char* name=0);
~try_mutex();
private:
#if defined(BOOST_HAS_WINTHREADS)
typedef void* cv_state;
#elif defined(BOOST_HAS_PTHREADS)
struct cv_state
{
pthread_mutex_t* pmutex;
};
#elif defined(BOOST_HAS_MPTASKS)
struct cv_state
{
};
#endif
void do_lock();
bool do_trylock();
void do_unlock();
void do_lock(cv_state& state);
void do_unlock(cv_state& state);
#if defined(BOOST_HAS_WINTHREADS)
void* m_mutex;
bool m_critical_section;
#elif defined(BOOST_HAS_PTHREADS)
pthread_mutex_t m_mutex;
#elif defined(BOOST_HAS_MPTASKS)
threads::mac::detail::scoped_critical_region m_mutex;
threads::mac::detail::scoped_critical_region m_mutex_mutex;
#endif
};
class BOOST_THREAD_DECL timed_mutex
: private noncopyable
, public boost::detail::named_object
{
public:
friend class detail::thread::lock_ops<timed_mutex>;
typedef detail::thread::scoped_lock<timed_mutex> scoped_lock;
typedef detail::thread::scoped_try_lock<timed_mutex> scoped_try_lock;
typedef detail::thread::scoped_timed_lock<timed_mutex> scoped_timed_lock;
timed_mutex(const char* name=0);
~timed_mutex();
private:
#if defined(BOOST_HAS_WINTHREADS)
typedef void* cv_state;
#elif defined(BOOST_HAS_PTHREADS)
struct cv_state
{
pthread_mutex_t* pmutex;
};
#elif defined(BOOST_HAS_MPTASKS)
struct cv_state
{
};
#endif
void do_lock();
bool do_trylock();
bool do_timedlock(const xtime& xt);
void do_unlock();
void do_lock(cv_state& state);
void do_unlock(cv_state& state);
#if defined(BOOST_HAS_WINTHREADS)
void* m_mutex;
#elif defined(BOOST_HAS_PTHREADS)
pthread_mutex_t m_mutex;
pthread_cond_t m_condition;
bool m_locked;
#elif defined(BOOST_HAS_MPTASKS)
threads::mac::detail::scoped_critical_region m_mutex;
threads::mac::detail::scoped_critical_region m_mutex_mutex;
#endif
};
} // namespace boost
// Change Log:
// 8 Feb 01 WEKEMPF Initial version.
// 22 May 01 WEKEMPF Modified to use xtime for time outs. Factored out
// to three classes, mutex, try_mutex and timed_mutex.
// 3 Jan 03 WEKEMPF Modified for DLL implementation.
#endif // BOOST_MUTEX_WEK070601_HPP

View File

@@ -1,16 +1,42 @@
#ifndef BOOST_THREAD_ONCE_HPP
#define BOOST_THREAD_ONCE_HPP
// once.hpp
// Copyright (C) 2001-2003
// William E. Kempf
//
// (C) Copyright 2006 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/detail/platform.hpp>
#include BOOST_THREAD_PLATFORM(once.hpp)
#ifndef BOOST_ONCE_WEK080101_HPP
#define BOOST_ONCE_WEK080101_HPP
#include <boost/thread/detail/config.hpp>
#if defined(BOOST_HAS_PTHREADS)
# include <pthread.h>
#endif
namespace boost {
#if defined(BOOST_HAS_PTHREADS)
typedef pthread_once_t once_flag;
#define BOOST_ONCE_INIT PTHREAD_ONCE_INIT
#elif (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
typedef long once_flag;
#define BOOST_ONCE_INIT 0
#endif
void BOOST_THREAD_DECL call_once(void (*func)(), once_flag& flag);
} // namespace boost
// Change Log:
// 1 Aug 01 WEKEMPF Initial version.
#endif // BOOST_ONCE_WEK080101_HPP

View File

@@ -1,156 +0,0 @@
// Copyright 2006 Roland Schwarz.
// 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)
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
#ifndef BOOST_THREAD_RS06040707_HPP
#define BOOST_THREAD_RS06040707_HPP
#include <boost/thread/pthread/config.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/utility.hpp>
#include <boost/thread/pthread/lock.hpp>
#include <pthread.h>
namespace boost {
struct xtime;
// disable warnings about non dll import
// see: http://www.boost.org/more/separate_compilation.html#dlls
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4251 4231 4660 4275)
#endif
namespace detail {
class BOOST_THREAD_DECL condition_impl : private noncopyable
{
friend class condition;
public:
condition_impl();
~condition_impl();
void notify_one();
void notify_all();
void do_wait(pthread_mutex_t* pmutex);
bool do_timed_wait(const xtime& xt, pthread_mutex_t* pmutex);
pthread_cond_t m_condition;
};
} // namespace detail
class condition : private noncopyable
{
public:
condition() { }
~condition() { }
void notify_one() { m_impl.notify_one(); }
void notify_all() { m_impl.notify_all(); }
template <typename L>
void wait(L& lock)
{
if (!lock)
throw lock_error();
do_wait(lock.m_mutex);
}
template <typename L, typename Pr>
void wait(L& lock, Pr pred)
{
if (!lock)
throw lock_error();
while (!pred())
do_wait(lock.m_mutex);
}
template <typename L>
bool timed_wait(L& lock, const xtime& xt)
{
if (!lock)
throw lock_error();
return do_timed_wait(lock.m_mutex, xt);
}
template <typename L, typename Pr>
bool timed_wait(L& lock, const xtime& xt, Pr pred)
{
if (!lock)
throw lock_error();
while (!pred())
{
if (!do_timed_wait(lock.m_mutex, xt))
return false;
}
return true;
}
private:
detail::condition_impl m_impl;
template <typename M>
void do_wait(M& mutex)
{
typedef detail::thread::lock_ops<M>
#if defined(__HP_aCC) && __HP_aCC <= 33900 && !defined(BOOST_STRICT_CONFIG)
# define lock_ops lock_ops_ // HP confuses lock_ops witht the template
#endif
lock_ops;
typename lock_ops::lock_state state;
lock_ops::unlock(mutex, state);
m_impl.do_wait(state.pmutex);
lock_ops::lock(mutex, state);
#undef lock_ops
}
template <typename M>
bool do_timed_wait(M& mutex, const xtime& xt)
{
typedef detail::thread::lock_ops<M>
#if defined(__HP_aCC) && __HP_aCC <= 33900 && !defined(BOOST_STRICT_CONFIG)
# define lock_ops lock_ops_ // HP confuses lock_ops witht the template
#endif
lock_ops;
typename lock_ops::lock_state state;
lock_ops::unlock(mutex, state);
bool ret = false;
ret = m_impl.do_timed_wait(xt, state.pmutex);
lock_ops::lock(mutex, state);
#undef lock_ops
return ret;
}
};
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
} // namespace boost
#endif // BOOST_CONDITION_RS06040707_HPP

View File

@@ -1,77 +0,0 @@
// Copyright 2006 Roland Schwarz.
// 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)
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
#ifndef BOOST_THREAD_RS06040702_HPP
#define BOOST_THREAD_RS06040702_HPP
#include <boost/config.hpp>
// insist on threading support being available:
#include <boost/config/requires_threads.hpp>
#if defined(BOOST_THREAD_BUILD_DLL) //Build dll
#elif defined(BOOST_THREAD_BUILD_LIB) //Build lib
#elif defined(BOOST_THREAD_USE_DLL) //Use dll
#elif defined(BOOST_THREAD_USE_LIB) //Use lib
#else //Use default
# if defined(BOOST_HAS_WINTHREADS)
# if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)
//For compilers supporting auto-tss cleanup
//with Boost.Threads lib, use Boost.Threads lib
# define BOOST_THREAD_USE_LIB
# else
//For compilers not yet supporting auto-tss cleanup
//with Boost.Threads lib, use Boost.Threads dll
# define BOOST_THREAD_USE_DLL
# endif
# else
# define BOOST_THREAD_USE_LIB
# endif
#endif
#if defined(BOOST_HAS_DECLSPEC)
# if defined(BOOST_THREAD_BUILD_DLL) //Build dll
# define BOOST_THREAD_DECL __declspec(dllexport)
# elif defined(BOOST_THREAD_USE_DLL) //Use dll
# define BOOST_THREAD_DECL __declspec(dllimport)
# else
# define BOOST_THREAD_DECL
# endif
#else
# define BOOST_THREAD_DECL
#endif // BOOST_HAS_DECLSPEC
//
// Automatically link to the correct build variant where possible.
//
#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_THREAD_NO_LIB) && !defined(BOOST_THREAD_BUILD_DLL) && !defined(BOOST_THREAD_BUILD_LIB)
//
// Tell the autolink to link dynamically, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#if defined(BOOST_THREAD_USE_DLL)
# define BOOST_DYN_LINK
#endif
//
// Set the name of our library, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#if defined(BOOST_THREAD_LIB_NAME)
# define BOOST_LIB_NAME BOOST_THREAD_LIB_NAME
#else
# define BOOST_LIB_NAME boost_thread_pthread
#endif
//
// If we're importing code from a dll, then tell auto_link.hpp about it:
//
// And include the header that does the work:
//
#include <boost/config/auto_link.hpp>
#endif // auto-linking disabled
#endif // BOOST_THREAD_RS06040702_HPP

View File

@@ -1,88 +0,0 @@
// Copyright 2006 Roland Schwarz.
// 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)
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
#ifndef BOOST_THREAD_RS06040709_HPP
#define BOOST_THREAD_RS06040709_HPP
#include <boost/thread/pthread/config.hpp>
#include <string>
#include <stdexcept>
namespace boost {
class BOOST_THREAD_DECL thread_exception : public std::exception
{
protected:
thread_exception();
thread_exception(int sys_err_code);
public:
~thread_exception() throw();
int native_error() const;
const char* message() const;
private:
int m_sys_err;
};
class BOOST_THREAD_DECL lock_error : public thread_exception
{
public:
lock_error();
lock_error(int sys_err_code);
~lock_error() throw();
virtual const char* what() const throw();
};
class BOOST_THREAD_DECL thread_resource_error : public thread_exception
{
public:
thread_resource_error();
thread_resource_error(int sys_err_code);
~thread_resource_error() throw();
virtual const char* what() const throw();
};
class BOOST_THREAD_DECL unsupported_thread_option : public thread_exception
{
public:
unsupported_thread_option();
unsupported_thread_option(int sys_err_code);
~unsupported_thread_option() throw();
virtual const char* what() const throw();
};
class BOOST_THREAD_DECL invalid_thread_argument : public thread_exception
{
public:
invalid_thread_argument();
invalid_thread_argument(int sys_err_code);
~invalid_thread_argument() throw();
virtual const char* what() const throw();
};
class BOOST_THREAD_DECL thread_permission_error : public thread_exception
{
public:
thread_permission_error();
thread_permission_error(int sys_err_code);
~thread_permission_error() throw();
virtual const char* what() const throw();
};
} // namespace boost
#endif // BOOST_THREAD_RS06040709_HPP

View File

@@ -1,116 +0,0 @@
// Copyright 2006 Roland Schwarz.
// 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)
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
#ifndef BOOST_THREAD_RS06040705_HPP
#define BOOST_THREAD_RS06040705_HPP
#include <boost/thread/pthread/config.hpp>
#include <boost/utility.hpp>
#include <boost/thread/pthread/lock.hpp>
#include <pthread.h>
namespace boost {
struct xtime;
// disable warnings about non dll import
// see: http://www.boost.org/more/separate_compilation.html#dlls
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4251 4231 4660 4275)
#endif
class BOOST_THREAD_DECL mutex
: private noncopyable
{
public:
friend class detail::thread::lock_ops<mutex>;
typedef detail::thread::scoped_lock<mutex> scoped_lock;
mutex();
~mutex();
private:
struct cv_state
{
pthread_mutex_t* pmutex;
};
void do_lock();
void do_unlock();
void do_lock(cv_state& state);
void do_unlock(cv_state& state);
pthread_mutex_t m_mutex;
};
class BOOST_THREAD_DECL try_mutex
: private noncopyable
{
public:
friend class detail::thread::lock_ops<try_mutex>;
typedef detail::thread::scoped_lock<try_mutex> scoped_lock;
typedef detail::thread::scoped_try_lock<try_mutex> scoped_try_lock;
try_mutex();
~try_mutex();
private:
struct cv_state
{
pthread_mutex_t* pmutex;
};
void do_lock();
bool do_trylock();
void do_unlock();
void do_lock(cv_state& state);
void do_unlock(cv_state& state);
pthread_mutex_t m_mutex;
};
class BOOST_THREAD_DECL timed_mutex
: private noncopyable
{
public:
friend class detail::thread::lock_ops<timed_mutex>;
typedef detail::thread::scoped_lock<timed_mutex> scoped_lock;
typedef detail::thread::scoped_try_lock<timed_mutex> scoped_try_lock;
typedef detail::thread::scoped_timed_lock<timed_mutex> scoped_timed_lock;
timed_mutex();
~timed_mutex();
private:
struct cv_state
{
pthread_mutex_t* pmutex;
};
void do_lock();
bool do_trylock();
bool do_timedlock(const xtime& xt);
void do_unlock();
void do_lock(cv_state& state);
void do_unlock(cv_state& state);
pthread_mutex_t m_mutex;
pthread_cond_t m_condition;
bool m_locked;
};
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
} // namespace boost
#endif // BOOST_MUTEX_RS06040705_HPP

View File

@@ -1,74 +0,0 @@
#ifndef BOOST_THREAD_PTHREAD_ONCE_HPP
#define BOOST_THREAD_PTHREAD_ONCE_HPP
// once.hpp
//
// (C) Copyright 2007 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/pthread/config.hpp>
#include <pthread.h>
#include <boost/assert.hpp>
namespace boost {
struct once_flag
{
pthread_mutex_t mutex;
unsigned flag;
};
#define BOOST_ONCE_INIT {PTHREAD_MUTEX_INITIALIZER,0}
namespace detail
{
struct pthread_mutex_scoped_lock
{
pthread_mutex_t * mutex;
explicit pthread_mutex_scoped_lock(pthread_mutex_t* mutex_):
mutex(mutex_)
{
int const res=pthread_mutex_lock(mutex);
BOOST_ASSERT(!res);
}
~pthread_mutex_scoped_lock()
{
int const res=pthread_mutex_unlock(mutex);
BOOST_ASSERT(!res);
}
};
}
template<typename Function>
void call_once(once_flag& flag,Function f)
{
long const function_complete_flag_value=0xc15730e2;
#ifdef BOOST_PTHREAD_HAS_ATOMICS
if(::boost::detail::interlocked_read_acquire(&flag.flag)!=function_complete_flag_value)
{
#endif
detail::pthread_mutex_scoped_lock const lock(&flag.mutex);
if(flag.flag!=function_complete_flag_value)
{
f();
#ifdef BOOST_PTHREAD_HAS_ATOMICS
::boost::detail::interlocked_write_release(&flag.flag,function_complete_flag_value);
#else
flag.flag=function_complete_flag_value;
#endif
}
#ifdef BOOST_PTHREAD_HAS_ATOMICS
}
#endif
}
}
#endif

View File

@@ -1,389 +0,0 @@
#ifndef BOOST_THREAD_PTHREAD_READ_WRITE_MUTEX_HPP
#define BOOST_THREAD_PTHREAD_READ_WRITE_MUTEX_HPP
// (C) Copyright 2006-7 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
#include <boost/thread/xtime.hpp>
namespace boost
{
class read_write_mutex
{
private:
struct state_data
{
unsigned shared_count:10;
unsigned exclusive:1;
unsigned upgradeable:1;
unsigned exclusive_waiting_blocked:1;
};
state_data state;
boost::mutex state_change;
boost::condition shared_cond;
boost::condition exclusive_cond;
boost::condition upgradeable_cond;
void release_waiters()
{
exclusive_cond.notify_one();
shared_cond.notify_all();
}
public:
read_write_mutex()
{
state_data state_={0};
state=state_;
}
~read_write_mutex()
{
}
void lock_shareable()
{
boost::mutex::scoped_lock lock(state_change);
while(true)
{
if(!state.exclusive && !state.exclusive_waiting_blocked)
{
++state.shared_count;
return;
}
shared_cond.wait(lock);
}
}
bool try_lock_shareable()
{
boost::mutex::scoped_lock lock(state_change);
if(state.exclusive || state.exclusive_waiting_blocked)
{
return false;
}
else
{
++state.shared_count;
return true;
}
}
bool timed_lock_shareable(xtime const& timeout)
{
boost::mutex::scoped_lock lock(state_change);
while(true)
{
if(!state.exclusive && !state.exclusive_waiting_blocked)
{
++state.shared_count;
return true;
}
if(!shared_cond.timed_wait(lock,timeout))
{
return false;
}
}
}
void unlock_shareable()
{
boost::mutex::scoped_lock lock(state_change);
bool const last_reader=!--state.shared_count;
if(last_reader)
{
if(state.upgradeable)
{
state.upgradeable=false;
state.exclusive=true;
upgradeable_cond.notify_one();
}
else
{
state.exclusive_waiting_blocked=false;
}
release_waiters();
}
}
void lock()
{
boost::mutex::scoped_lock lock(state_change);
while(true)
{
if(state.shared_count || state.exclusive)
{
state.exclusive_waiting_blocked=true;
}
else
{
state.exclusive=true;
return;
}
exclusive_cond.wait(lock);
}
}
bool timed_lock(xtime const& timeout)
{
boost::mutex::scoped_lock lock(state_change);
while(true)
{
if(state.shared_count || state.exclusive)
{
state.exclusive_waiting_blocked=true;
}
else
{
state.exclusive=true;
return true;
}
if(!exclusive_cond.timed_wait(lock,timeout))
{
return false;
}
}
}
bool try_lock()
{
boost::mutex::scoped_lock lock(state_change);
if(state.shared_count || state.exclusive)
{
return false;
}
else
{
state.exclusive=true;
return true;
}
}
void unlock()
{
boost::mutex::scoped_lock lock(state_change);
state.exclusive=false;
state.exclusive_waiting_blocked=false;
release_waiters();
}
void lock_upgradeable()
{
boost::mutex::scoped_lock lock(state_change);
while(true)
{
if(!state.exclusive && !state.exclusive_waiting_blocked && !state.upgradeable)
{
++state.shared_count;
state.upgradeable=true;
return;
}
shared_cond.wait(lock);
}
}
bool timed_lock_upgradeable(xtime const& timeout)
{
boost::mutex::scoped_lock lock(state_change);
while(true)
{
if(!state.exclusive && !state.exclusive_waiting_blocked && !state.upgradeable)
{
++state.shared_count;
state.upgradeable=true;
return true;
}
if(!shared_cond.timed_wait(lock,timeout))
{
return false;
}
}
}
bool try_lock_upgradeable()
{
boost::mutex::scoped_lock lock(state_change);
if(state.exclusive || state.exclusive_waiting_blocked || state.upgradeable)
{
return false;
}
else
{
++state.shared_count;
state.upgradeable=true;
return true;
}
}
void unlock_upgradeable()
{
boost::mutex::scoped_lock lock(state_change);
state.upgradeable=false;
bool const last_reader=!--state.shared_count;
if(last_reader)
{
state.exclusive_waiting_blocked=false;
release_waiters();
}
}
void unlock_upgradeable_and_lock()
{
boost::mutex::scoped_lock lock(state_change);
--state.shared_count;
while(true)
{
if(!state.shared_count)
{
state.upgradeable=false;
state.exclusive=true;
break;
}
upgradeable_cond.wait(lock);
}
}
void unlock_and_lock_upgradeable()
{
boost::mutex::scoped_lock lock(state_change);
state.exclusive=false;
state.upgradeable=true;
++state.shared_count;
state.exclusive_waiting_blocked=false;
release_waiters();
}
void unlock_and_lock_shareable()
{
boost::mutex::scoped_lock lock(state_change);
state.exclusive=false;
++state.shared_count;
state.exclusive_waiting_blocked=false;
release_waiters();
}
void unlock_upgradeable_and_lock_shareable()
{
boost::mutex::scoped_lock lock(state_change);
state.upgradeable=false;
state.exclusive_waiting_blocked=false;
release_waiters();
}
class scoped_read_lock
{
read_write_mutex& m;
public:
scoped_read_lock(read_write_mutex& m_):
m(m_)
{
m.lock_shareable();
}
~scoped_read_lock()
{
m.unlock_shareable();
}
};
class scoped_write_lock
{
read_write_mutex& m;
bool locked;
public:
scoped_write_lock(read_write_mutex& m_):
m(m_),locked(false)
{
lock();
}
void lock()
{
m.lock();
locked=true;
}
void unlock()
{
m.unlock();
locked=false;
}
~scoped_write_lock()
{
if(locked)
{
unlock();
}
}
};
class scoped_upgradeable_lock
{
read_write_mutex& m;
bool locked;
bool upgraded;
public:
scoped_upgradeable_lock(read_write_mutex& m_):
m(m_),
locked(false),upgraded(false)
{
lock();
}
void lock()
{
m.lock_upgradeable();
locked=true;
}
void upgrade()
{
m.unlock_upgradeable_and_lock();
upgraded=true;
}
void unlock()
{
if(upgraded)
{
m.unlock();
}
else
{
m.unlock_upgradeable();
}
}
~scoped_upgradeable_lock()
{
if(locked)
{
unlock();
}
}
};
};
}
#endif

View File

@@ -1,136 +0,0 @@
// Copyright (C) 2001-2003 William E. Kempf
// Copyright (C) 2006 Roland Schwarz
// 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)
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
#ifndef BOOST_RECURSIVE_MUTEX_RS06092302_HPP
#define BOOST_RECURSIVE_MUTEX_RS06092302_HPP
#include <boost/thread/pthread/config.hpp>
#include <boost/utility.hpp>
#include <boost/thread/pthread/lock.hpp>
#include <pthread.h>
namespace boost {
struct xtime;
// disable warnings about non dll import
// see: http://www.boost.org/more/separate_compilation.html#dlls
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4251 4231 4660 4275)
#endif
class BOOST_THREAD_DECL recursive_mutex
: private noncopyable
{
public:
friend class detail::thread::lock_ops<recursive_mutex>;
typedef detail::thread::scoped_lock<recursive_mutex> scoped_lock;
recursive_mutex();
~recursive_mutex();
private:
struct cv_state
{
long count;
pthread_mutex_t* pmutex;
};
void do_lock();
void do_unlock();
void do_lock(cv_state& state);
void do_unlock(cv_state& state);
pthread_mutex_t m_mutex;
unsigned m_count;
#if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
pthread_cond_t m_unlocked;
pthread_t m_thread_id;
bool m_valid_id;
#endif
};
class BOOST_THREAD_DECL recursive_try_mutex
: private noncopyable
{
public:
friend class detail::thread::lock_ops<recursive_try_mutex>;
typedef detail::thread::scoped_lock<recursive_try_mutex> scoped_lock;
typedef detail::thread::scoped_try_lock<
recursive_try_mutex> scoped_try_lock;
recursive_try_mutex();
~recursive_try_mutex();
private:
struct cv_state
{
long count;
pthread_mutex_t* pmutex;
};
void do_lock();
bool do_trylock();
void do_unlock();
void do_lock(cv_state& state);
void do_unlock(cv_state& state);
pthread_mutex_t m_mutex;
unsigned m_count;
#if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
pthread_cond_t m_unlocked;
pthread_t m_thread_id;
bool m_valid_id;
#endif
};
class BOOST_THREAD_DECL recursive_timed_mutex
: private noncopyable
{
public:
friend class detail::thread::lock_ops<recursive_timed_mutex>;
typedef detail::thread::scoped_lock<recursive_timed_mutex> scoped_lock;
typedef detail::thread::scoped_try_lock<
recursive_timed_mutex> scoped_try_lock;
typedef detail::thread::scoped_timed_lock<
recursive_timed_mutex> scoped_timed_lock;
recursive_timed_mutex();
~recursive_timed_mutex();
private:
struct cv_state
{
long count;
pthread_mutex_t* pmutex;
};
void do_lock();
bool do_trylock();
bool do_timedlock(const xtime& xt);
void do_unlock();
void do_lock(cv_state& state);
void do_unlock(cv_state& state);
pthread_mutex_t m_mutex;
pthread_cond_t m_unlocked;
pthread_t m_thread_id;
bool m_valid_id;
unsigned m_count;
};
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
} // namespace boost
#endif // BOOST_RECURSIVE_MUTEX_RS06092302_HPP

View File

@@ -1,75 +0,0 @@
// Copyright 2006 Roland Schwarz.
// 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)
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
#ifndef BOOST_THREAD_RS06040701_HPP
#define BOOST_THREAD_RS06040701_HPP
#include <boost/thread/pthread/config.hpp>
#include <boost/thread/pthread/mutex.hpp>
#include <boost/utility.hpp>
#include <boost/function.hpp>
#include <list>
#include <memory>
#include <pthread.h>
namespace boost {
struct xtime;
// disable warnings about non dll import
// see: http://www.boost.org/more/separate_compilation.html#dlls
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4251 4231 4660 4275)
#endif
class BOOST_THREAD_DECL thread : private noncopyable
{
public:
thread();
explicit thread(const function0<void>& threadfunc);
~thread();
bool operator==(const thread& other) const;
bool operator!=(const thread& other) const;
void join();
static void sleep(const xtime& xt);
static void yield();
private:
pthread_t m_thread;
bool m_joinable;
};
class BOOST_THREAD_DECL thread_group : private noncopyable
{
public:
thread_group();
~thread_group();
thread* create_thread(const function0<void>& threadfunc);
void add_thread(thread* thrd);
void remove_thread(thread* thrd);
void join_all();
int size();
private:
std::list<thread*> m_threads;
mutex m_mutex;
};
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
} // namespace boost
#endif // BOOST_THREAD_RS06040701_HPP

View File

@@ -1,108 +0,0 @@
// Copyright (C) 2001-2003 William E. Kempf
// Copyright (C) 2006 Roland Schwarz
// 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)
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
#ifndef BOOST_TSS_RS06092304_HPP
#define BOOST_TSS_RS06092304_HPP
#include <boost/thread/pthread/config.hpp>
#include <boost/utility.hpp>
#include <boost/function.hpp>
#include <boost/thread/pthread/exceptions.hpp>
#include <pthread.h>
namespace boost {
// disable warnings about non dll import
// see: http://www.boost.org/more/separate_compilation.html#dlls
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4251 4231 4660 4275)
#endif
namespace detail {
class BOOST_THREAD_DECL tss : private noncopyable
{
public:
tss(boost::function1<void, void*>* pcleanup) {
if (pcleanup == 0) throw boost::thread_resource_error();
try
{
init(pcleanup);
}
catch (...)
{
delete pcleanup;
throw boost::thread_resource_error();
}
}
void* get() const;
void set(void* value);
void cleanup(void* p);
private:
unsigned int m_slot; //This is a "pseudo-slot", not a native slot
void init(boost::function1<void, void*>* pcleanup);
};
template <typename T>
struct tss_adapter
{
template <typename F>
tss_adapter(const F& cleanup) : m_cleanup(cleanup) { }
void operator()(void* p) { m_cleanup(static_cast<T*>(p)); }
boost::function1<void, T*> m_cleanup;
};
} // namespace detail
template <typename T>
class thread_specific_ptr : private noncopyable
{
public:
thread_specific_ptr()
: m_tss(new boost::function1<void, void*>(
boost::detail::tss_adapter<T>(
&thread_specific_ptr<T>::cleanup)))
{
}
thread_specific_ptr(void (*clean)(T*))
: m_tss(new boost::function1<void, void*>(
boost::detail::tss_adapter<T>(clean)))
{
}
~thread_specific_ptr() { reset(); }
T* get() const { return static_cast<T*>(m_tss.get()); }
T* operator->() const { return get(); }
T& operator*() const { return *get(); }
T* release() { T* temp = get(); if (temp) m_tss.set(0); return temp; }
void reset(T* p=0)
{
T* cur = get();
if (cur == p) return;
m_tss.set(p);
if (cur) m_tss.cleanup(cur);
}
private:
static void cleanup(T* p) { delete p; }
detail::tss m_tss;
};
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
} // namespace boost
#endif //BOOST_TSS_RS06092304_HPP

View File

@@ -1,56 +0,0 @@
// Copyright 2006 Roland Schwarz.
// 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)
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
#ifndef BOOST_THREAD_RS06040711_HPP
#define BOOST_THREAD_RS06040711_HPP
#include <boost/thread/pthread/config.hpp>
#include <boost/cstdint.hpp>
namespace boost {
enum xtime_clock_types
{
TIME_UTC=1
// TIME_TAI,
// TIME_MONOTONIC,
// TIME_PROCESS,
// TIME_THREAD,
// TIME_LOCAL,
// TIME_SYNC,
// TIME_RESOLUTION
};
struct xtime
{
#if defined(BOOST_NO_INT64_T)
typedef int_fast32_t xtime_sec_t; //INT_FAST32_MIN <= sec <= INT_FAST32_MAX
#else
typedef int_fast64_t xtime_sec_t; //INT_FAST64_MIN <= sec <= INT_FAST64_MAX
#endif
typedef int_fast32_t xtime_nsec_t; //0 <= xtime.nsec < NANOSECONDS_PER_SECOND
xtime_sec_t sec;
xtime_nsec_t nsec;
};
int BOOST_THREAD_DECL xtime_get(struct xtime* xtp, int clock_type);
inline int xtime_cmp(const xtime& xt1, const xtime& xt2)
{
if (xt1.sec == xt2.sec)
return (int)(xt1.nsec - xt2.nsec);
else
return (xt1.sec > xt2.sec) ? 1 : -1;
}
} // namespace boost
#endif //BOOST_THREAD_RS06040711_HPP

View File

@@ -1,13 +1,271 @@
#ifndef BOOST_THREAD_READ_WRITE_MUTEX_HPP
#define BOOST_THREAD_READ_WRITE_MUTEX_HPP
// Copyright (C) 2002-2003
// David Moore, William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. David Moore makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
// (C) Copyright 2006 Anthony Williams
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// A Boost::threads implementation of a synchronization
// primitive which can allow multiple readers or a single
// writer to have access to a shared resource.
#ifndef BOOST_READ_WRITE_MUTEX_JDM030602_HPP
#define BOOST_READ_WRITE_MUTEX_JDM030602_HPP
#include <boost/thread/detail/config.hpp>
#include <boost/utility.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/detail/lock.hpp>
#include <boost/thread/detail/read_write_lock.hpp>
#include <boost/thread/condition.hpp>
namespace boost {
namespace read_write_scheduling_policy {
enum read_write_scheduling_policy_enum
{
writer_priority, //Prefer writers; can starve readers
reader_priority, //Prefer readers; can starve writers
alternating_many_reads, //Alternate readers and writers; before a writer, release all queued readers
alternating_single_read //Alternate readers and writers; before a writer, release only on queued reader
};
} // namespace read_write_scheduling_policy
namespace detail {
namespace thread {
// Shared implementation construct for explicit Scheduling Policies
// This implementation is susceptible to self-deadlock, though....
template<typename Mutex>
struct read_write_mutex_impl
{
typedef Mutex mutex_type;
typedef detail::thread::scoped_lock<Mutex> scoped_lock;
typedef detail::thread::scoped_try_lock<Mutex> scoped_try_lock;
typedef detail::thread::scoped_timed_lock<Mutex> scoped_timed_lock;
read_write_mutex_impl(read_write_scheduling_policy::read_write_scheduling_policy_enum sp)
: m_num_waiting_writers(0),
m_num_waiting_readers(0),
m_num_readers_to_wake(0),
m_state_waiting_promotion(false),
m_state(0),
m_sp(sp),
m_readers_next(true) { }
Mutex m_prot;
boost::condition m_waiting_writers;
boost::condition m_waiting_readers;
int m_num_waiting_writers;
int m_num_waiting_readers;
int m_num_readers_to_wake;
boost::condition m_waiting_promotion;
bool m_state_waiting_promotion;
int m_state; // -1 = excl locked
// 0 = unlocked
// 1-> INT_MAX - shared locked
const read_write_scheduling_policy::read_write_scheduling_policy_enum m_sp;
bool m_readers_next;
void do_read_lock();
void do_write_lock();
void do_write_unlock();
void do_read_unlock();
bool do_try_write_lock();
bool do_try_read_lock();
bool do_timed_write_lock(const xtime &xt);
bool do_timed_read_lock(const xtime &xt);
void do_demote_to_read_lock();
bool do_try_demote_to_read_lock();
bool do_timed_demote_to_read_lock(const xtime &xt);
void do_promote_to_write_lock();
bool do_try_promote_to_write_lock();
bool do_timed_promote_to_write_lock(const xtime &xt);
bool locked();
read_write_lock_state::read_write_lock_state_enum state();
private:
void do_unlock_scheduling_impl();
void do_demote_scheduling_impl();
void do_scheduling_impl();
bool do_demote_to_read_lock_impl();
};
} // namespace detail
} // namespace thread
class BOOST_THREAD_DECL read_write_mutex : private noncopyable
{
public:
read_write_mutex(read_write_scheduling_policy::read_write_scheduling_policy_enum sp) : m_impl(sp) { }
~read_write_mutex() { }
read_write_scheduling_policy::read_write_scheduling_policy_enum policy() const { return m_impl.m_sp; }
friend class detail::thread::read_write_lock_ops<read_write_mutex>;
typedef detail::thread::scoped_read_write_lock<
read_write_mutex> scoped_read_write_lock;
typedef detail::thread::scoped_read_lock<
read_write_mutex> scoped_read_lock;
typedef detail::thread::scoped_write_lock<
read_write_mutex> scoped_write_lock;
private:
// Operations that will eventually be done only
// via lock types
void do_write_lock();
void do_read_lock();
void do_write_unlock();
void do_read_unlock();
void do_demote_to_read_lock();
void do_promote_to_write_lock();
bool locked();
read_write_lock_state::read_write_lock_state_enum state();
detail::thread::read_write_mutex_impl<mutex> m_impl;
};
class BOOST_THREAD_DECL try_read_write_mutex : private noncopyable
{
public:
try_read_write_mutex(read_write_scheduling_policy::read_write_scheduling_policy_enum sp) : m_impl(sp) { }
~try_read_write_mutex() { }
read_write_scheduling_policy::read_write_scheduling_policy_enum policy() const { return m_impl.m_sp; }
friend class detail::thread::read_write_lock_ops<try_read_write_mutex>;
typedef detail::thread::scoped_read_write_lock<
try_read_write_mutex> scoped_read_write_lock;
typedef detail::thread::scoped_try_read_write_lock<
try_read_write_mutex> scoped_try_read_write_lock;
typedef detail::thread::scoped_read_lock<
try_read_write_mutex> scoped_read_lock;
typedef detail::thread::scoped_try_read_lock<
try_read_write_mutex> scoped_try_read_lock;
typedef detail::thread::scoped_write_lock<
try_read_write_mutex> scoped_write_lock;
typedef detail::thread::scoped_try_write_lock<
try_read_write_mutex> scoped_try_write_lock;
private:
// Operations that will eventually be done only
// via lock types
void do_write_lock();
void do_read_lock();
void do_write_unlock();
void do_read_unlock();
bool do_try_write_lock();
bool do_try_read_lock();
#include <boost/thread/detail/platform.hpp>
#include BOOST_THREAD_PLATFORM(read_write_mutex.hpp)
void do_demote_to_read_lock();
bool do_try_demote_to_read_lock();
void do_promote_to_write_lock();
bool do_try_promote_to_write_lock();
bool locked();
read_write_lock_state::read_write_lock_state_enum state();
detail::thread::read_write_mutex_impl<try_mutex> m_impl;
};
class BOOST_THREAD_DECL timed_read_write_mutex : private noncopyable
{
public:
timed_read_write_mutex(read_write_scheduling_policy::read_write_scheduling_policy_enum sp) : m_impl(sp) { }
~timed_read_write_mutex() { }
read_write_scheduling_policy::read_write_scheduling_policy_enum policy() const { return m_impl.m_sp; }
friend class detail::thread::read_write_lock_ops<timed_read_write_mutex>;
typedef detail::thread::scoped_read_write_lock<
timed_read_write_mutex> scoped_read_write_lock;
typedef detail::thread::scoped_try_read_write_lock<
timed_read_write_mutex> scoped_try_read_write_lock;
typedef detail::thread::scoped_timed_read_write_lock<
timed_read_write_mutex> scoped_timed_read_write_lock;
typedef detail::thread::scoped_read_lock<
timed_read_write_mutex> scoped_read_lock;
typedef detail::thread::scoped_try_read_lock<
timed_read_write_mutex> scoped_try_read_lock;
typedef detail::thread::scoped_timed_read_lock<
timed_read_write_mutex> scoped_timed_read_lock;
typedef detail::thread::scoped_write_lock<
timed_read_write_mutex> scoped_write_lock;
typedef detail::thread::scoped_try_write_lock<
timed_read_write_mutex> scoped_try_write_lock;
typedef detail::thread::scoped_timed_write_lock<
timed_read_write_mutex> scoped_timed_write_lock;
private:
// Operations that will eventually be done only
// via lock types
void do_write_lock();
void do_read_lock();
void do_write_unlock();
void do_read_unlock();
bool do_try_write_lock();
bool do_try_read_lock();
bool do_timed_write_lock(const xtime &xt);
bool do_timed_read_lock(const xtime &xt);
void do_demote_to_read_lock();
bool do_try_demote_to_read_lock();
bool do_timed_demote_to_read_lock(const xtime &xt);
void do_promote_to_write_lock();
bool do_try_promote_to_write_lock();
bool do_timed_promote_to_write_lock(const xtime &xt);
bool locked();
read_write_lock_state::read_write_lock_state_enum state();
detail::thread::read_write_mutex_impl<timed_mutex> m_impl;
};
} // namespace boost
#endif
// Change Log:
// 10 Mar 02
// Original version.
// 4 May 04 GlassfordM
// Implement lock promotion and demotion.
// Add locked() and state() member functions for debugging
// (should these be made public?).
// Rename to improve consistency and eliminate abbreviations:
// Use "read" and "write" instead of "shared" and "exclusive".
// Change "rd" to "read", "wr" to "write", "rw" to "read_write".
// Add mutex_type typdef.

View File

@@ -1,16 +1,186 @@
#ifndef BOOST_THREAD_RECURSIVE_MUTEX_HPP
#define BOOST_THREAD_RECURSIVE_MUTEX_HPP
// recursive_mutex.hpp
// Copyright (C) 2001-2003
// William E. Kempf
//
// (C) Copyright 2006 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/detail/platform.hpp>
#include BOOST_THREAD_PLATFORM(recursive_mutex.hpp)
#ifndef BOOST_RECURSIVE_MUTEX_WEK070601_HPP
#define BOOST_RECURSIVE_MUTEX_WEK070601_HPP
#include <boost/thread/detail/config.hpp>
#include <boost/utility.hpp>
#include <boost/thread/detail/lock.hpp>
#include <boost/thread/detail/named.hpp>
#if defined(BOOST_HAS_PTHREADS)
# include <pthread.h>
#endif
#if defined(BOOST_HAS_MPTASKS)
# include "scoped_critical_region.hpp"
#endif
namespace boost {
struct xtime;
class BOOST_THREAD_DECL recursive_mutex
: private noncopyable
, public boost::detail::named_object
{
public:
friend class detail::thread::lock_ops<recursive_mutex>;
typedef detail::thread::scoped_lock<recursive_mutex> scoped_lock;
recursive_mutex(const char* name=0);
~recursive_mutex();
private:
#if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
typedef std::size_t cv_state;
#elif defined(BOOST_HAS_PTHREADS)
struct cv_state
{
long count;
pthread_mutex_t* pmutex;
};
#endif
void do_lock();
void do_unlock();
void do_lock(cv_state& state);
void do_unlock(cv_state& state);
#if defined(BOOST_HAS_WINTHREADS)
void* m_mutex;
bool m_critical_section;
unsigned long m_count;
#elif defined(BOOST_HAS_PTHREADS)
pthread_mutex_t m_mutex;
unsigned m_count;
# if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
pthread_cond_t m_unlocked;
pthread_t m_thread_id;
bool m_valid_id;
# endif
#elif defined(BOOST_HAS_MPTASKS)
threads::mac::detail::scoped_critical_region m_mutex;
threads::mac::detail::scoped_critical_region m_mutex_mutex;
std::size_t m_count;
#endif
};
class BOOST_THREAD_DECL recursive_try_mutex
: private noncopyable
, public boost::detail::named_object
{
public:
friend class detail::thread::lock_ops<recursive_try_mutex>;
typedef detail::thread::scoped_lock<recursive_try_mutex> scoped_lock;
typedef detail::thread::scoped_try_lock<
recursive_try_mutex> scoped_try_lock;
recursive_try_mutex(const char* name=0);
~recursive_try_mutex();
private:
#if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
typedef std::size_t cv_state;
#elif defined(BOOST_HAS_PTHREADS)
struct cv_state
{
long count;
pthread_mutex_t* pmutex;
};
#endif
void do_lock();
bool do_trylock();
void do_unlock();
void do_lock(cv_state& state);
void do_unlock(cv_state& state);
#if defined(BOOST_HAS_WINTHREADS)
void* m_mutex;
bool m_critical_section;
unsigned long m_count;
#elif defined(BOOST_HAS_PTHREADS)
pthread_mutex_t m_mutex;
unsigned m_count;
# if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
pthread_cond_t m_unlocked;
pthread_t m_thread_id;
bool m_valid_id;
# endif
#elif defined(BOOST_HAS_MPTASKS)
threads::mac::detail::scoped_critical_region m_mutex;
threads::mac::detail::scoped_critical_region m_mutex_mutex;
std::size_t m_count;
#endif
};
class BOOST_THREAD_DECL recursive_timed_mutex
: private noncopyable
, public boost::detail::named_object
{
public:
friend class detail::thread::lock_ops<recursive_timed_mutex>;
typedef detail::thread::scoped_lock<recursive_timed_mutex> scoped_lock;
typedef detail::thread::scoped_try_lock<
recursive_timed_mutex> scoped_try_lock;
typedef detail::thread::scoped_timed_lock<
recursive_timed_mutex> scoped_timed_lock;
recursive_timed_mutex(const char* name=0);
~recursive_timed_mutex();
private:
#if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
typedef std::size_t cv_state;
#elif defined(BOOST_HAS_PTHREADS)
struct cv_state
{
long count;
pthread_mutex_t* pmutex;
};
#endif
void do_lock();
bool do_trylock();
bool do_timedlock(const xtime& xt);
void do_unlock();
void do_lock(cv_state& state);
void do_unlock(cv_state& state);
#if defined(BOOST_HAS_WINTHREADS)
void* m_mutex;
unsigned long m_count;
#elif defined(BOOST_HAS_PTHREADS)
pthread_mutex_t m_mutex;
pthread_cond_t m_unlocked;
pthread_t m_thread_id;
bool m_valid_id;
unsigned m_count;
#elif defined(BOOST_HAS_MPTASKS)
threads::mac::detail::scoped_critical_region m_mutex;
threads::mac::detail::scoped_critical_region m_mutex_mutex;
std::size_t m_count;
#endif
};
} // namespace boost
#endif // BOOST_RECURSIVE_MUTEX_WEK070601_HPP
// Change Log:
// 8 Feb 01 WEKEMPF Initial version.
// 1 Jun 01 WEKEMPF Modified to use xtime for time outs. Factored out
// to three classes, mutex, try_mutex and timed_mutex.
// 11 Jun 01 WEKEMPF Modified to use PTHREAD_MUTEX_RECURSIVE if available.
// 3 Jan 03 WEKEMPF Modified for DLL implementation.

View File

@@ -0,0 +1,58 @@
// Copyright (C) 2002-2003
// William E. Kempf, David Moore
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_MUTEX_JDM062402_HPP
#define BOOST_MUTEX_JDM062402_HPP
#include <boost/thread/detail/config.hpp>
#include <boost/utility.hpp>
#include <boost/function.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/thread/detail/named.hpp>
#include <string>
namespace boost {
class shared_memory : public boost::detail::named_object
{
public:
enum {
write=0x1,
create=0x2,
exclusive=0x4,
};
shared_memory(const char *name, std::size_t len, int flags);
shared_memory(const char *name, std::size_t len, int flags,
const boost::function1<void,void *>& initfunc);
~shared_memory();
void* get() const { return m_ptr; }
private:
void init(std::size_t len, int flags,
const boost::function1<void, void*>* initfunc);
void *m_ptr; // Pointer to shared memory block
#if defined(BOOST_HAS_WINTHREADS)
void* m_hmap;
#elif defined(BOOST_HAS_PTHREADS)
std::size_t m_len;
int m_hmap;
#endif
};
} // namespace boost
#endif

View File

@@ -1,16 +1,193 @@
// Copyright 2006 Roland Schwarz.
// 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)
// Copyright (C) 2001-2003
// William E. Kempf
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_THREAD_RS06032802_HPP
#define BOOST_THREAD_RS06032802_HPP
#ifndef BOOST_THREAD_WEK070601_HPP
#define BOOST_THREAD_WEK070601_HPP
#include <boost/thread/detail/platform.hpp>
#include BOOST_THREAD_PLATFORM(thread.hpp)
#include <boost/thread/detail/config.hpp>
#endif // BOOST_THREAD_RS06032802_HPP
#include <boost/function.hpp>
#include <boost/thread/mutex.hpp>
#include <iostream>
#include <list>
#include <memory>
#if defined(BOOST_HAS_PTHREADS)
# include <pthread.h>
# include <boost/thread/condition.hpp>
#elif defined(BOOST_HAS_MPTASKS)
# include <Multiprocessing.h>
#endif
namespace boost {
struct xtime;
class BOOST_THREAD_DECL thread_cancel
{
public:
thread_cancel();
~thread_cancel();
};
class BOOST_THREAD_DECL cancellation_guard
{
public:
cancellation_guard();
~cancellation_guard();
private:
void* m_handle;
};
#if defined(BOOST_HAS_WINTHREADS)
struct sched_param
{
int priority;
};
enum { sched_fifo, sched_round_robin, sched_other };
enum { scope_process, scope_system };
#elif defined(BOOST_HAS_PTHREADS)
using ::sched_param;
enum
{
sched_fifo = SCHED_FIFO,
sched_round_robin = SCHED_RR,
sched_other = SCHED_OTHER
};
enum
{
scope_process = PTHREAD_SCOPE_PROCESS,
scope_system = PTHREAD_SCOPE_SYSTEM
};
#endif
class BOOST_THREAD_DECL thread
{
public:
class BOOST_THREAD_DECL attributes
{
public:
attributes();
~attributes();
attributes& set_stack_size(size_t size);
size_t get_stack_size() const;
attributes& set_stack_address(void* addr);
void* get_stack_address() const;
attributes& inherit_scheduling(bool inherit);
bool inherit_scheduling() const;
attributes& set_schedule(int policy, const sched_param& param);
void get_schedule(int& policy, sched_param& param);
attributes& scope(int scope);
int scope() const;
private:
friend class thread;
#if defined(BOOST_HAS_WINTHREADS)
size_t m_stacksize;
bool m_schedinherit;
sched_param m_schedparam;
#elif defined(BOOST_HAS_PTHREADS)
pthread_attr_t m_attr;
#endif
};
thread();
explicit thread(const function0<void>& threadfunc,
const attributes& attr=attributes());
thread(const thread& other);
~thread();
thread& operator=(const thread& other);
bool operator==(const thread& other) const;
bool operator!=(const thread& other) const;
bool operator<(const thread& other) const;
void join();
bool timed_join(const xtime& xt);
void cancel();
bool cancelled() const;
void set_scheduling_parameter(int policy, const sched_param& param);
void get_scheduling_parameter(int& policy, sched_param& param) const;
static int max_priority(int policy);
static int min_priority(int policy);
static void test_cancel();
static void sleep(const xtime& xt);
static void yield();
static const int stack_min;
#if defined(BOOST_HAS_WINTHREADS)
typedef unsigned int id_type;
#else
typedef const void* id_type;
#endif
id_type id() const;
private:
void* m_handle;
};
template <typename charT, typename Traits>
std::basic_ostream<charT, Traits>& operator<<(
std::basic_ostream<charT, Traits>& os, const thread& thrd)
{
if (!os.good()) return os;
typename std::basic_ostream<charT, Traits>::sentry opfx(os);
if (opfx)
os << thrd.id();
return os;
}
class BOOST_THREAD_DECL thread_group : private noncopyable
{
public:
thread_group();
~thread_group();
thread create_thread(const function0<void>& threadfunc);
void add_thread(thread thrd);
void remove_thread(thread thrd);
// thread* thread_group::find(thread& thrd);
void join_all();
private:
std::list<thread> m_threads;
mutex m_mutex;
};
} // namespace boost
#endif // BOOST_THREAD_WEK070601_HPP
// Change Log:
// 8 Feb 01 WEKEMPF Initial version.
// 1 Jun 01 WEKEMPF Added boost::thread initial implementation.
// 3 Jul 01 WEKEMPF Redesigned boost::thread to be noncopyable.

View File

@@ -0,0 +1,44 @@
// Copyright (C) 2002-2003
// David Moore, William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
// Derived loosely from work queue manager in "Programming POSIX Threads"
// by David Butenhof.
#ifndef BOOST_THREAD_POOL_JDM031802_HPP
#define BOOST_THREAD_POOL_JDM031802_HPP
#include <boost/thread/detail/config.hpp>
#include <boost/function.hpp>
#include <boost/limits.hpp>
namespace boost {
class BOOST_THREAD_DECL thread_pool
{
public:
thread_pool(int max_threads=std::numeric_limits<int>::max(),
int min_threads=0, int timeout_secs=5, int timeout_nsecs=0);
~thread_pool();
void add(const boost::function0<void> &job);
void join();
void cancel();
void detach();
private:
class impl;
impl* m_pimpl;
};
} // namespace boost
#endif

View File

@@ -1,16 +1,121 @@
// Copyright 2006 Roland Schwarz.
// 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)
// Copyright (C) 2001-2003
// William E. Kempf
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_TSS_RS06092303_HPP
#define BOOST_TSS_RS06092303_HPP
#ifndef BOOST_TSS_WEK070601_HPP
#define BOOST_TSS_WEK070601_HPP
#include <boost/thread/detail/platform.hpp>
#include BOOST_THREAD_PLATFORM(tss.hpp)
#include <boost/thread/detail/config.hpp>
#endif // BOOST_TSS_RS06092301_HPP
#include <boost/utility.hpp>
#include <boost/function.hpp>
#include <boost/thread/exceptions.hpp>
#if defined(BOOST_HAS_PTHREADS)
# include <pthread.h>
#elif defined(BOOST_HAS_MPTASKS)
# include <Multiprocessing.h>
#endif
namespace boost {
namespace detail {
class BOOST_THREAD_DECL tss : private noncopyable
{
public:
tss(boost::function1<void, void*>* pcleanup) {
if (pcleanup == 0) throw boost::thread_resource_error();
try
{
init(pcleanup);
}
catch (...)
{
delete pcleanup;
throw boost::thread_resource_error();
}
}
void* get() const;
void set(void* value);
void cleanup(void* p);
private:
unsigned int m_slot; //This is a "pseudo-slot", not a native slot
void init(boost::function1<void, void*>* pcleanup);
};
#if defined(BOOST_HAS_MPTASKS)
void thread_cleanup();
#endif
template <typename T>
struct tss_adapter
{
template <typename F>
tss_adapter(const F& cleanup) : m_cleanup(cleanup) { }
void operator()(void* p) { m_cleanup(static_cast<T*>(p)); }
boost::function1<void, T*> m_cleanup;
};
} // namespace detail
template <typename T>
class thread_specific_ptr : private noncopyable
{
public:
thread_specific_ptr()
: m_tss(new boost::function1<void, void*>(
boost::detail::tss_adapter<T>(
&thread_specific_ptr<T>::cleanup)))
{
}
thread_specific_ptr(void (*clean)(T*))
: m_tss(new boost::function1<void, void*>(
boost::detail::tss_adapter<T>(clean)))
{
}
~thread_specific_ptr() { reset(); }
T* get() const { return static_cast<T*>(m_tss.get()); }
T* operator->() const { return get(); }
T& operator*() const { return *get(); }
T* release() { T* temp = get(); if (temp) m_tss.set(0); return temp; }
void reset(T* p=0)
{
T* cur = get();
if (cur == p) return;
m_tss.set(p);
if (cur) m_tss.cleanup(cur);
}
private:
static void cleanup(T* p) { delete p; }
detail::tss m_tss;
};
} // namespace boost
#endif //BOOST_TSS_WEK070601_HPP
// Change Log:
// 6 Jun 01
// WEKEMPF Initial version.
// 30 May 02 WEKEMPF
// Added interface to set specific cleanup handlers.
// Removed TLS slot limits from most implementations.
// 22 Mar 04 GlassfordM for WEKEMPF
// Fixed: thread_specific_ptr::reset() doesn't check error returned
// by tss::set(); tss::set() now throws if it fails.
// Fixed: calling thread_specific_ptr::reset() or
// thread_specific_ptr::release() causes double-delete: once on
// reset()/release() and once on ~thread_specific_ptr().

View File

@@ -1,140 +0,0 @@
#ifndef BOOST_BASIC_CHECKED_MUTEX_WIN32_HPP
#define BOOST_BASIC_CHECKED_MUTEX_WIN32_HPP
// basic_checked_mutex_win32.hpp
//
// (C) Copyright 2006 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/detail/interlocked.hpp>
#include <boost/thread/win32/thread_primitives.hpp>
#include <boost/thread/win32/interlocked_read.hpp>
#include <boost/assert.hpp>
namespace boost
{
namespace detail
{
struct basic_checked_mutex
{
long locking_thread;
long active_count;
void* semaphore;
BOOST_STATIC_CONSTANT(long,destroyed_mutex_marker=~0);
void initialize()
{
locking_thread=0;
active_count=0;
semaphore=0;
}
void destroy()
{
long const old_locking_thread=BOOST_INTERLOCKED_EXCHANGE(&locking_thread,destroyed_mutex_marker);
BOOST_ASSERT(!old_locking_thread);
void* const old_semaphore=BOOST_INTERLOCKED_EXCHANGE_POINTER(&semaphore,0);
if(old_semaphore)
{
bool const close_handle_succeeded=BOOST_CLOSE_HANDLE(old_semaphore)!=0;
BOOST_ASSERT(close_handle_succeeded);
}
}
bool try_lock()
{
check_mutex_lock();
bool const success=!BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,1,0);
if(success)
{
set_locking_thread();
}
return success;
}
void lock()
{
check_mutex_lock();
if(BOOST_INTERLOCKED_INCREMENT(&active_count)!=1)
{
bool const wait_succeeded=BOOST_WAIT_FOR_SINGLE_OBJECT(get_semaphore(),BOOST_INFINITE)==0;
BOOST_ASSERT(wait_succeeded);
}
set_locking_thread();
}
long get_active_count()
{
return ::boost::detail::interlocked_read(&active_count);
}
void unlock()
{
long const current_thread=BOOST_GET_CURRENT_THREAD_ID();
long const old_locking_thread=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&locking_thread,0,current_thread);
BOOST_ASSERT(old_locking_thread!=destroyed_mutex_marker);
BOOST_ASSERT(old_locking_thread==current_thread);
if(BOOST_INTERLOCKED_DECREMENT(&active_count)!=0)
{
bool const release_succeeded=BOOST_RELEASE_SEMAPHORE(get_semaphore(),1,0)!=0;
BOOST_ASSERT(release_succeeded);
}
}
bool locked()
{
return get_active_count()!=0;
}
private:
void check_mutex_lock()
{
long const current_thread=BOOST_GET_CURRENT_THREAD_ID();
long const current_locking_thread=::boost::detail::interlocked_read(&locking_thread);
BOOST_ASSERT(current_locking_thread!=current_thread);
BOOST_ASSERT(current_locking_thread!=destroyed_mutex_marker);
}
void set_locking_thread()
{
long const old_owner=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&locking_thread,BOOST_GET_CURRENT_THREAD_ID(),0);
BOOST_ASSERT(old_owner==0);
}
void* get_semaphore()
{
void* current_semaphore=::boost::detail::interlocked_read(&semaphore);
if(!current_semaphore)
{
void* const new_semaphore=BOOST_CREATE_SEMAPHORE(0,0,1,0);
BOOST_ASSERT(new_semaphore);
void* const old_semaphore=BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&semaphore,new_semaphore,0);
if(old_semaphore!=0)
{
bool const close_succeeded=BOOST_CLOSE_HANDLE(new_semaphore)!=0;
BOOST_ASSERT(close_succeeded);
return old_semaphore;
}
else
{
return new_semaphore;
}
}
return current_semaphore;
}
};
}
}
#define BOOST_BASIC_CHECKED_MUTEX_INITIALIZER {0}
#endif

View File

@@ -1,123 +0,0 @@
#ifndef BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP
#define BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP
// basic_recursive_mutex.hpp
//
// (C) Copyright 2006 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/detail/interlocked.hpp>
#include <boost/thread/win32/thread_primitives.hpp>
#include <boost/thread/win32/interlocked_read.hpp>
#include <boost/thread/win32/basic_timed_mutex.hpp>
#include <boost/thread/xtime.hpp>
namespace boost
{
namespace detail
{
template<typename underlying_mutex_type>
struct basic_recursive_mutex_impl
{
long recursion_count;
long locking_thread_id;
underlying_mutex_type mutex;
void initialize()
{
recursion_count=0;
locking_thread_id=0;
mutex.initialize();
}
void destroy()
{
mutex.destroy();
}
bool try_lock()
{
long const current_thread_id=win32::GetCurrentThreadId();
return try_recursive_lock(current_thread_id) || try_basic_lock(current_thread_id);
}
void lock()
{
long const current_thread_id=win32::GetCurrentThreadId();
if(!try_recursive_lock(current_thread_id))
{
mutex.lock();
BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
recursion_count=1;
}
}
bool timed_lock(::boost::xtime const& target)
{
long const current_thread_id=win32::GetCurrentThreadId();
return try_recursive_lock(current_thread_id) || try_timed_lock(current_thread_id,target);
}
long get_active_count()
{
return mutex.get_active_count();
}
void unlock()
{
if(!--recursion_count)
{
BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,0);
mutex.unlock();
}
}
bool locked()
{
return mutex.locked();
}
private:
bool try_recursive_lock(long current_thread_id)
{
if(::boost::detail::interlocked_read(&locking_thread_id)==current_thread_id)
{
++recursion_count;
return true;
}
return false;
}
bool try_basic_lock(long current_thread_id)
{
if(mutex.try_lock())
{
BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
recursion_count=1;
return true;
}
return false;
}
bool try_timed_lock(long current_thread_id,::boost::xtime const& target)
{
if(mutex.timed_lock(target))
{
BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
recursion_count=1;
return true;
}
return false;
}
};
typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_mutex;
typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_timed_mutex;
}
}
#define BOOST_BASIC_RECURSIVE_MUTEX_INITIALIZER {0}
#endif

View File

@@ -1,158 +0,0 @@
#ifndef BOOST_BASIC_TIMED_MUTEX_WIN32_HPP
#define BOOST_BASIC_TIMED_MUTEX_WIN32_HPP
// basic_timed_mutex_win32.hpp
//
// (C) Copyright 2006 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/assert.hpp>
#include <boost/detail/interlocked.hpp>
#include <boost/thread/win32/thread_primitives.hpp>
#include <boost/thread/win32/interlocked_read.hpp>
#include <boost/thread/win32/xtime.hpp>
#include <boost/thread/win32/xtime_utils.hpp>
namespace boost
{
namespace detail
{
struct basic_timed_mutex
{
BOOST_STATIC_CONSTANT(long,lock_flag_value=0x10000);
long active_count;
void* event;
void initialize()
{
active_count=0;
event=0;
}
void destroy()
{
void* const old_event=BOOST_INTERLOCKED_EXCHANGE_POINTER(&event,0);
if(old_event)
{
win32::CloseHandle(old_event);
}
}
bool try_lock()
{
long old_count=0;
while(!(old_count&lock_flag_value))
{
long const current_count=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,(old_count+1)|lock_flag_value,old_count);
if(current_count==old_count)
{
return true;
}
old_count=current_count;
}
return false;
}
void lock()
{
bool const success=timed_lock(::boost::detail::get_xtime_sentinel());
BOOST_ASSERT(success);
}
bool timed_lock(::boost::xtime const& target_time)
{
long old_count=0;
while(true)
{
long const current_count=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,(old_count+1)|lock_flag_value,old_count);
if(current_count==old_count)
{
break;
}
old_count=current_count;
}
if(old_count&lock_flag_value)
{
bool lock_acquired=false;
void* const sem=get_event();
++old_count; // we're waiting, too
do
{
old_count-=(lock_flag_value+1); // there will be one less active thread on this mutex when it gets unlocked
if(win32::WaitForSingleObject(sem,::boost::detail::get_milliseconds_until_time(target_time))!=0)
{
BOOST_INTERLOCKED_DECREMENT(&active_count);
return false;
}
do
{
long const current_count=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,old_count|lock_flag_value,old_count);
if(current_count==old_count)
{
break;
}
old_count=current_count;
}
while(!(old_count&lock_flag_value));
lock_acquired=!(old_count&lock_flag_value);
}
while(!lock_acquired);
}
return true;
}
long get_active_count()
{
return ::boost::detail::interlocked_read(&active_count);
}
void unlock()
{
long const offset=lock_flag_value+1;
long old_count=BOOST_INTERLOCKED_EXCHANGE_ADD(&active_count,-offset);
if(old_count>offset)
{
win32::SetEvent(get_event());
}
}
bool locked()
{
return get_active_count()>=lock_flag_value;
}
private:
void* get_event()
{
void* current_event=::boost::detail::interlocked_read(&event);
if(!current_event)
{
void* const new_event=win32::create_anonymous_event(win32::auto_reset_event,win32::event_initially_reset);
void* const old_event=BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&event,new_event,0);
if(old_event!=0)
{
win32::CloseHandle(new_event);
return old_event;
}
else
{
return new_event;
}
}
return current_event;
}
};
}
}
#define BOOST_BASIC_TIMED_MUTEX_INITIALIZER {0}
#endif

View File

@@ -1,229 +0,0 @@
// 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 Anthony Williams
#ifndef CONDITION_HPP
#define CONDITION_HPP
#include "boost/config.hpp"
#include "boost/thread/mutex.hpp"
#include "boost/thread/win32/thread_primitives.hpp"
#include "boost/thread/win32/xtime.hpp"
#include "boost/thread/win32/xtime_utils.hpp"
#include <limits.h>
#include "boost/assert.hpp"
#include <algorithm>
namespace boost
{
template<typename lock_type>
class basic_condition
{
boost::mutex internal_mutex;
struct list_entry
{
detail::win32::handle semaphore;
long count;
bool notified;
};
BOOST_STATIC_CONSTANT(unsigned,generation_count=10);
list_entry generations[generation_count];
detail::win32::handle wake_sem;
static bool no_waiters(list_entry const& entry)
{
return entry.count==0;
}
void shift_generations_down()
{
if(std::remove_if(generations,generations+generation_count,no_waiters)==generations+generation_count)
{
broadcast_entry(generations[generation_count-1],false);
}
std::copy_backward(generations,generations+generation_count,generations+generation_count);
generations[0].semaphore=0;
generations[0].count=0;
generations[0].notified=false;
}
void broadcast_entry(list_entry& entry,bool wake)
{
if(wake)
{
detail::win32::ReleaseSemaphore(wake_sem,entry.count,NULL);
}
detail::win32::ReleaseSemaphore(entry.semaphore,entry.count,NULL);
entry.count=0;
dispose_entry(entry);
}
void dispose_entry(list_entry& entry)
{
BOOST_ASSERT(entry.count==0);
if(entry.semaphore)
{
unsigned long const close_result=detail::win32::CloseHandle(entry.semaphore);
BOOST_ASSERT(close_result);
}
entry.semaphore=0;
entry.notified=false;
}
detail::win32::handle duplicate_handle(detail::win32::handle source)
{
detail::win32::handle const current_process=detail::win32::GetCurrentProcess();
long const same_access_flag=2;
detail::win32::handle new_handle=0;
bool const success=detail::win32::DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0;
BOOST_ASSERT(success);
return new_handle;
}
bool do_wait(lock_type& lock,::boost::xtime const& target_time)
{
detail::win32::handle local_wake_sem;
detail::win32::handle sem;
bool first_loop=true;
bool woken=false;
while(!woken)
{
{
boost::mutex::scoped_lock internal_lock(internal_mutex);
if(first_loop)
{
lock.unlock();
if(!wake_sem)
{
wake_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
BOOST_ASSERT(wake_sem);
}
local_wake_sem=duplicate_handle(wake_sem);
if(generations[0].notified)
{
shift_generations_down();
}
if(!generations[0].semaphore)
{
generations[0].semaphore=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
BOOST_ASSERT(generations[0].semaphore);
}
first_loop=false;
}
++generations[0].count;
sem=duplicate_handle(generations[0].semaphore);
}
unsigned long const notified=detail::win32::WaitForSingleObject(sem,::boost::detail::get_milliseconds_until_time(target_time));
BOOST_ASSERT(notified==detail::win32::timeout || notified==0);
unsigned long const sem_close_result=detail::win32::CloseHandle(sem);
BOOST_ASSERT(sem_close_result);
if(notified==detail::win32::timeout)
{
break;
}
unsigned long const woken_result=detail::win32::WaitForSingleObject(local_wake_sem,0);
BOOST_ASSERT(woken_result==detail::win32::timeout || woken_result==0);
woken=(woken_result==0);
}
unsigned long const wake_sem_close_result=detail::win32::CloseHandle(local_wake_sem);
BOOST_ASSERT(wake_sem_close_result);
lock.lock();
return woken;
}
public:
basic_condition():
wake_sem(0)
{
for(unsigned i=0;i<generation_count;++i)
{
generations[i]=list_entry();
}
}
~basic_condition()
{
for(unsigned i=0;i<generation_count;++i)
{
dispose_entry(generations[i]);
}
detail::win32::CloseHandle(wake_sem);
}
void wait(lock_type& m)
{
do_wait(m,::boost::detail::get_xtime_sentinel());
}
template<typename predicate_type>
void wait(lock_type& m,predicate_type pred)
{
while(!pred()) wait(m);
}
bool timed_wait(lock_type& m,::boost::xtime const& target_time)
{
return do_wait(m,target_time);
}
template<typename predicate_type>
bool timed_wait(lock_type& m,::boost::xtime const& target_time,predicate_type pred)
{
while (!pred()) { if (!timed_wait(m, target_time)) return false; } return true;
}
void notify_one()
{
boost::mutex::scoped_lock internal_lock(internal_mutex);
if(wake_sem)
{
detail::win32::ReleaseSemaphore(wake_sem,1,NULL);
for(unsigned generation=generation_count;generation!=0;--generation)
{
list_entry& entry=generations[generation-1];
if(entry.count)
{
entry.notified=true;
detail::win32::ReleaseSemaphore(entry.semaphore,1,NULL);
if(!--entry.count)
{
dispose_entry(entry);
}
}
}
}
}
void notify_all()
{
boost::mutex::scoped_lock internal_lock(internal_mutex);
if(wake_sem)
{
for(unsigned generation=generation_count;generation!=0;--generation)
{
list_entry& entry=generations[generation-1];
if(entry.count)
{
broadcast_entry(entry,true);
}
}
}
}
};
typedef basic_condition<boost::mutex::scoped_lock> condition;
}
#endif

View File

@@ -1,77 +0,0 @@
// Copyright 2006 Roland Schwarz.
// 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)
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
#ifndef BOOST_THREAD_RS06041002_HPP
#define BOOST_THREAD_RS06041002_HPP
#include <boost/config.hpp>
// insist on threading support being available:
#include <boost/config/requires_threads.hpp>
#if defined(BOOST_THREAD_BUILD_DLL) //Build dll
#elif defined(BOOST_THREAD_BUILD_LIB) //Build lib
#elif defined(BOOST_THREAD_USE_DLL) //Use dll
#elif defined(BOOST_THREAD_USE_LIB) //Use lib
#else //Use default
# if defined(BOOST_HAS_WINTHREADS)
# if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)
//For compilers supporting auto-tss cleanup
//with Boost.Threads lib, use Boost.Threads lib
# define BOOST_THREAD_USE_LIB
# else
//For compilers not yet supporting auto-tss cleanup
//with Boost.Threads lib, use Boost.Threads dll
# define BOOST_THREAD_USE_DLL
# endif
# else
# define BOOST_THREAD_USE_LIB
# endif
#endif
#if defined(BOOST_HAS_DECLSPEC)
# if defined(BOOST_THREAD_BUILD_DLL) //Build dll
# define BOOST_THREAD_DECL __declspec(dllexport)
# elif defined(BOOST_THREAD_USE_DLL) //Use dll
# define BOOST_THREAD_DECL __declspec(dllimport)
# else
# define BOOST_THREAD_DECL
# endif
#else
# define BOOST_THREAD_DECL
#endif // BOOST_HAS_DECLSPEC
//
// Automatically link to the correct build variant where possible.
//
#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_THREAD_NO_LIB) && !defined(BOOST_THREAD_BUILD_DLL) && !defined(BOOST_THREAD_BUILD_LIB)
//
// Tell the autolink to link dynamically, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#if defined(BOOST_THREAD_USE_DLL)
# define BOOST_DYN_LINK
#endif
//
// Set the name of our library, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#if defined(BOOST_THREAD_LIB_NAME)
# define BOOST_LIB_NAME BOOST_THREAD_LIB_NAME
#else
# define BOOST_LIB_NAME boost_thread
#endif
//
// If we're importing code from a dll, then tell auto_link.hpp about it:
//
// And include the header that does the work:
//
#include <boost/config/auto_link.hpp>
#endif // auto-linking disabled
#endif // BOOST_THREAD_RS06041002_HPP

View File

@@ -1,91 +0,0 @@
// (C) Copyright 2005-6 Anthony Williams
// Copyright 2006 Roland Schwarz.
// 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)
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
#ifndef BOOST_THREAD_RS06041003_HPP
#define BOOST_THREAD_RS06041003_HPP
#include <boost/thread/win32/config.hpp>
#include <string>
#include <stdexcept>
namespace boost {
class BOOST_THREAD_DECL thread_exception : public std::exception
{
protected:
thread_exception();
thread_exception(int sys_err_code);
public:
~thread_exception() throw();
int native_error() const;
const char* message() const;
private:
int m_sys_err;
};
class BOOST_THREAD_DECL lock_error : public thread_exception
{
public:
lock_error();
lock_error(int sys_err_code);
~lock_error() throw();
virtual const char* what() const throw();
};
class BOOST_THREAD_DECL thread_resource_error : public thread_exception
{
public:
thread_resource_error();
thread_resource_error(int sys_err_code);
~thread_resource_error() throw();
virtual const char* what() const throw();
};
class BOOST_THREAD_DECL unsupported_thread_option : public thread_exception
{
public:
unsupported_thread_option();
unsupported_thread_option(int sys_err_code);
~unsupported_thread_option() throw();
virtual const char* what() const throw();
};
class BOOST_THREAD_DECL invalid_thread_argument : public thread_exception
{
public:
invalid_thread_argument();
invalid_thread_argument(int sys_err_code);
~invalid_thread_argument() throw();
virtual const char* what() const throw();
};
class BOOST_THREAD_DECL thread_permission_error : public thread_exception
{
public:
thread_permission_error();
thread_permission_error(int sys_err_code);
~thread_permission_error() throw();
virtual const char* what() const throw();
};
} // namespace boost
#endif // BOOST_THREAD_RS06041003_HPP

View File

@@ -1,36 +0,0 @@
#ifndef BOOST_THREAD_DETAIL_INTERLOCKED_READ_WIN32_HPP
#define BOOST_THREAD_DETAIL_INTERLOCKED_READ_WIN32_HPP
// interlocked_read_win32.hpp
//
// (C) Copyright 2005-7 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/detail/interlocked.hpp>
extern "C" void _ReadWriteBarrier(void);
#pragma intrinsic(_ReadWriteBarrier)
namespace boost
{
namespace detail
{
inline long interlocked_read_acquire(long volatile* x)
{
long const res=*x;
_ReadWriteBarrier();
return res;
}
inline void* interlocked_read_acquire(void* volatile* x)
{
void* const res=*x;
_ReadWriteBarrier();
return res;
}
}
}
#endif

View File

@@ -1,201 +0,0 @@
// Copyright 2006 Roland Schwarz.
// 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)
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
#ifndef BOOST_THREAD_RS06041005_HPP
#define BOOST_THREAD_RS06041005_HPP
#include <boost/thread/win32/config.hpp>
#include <boost/utility.hpp>
#include <boost/thread/win32/exceptions.hpp>
namespace boost {
struct xtime;
namespace detail { namespace thread {
template <typename Mutex>
class lock_ops : private noncopyable
{
private:
lock_ops() { }
public:
typedef typename Mutex::cv_state lock_state;
static void lock(Mutex& m)
{
m.do_lock();
}
static bool trylock(Mutex& m)
{
return m.do_trylock();
}
static bool timedlock(Mutex& m, const xtime& xt)
{
return m.do_timedlock(xt);
}
static void unlock(Mutex& m)
{
m.do_unlock();
}
static void lock(Mutex& m, lock_state& state)
{
m.do_lock(state);
}
static void unlock(Mutex& m, lock_state& state)
{
m.do_unlock(state);
}
};
template <typename Mutex>
class scoped_lock : private noncopyable
{
public:
typedef Mutex mutex_type;
explicit scoped_lock(Mutex& mx, bool initially_locked=true)
: m_mutex(mx), m_locked(false)
{
if (initially_locked) lock();
}
~scoped_lock()
{
if (m_locked) unlock();
}
void lock()
{
if (m_locked) throw lock_error();
lock_ops<Mutex>::lock(m_mutex);
m_locked = true;
}
void unlock()
{
if (!m_locked) throw lock_error();
lock_ops<Mutex>::unlock(m_mutex);
m_locked = false;
}
bool locked() const { return m_locked; }
operator const void*() const { return m_locked ? this : 0; }
private:
Mutex& m_mutex;
bool m_locked;
};
template <typename TryMutex>
class scoped_try_lock : private noncopyable
{
public:
typedef TryMutex mutex_type;
explicit scoped_try_lock(TryMutex& mx)
: m_mutex(mx), m_locked(false)
{
try_lock();
}
scoped_try_lock(TryMutex& mx, bool initially_locked)
: m_mutex(mx), m_locked(false)
{
if (initially_locked) lock();
}
~scoped_try_lock()
{
if (m_locked) unlock();
}
void lock()
{
if (m_locked) throw lock_error();
lock_ops<TryMutex>::lock(m_mutex);
m_locked = true;
}
bool try_lock()
{
if (m_locked) throw lock_error();
return (m_locked = lock_ops<TryMutex>::trylock(m_mutex));
}
void unlock()
{
if (!m_locked) throw lock_error();
lock_ops<TryMutex>::unlock(m_mutex);
m_locked = false;
}
bool locked() const { return m_locked; }
operator const void*() const { return m_locked ? this : 0; }
private:
TryMutex& m_mutex;
bool m_locked;
};
template <typename TimedMutex>
class scoped_timed_lock : private noncopyable
{
public:
typedef TimedMutex mutex_type;
scoped_timed_lock(TimedMutex& mx, const xtime& xt)
: m_mutex(mx), m_locked(false)
{
timed_lock(xt);
}
scoped_timed_lock(TimedMutex& mx, bool initially_locked)
: m_mutex(mx), m_locked(false)
{
if (initially_locked) lock();
}
~scoped_timed_lock()
{
if (m_locked) unlock();
}
void lock()
{
if (m_locked) throw lock_error();
lock_ops<TimedMutex>::lock(m_mutex);
m_locked = true;
}
bool try_lock()
{
if (m_locked) throw lock_error();
return (m_locked = lock_ops<TimedMutex>::trylock(m_mutex));
}
bool timed_lock(const xtime& xt)
{
if (m_locked) throw lock_error();
return (m_locked = lock_ops<TimedMutex>::timedlock(m_mutex, xt));
}
void unlock()
{
if (!m_locked) throw lock_error();
lock_ops<TimedMutex>::unlock(m_mutex);
m_locked = false;
}
bool locked() const { return m_locked; }
operator const void*() const { return m_locked ? this : 0; }
private:
TimedMutex& m_mutex;
bool m_locked;
};
} // namespace thread
} // namespace detail
} // namespace boost
#endif // BOOST_THREAD_RS06041005_HPP

View File

@@ -1,272 +0,0 @@
// (C) Copyright 2005-6 Anthony Williams
// Copyright 2006 Roland Schwarz.
// 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)
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
#ifndef BOOST_THREAD_RS06041004_HPP
#define BOOST_THREAD_RS06041004_HPP
#include <boost/thread/win32/config.hpp>
#include <boost/thread/win32/basic_timed_mutex.hpp>
#include <boost/utility.hpp>
#include <boost/thread/win32/lock.hpp>
#include <boost/thread/win32/xtime.hpp>
#include <boost/thread/win32/exceptions.hpp>
namespace boost
{
namespace detail
{
typedef ::boost::detail::basic_timed_mutex underlying_mutex;
}
class mutex:
noncopyable,
public ::boost::detail::underlying_mutex
{
public:
mutex()
{
initialize();
}
~mutex()
{
destroy();
}
class scoped_lock
{
protected:
mutex& m;
bool is_locked;
public:
scoped_lock(mutex& m_):
m(m_),is_locked(false)
{
lock();
}
scoped_lock(mutex& m_,bool do_lock):
m(m_),is_locked(false)
{
if(do_lock)
{
lock();
}
}
~scoped_lock()
{
if(locked())
{
m.unlock();
}
}
void lock()
{
if(locked())
{
throw boost::lock_error();
}
m.lock();
is_locked=true;
}
void unlock()
{
if(!locked())
{
throw boost::lock_error();
}
m.unlock();
is_locked=false;
}
operator void* () const
{
return is_locked?const_cast<void*>(static_cast<void const*>(this)):0;
}
bool locked() const
{
return is_locked;
}
};
};
class try_mutex:
noncopyable,
protected ::boost::detail::underlying_mutex
{
public:
try_mutex()
{
initialize();
}
~try_mutex()
{
destroy();
}
class scoped_try_lock
{
protected:
try_mutex& m;
bool is_locked;
public:
scoped_try_lock(try_mutex& m_):
m(m_),is_locked(false)
{
lock();
}
scoped_try_lock(try_mutex& m_,bool do_lock):
m(m_),is_locked(false)
{
if(do_lock)
{
lock();
}
}
~scoped_try_lock()
{
if(locked())
{
m.unlock();
}
}
void lock()
{
if(locked())
{
throw boost::lock_error();
}
m.lock();
is_locked=true;
}
bool try_lock()
{
if(locked())
{
throw boost::lock_error();
}
is_locked=m.try_lock();
return is_locked;
}
void unlock()
{
if(!locked())
{
throw boost::lock_error();
}
m.unlock();
is_locked=false;
}
operator void* () const
{
return is_locked?const_cast<void*>(static_cast<void const*>(this)):0;
}
bool locked() const
{
return is_locked;
}
};
typedef scoped_try_lock scoped_lock;
};
class timed_mutex:
noncopyable,
protected ::boost::detail::basic_timed_mutex
{
public:
timed_mutex()
{
initialize();
}
~timed_mutex()
{
destroy();
}
class scoped_timed_lock
{
protected:
timed_mutex& m;
bool is_locked;
public:
scoped_timed_lock(timed_mutex& m_):
m(m_),is_locked(false)
{
lock();
}
scoped_timed_lock(timed_mutex& m_,::boost::xtime const& target):
m(m_),is_locked(false)
{
timed_lock(target);
}
scoped_timed_lock(timed_mutex& m_,bool do_lock):
m(m_),is_locked(false)
{
if(do_lock)
{
lock();
}
}
~scoped_timed_lock()
{
if(locked())
{
m.unlock();
}
}
void lock()
{
if(locked())
{
throw boost::lock_error();
}
m.lock();
is_locked=true;
}
bool try_lock()
{
is_locked=m.try_lock();
return is_locked;
}
bool timed_lock(::boost::xtime const& target)
{
is_locked=m.timed_lock(target);
return is_locked;
}
void unlock()
{
if(!locked())
{
throw boost::lock_error();
}
m.unlock();
is_locked=false;
}
operator void* () const
{
return is_locked?const_cast<void*>(static_cast<void const*>(this)):0;
}
bool locked() const
{
return is_locked;
}
};
typedef scoped_timed_lock scoped_try_lock;
typedef scoped_timed_lock scoped_lock;
};
}
#endif // BOOST_THREAD_RS06041004_HPP

View File

@@ -1,114 +0,0 @@
#ifndef BOOST_THREAD_WIN32_ONCE_HPP
#define BOOST_THREAD_WIN32_ONCE_HPP
// once.hpp
//
// (C) Copyright 2005-7 Anthony Williams
// (C) Copyright 2005 John Maddock
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <cstring>
#include <cstddef>
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/interlocked.hpp>
#include <boost/thread/win32/thread_primitives.hpp>
#include <boost/thread/win32/interlocked_read.hpp>
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std
{
using ::strlen;
using ::memcpy;
using ::ptrdiff_t;
}
#endif
namespace boost
{
typedef long once_flag;
#define BOOST_ONCE_INIT 0
namespace detail
{
struct win32_mutex_scoped_lock
{
void* const mutex_handle;
explicit win32_mutex_scoped_lock(void* mutex_handle_):
mutex_handle(mutex_handle_)
{
unsigned long const res=win32::WaitForSingleObject(mutex_handle,win32::infinite);
BOOST_ASSERT(!res);
}
~win32_mutex_scoped_lock()
{
bool const success=win32::ReleaseMutex(mutex_handle)!=0;
BOOST_ASSERT(success);
}
};
template <class I>
void int_to_string(I p, char* buf)
{
unsigned i=0;
for(; i < sizeof(I)*2; ++i)
{
buf[i] = 'A' + static_cast<char>((p >> (i*4)) & 0x0f);
}
buf[i] = 0;
}
unsigned const once_mutex_name_fixed_length=48;
unsigned const once_mutex_name_fixed_buffer_size=once_mutex_name_fixed_length+1;
unsigned const once_mutex_name_length=once_mutex_name_fixed_buffer_size+sizeof(void*)*2+sizeof(unsigned long)*2;
// create a named mutex. It doesn't really matter what this name is
// as long as it is unique both to this process, and to the address of "flag":
inline void* create_once_mutex(char (&mutex_name)[once_mutex_name_length],void* flag_address)
{
static const char fixed_mutex_name[]="{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag";
BOOST_STATIC_ASSERT(sizeof(fixed_mutex_name) == once_mutex_name_fixed_buffer_size);
std::memcpy(mutex_name,fixed_mutex_name,sizeof(fixed_mutex_name));
BOOST_ASSERT(sizeof(mutex_name) == std::strlen(mutex_name) + sizeof(void*)*2 + sizeof(unsigned long)*2 + 1);
BOOST_STATIC_ASSERT(sizeof(void*) == sizeof(std::ptrdiff_t));
detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address), mutex_name + once_mutex_name_fixed_length);
detail::int_to_string(win32::GetCurrentProcessId(), mutex_name + once_mutex_name_fixed_length + sizeof(void*)*2);
BOOST_ASSERT(sizeof(mutex_name) == std::strlen(mutex_name) + 1);
return win32::CreateMutexA(NULL, 0, mutex_name);
}
}
template<typename Function>
void call_once(once_flag& flag,Function f)
{
// Try for a quick win: if the proceedure has already been called
// just skip through:
long const function_complete_flag_value=0xc15730e2;
if(::boost::detail::interlocked_read_acquire(&flag)!=function_complete_flag_value)
{
char mutex_name[::boost::detail::once_mutex_name_length];
void* const mutex_handle(::boost::detail::create_once_mutex(mutex_name,&flag));
BOOST_ASSERT(mutex_handle);
detail::win32::handle_manager const closer(mutex_handle);
detail::win32_mutex_scoped_lock const lock(mutex_handle);
if(flag!=function_complete_flag_value)
{
f();
BOOST_INTERLOCKED_EXCHANGE(&flag,function_complete_flag_value);
}
}
}
}
#endif

View File

@@ -1,528 +0,0 @@
#ifndef BOOST_THREAD_WIN32_READ_WRITE_MUTEX_HPP
#define BOOST_THREAD_WIN32_READ_WRITE_MUTEX_HPP
// (C) Copyright 2006 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/assert.hpp>
#include <boost/detail/interlocked.hpp>
#include <boost/thread/win32/thread_primitives.hpp>
#include <boost/thread/win32/interlocked_read.hpp>
#include <boost/static_assert.hpp>
#include <limits.h>
namespace boost
{
class read_write_mutex
{
private:
struct state_data
{
unsigned shared_count:10;
unsigned shared_waiting:10;
unsigned exclusive:1;
unsigned upgradeable:1;
unsigned exclusive_waiting:9;
unsigned exclusive_waiting_blocked:1;
friend bool operator==(state_data const& lhs,state_data const& rhs)
{
return *reinterpret_cast<unsigned const*>(&lhs)==*reinterpret_cast<unsigned const*>(&rhs);
}
};
template<typename T>
T interlocked_compare_exchange(T* target,T new_value,T comparand)
{
BOOST_STATIC_ASSERT(sizeof(T)==sizeof(long));
long const res=BOOST_INTERLOCKED_COMPARE_EXCHANGE(reinterpret_cast<long*>(target),
*reinterpret_cast<long*>(&new_value),
*reinterpret_cast<long*>(&comparand));
return *reinterpret_cast<T const*>(&res);
}
state_data state;
void* semaphores[2];
void* &unlock_sem;
void* &exclusive_sem;
void* upgradeable_sem;
void release_waiters(state_data old_state)
{
if(old_state.exclusive_waiting)
{
bool const success=detail::win32::ReleaseSemaphore(exclusive_sem,1,NULL)!=0;
BOOST_ASSERT(success);
}
if(old_state.shared_waiting || old_state.exclusive_waiting)
{
bool const success=detail::win32::ReleaseSemaphore(unlock_sem,old_state.shared_waiting + (old_state.exclusive_waiting?1:0),NULL)!=0;
BOOST_ASSERT(success);
}
}
public:
read_write_mutex():
unlock_sem(semaphores[0]),
exclusive_sem(semaphores[1])
{
unlock_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
exclusive_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
upgradeable_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
state_data state_={0};
state=state_;
}
~read_write_mutex()
{
detail::win32::CloseHandle(upgradeable_sem);
detail::win32::CloseHandle(unlock_sem);
detail::win32::CloseHandle(exclusive_sem);
}
bool try_lock_shareable()
{
state_data old_state=state;
do
{
state_data new_state=old_state;
if(!new_state.exclusive && !new_state.exclusive_waiting_blocked)
{
++new_state.shared_count;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
while(true);
return !(old_state.exclusive| old_state.exclusive_waiting_blocked);
}
void lock_shareable()
{
while(true)
{
state_data old_state=state;
do
{
state_data new_state=old_state;
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
{
++new_state.shared_waiting;
}
else
{
++new_state.shared_count;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
while(true);
if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
{
return;
}
unsigned long const res=detail::win32::WaitForSingleObject(unlock_sem,detail::win32::infinite);
BOOST_ASSERT(res==0);
}
}
void unlock_shareable()
{
state_data old_state=state;
do
{
state_data new_state=old_state;
bool const last_reader=!--new_state.shared_count;
if(last_reader)
{
if(new_state.upgradeable)
{
new_state.upgradeable=false;
new_state.exclusive=true;
}
else
{
if(new_state.exclusive_waiting)
{
--new_state.exclusive_waiting;
new_state.exclusive_waiting_blocked=false;
}
new_state.shared_waiting=0;
}
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
if(last_reader)
{
if(old_state.upgradeable)
{
bool const success=detail::win32::ReleaseSemaphore(upgradeable_sem,1,NULL)!=0;
BOOST_ASSERT(success);
}
else
{
release_waiters(old_state);
}
}
break;
}
old_state=current_state;
}
while(true);
}
void lock()
{
while(true)
{
state_data old_state=state;
do
{
state_data new_state=old_state;
if(new_state.shared_count || new_state.exclusive)
{
++new_state.exclusive_waiting;
new_state.exclusive_waiting_blocked=true;
}
else
{
new_state.exclusive=true;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
while(true);
if(!old_state.shared_count && !old_state.exclusive)
{
break;
}
bool const success2=detail::win32::WaitForMultipleObjects(2,semaphores,true,detail::win32::infinite)<2;
BOOST_ASSERT(success2);
}
}
void unlock()
{
state_data old_state=state;
do
{
state_data new_state=old_state;
new_state.exclusive=false;
if(new_state.exclusive_waiting)
{
--new_state.exclusive_waiting;
new_state.exclusive_waiting_blocked=false;
}
new_state.shared_waiting=0;
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
while(true);
release_waiters(old_state);
}
void lock_upgradeable()
{
while(true)
{
state_data old_state=state;
do
{
state_data new_state=old_state;
if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgradeable)
{
++new_state.shared_waiting;
}
else
{
++new_state.shared_count;
new_state.upgradeable=true;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
while(true);
if(!(old_state.exclusive|| old_state.exclusive_waiting_blocked|| old_state.upgradeable))
{
return;
}
unsigned long const res=detail::win32::WaitForSingleObject(unlock_sem,detail::win32::infinite);
BOOST_ASSERT(res==0);
}
}
void unlock_upgradeable()
{
state_data old_state=state;
do
{
state_data new_state=old_state;
new_state.upgradeable=false;
bool const last_reader=!--new_state.shared_count;
if(last_reader)
{
if(new_state.exclusive_waiting)
{
--new_state.exclusive_waiting;
new_state.exclusive_waiting_blocked=false;
}
new_state.shared_waiting=0;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
if(last_reader)
{
release_waiters(old_state);
}
break;
}
old_state=current_state;
}
while(true);
}
void unlock_upgradeable_and_lock()
{
state_data old_state=state;
do
{
state_data new_state=old_state;
bool const last_reader=!--new_state.shared_count;
if(last_reader)
{
new_state.upgradeable=false;
new_state.exclusive=true;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
if(!last_reader)
{
unsigned long const res=detail::win32::WaitForSingleObject(upgradeable_sem,detail::win32::infinite);
BOOST_ASSERT(res==0);
}
break;
}
old_state=current_state;
}
while(true);
}
void unlock_and_lock_upgradeable()
{
state_data old_state=state;
do
{
state_data new_state=old_state;
new_state.exclusive=false;
new_state.upgradeable=true;
++new_state.shared_count;
if(new_state.exclusive_waiting)
{
--new_state.exclusive_waiting;
new_state.exclusive_waiting_blocked=false;
}
new_state.shared_waiting=0;
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
while(true);
release_waiters(old_state);
}
void unlock_and_lock_shareable()
{
state_data old_state=state;
do
{
state_data new_state=old_state;
new_state.exclusive=false;
++new_state.shared_count;
if(new_state.exclusive_waiting)
{
--new_state.exclusive_waiting;
new_state.exclusive_waiting_blocked=false;
}
new_state.shared_waiting=0;
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
while(true);
release_waiters(old_state);
}
void unlock_upgradeable_and_lock_shareable()
{
state_data old_state=state;
do
{
state_data new_state=old_state;
new_state.upgradeable=false;
if(new_state.exclusive_waiting)
{
--new_state.exclusive_waiting;
new_state.exclusive_waiting_blocked=false;
}
new_state.shared_waiting=0;
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
while(true);
release_waiters(old_state);
}
class scoped_read_lock
{
read_write_mutex& m;
public:
scoped_read_lock(read_write_mutex& m_):
m(m_)
{
m.lock_shareable();
}
~scoped_read_lock()
{
m.unlock_shareable();
}
};
class scoped_write_lock
{
read_write_mutex& m;
bool locked;
public:
scoped_write_lock(read_write_mutex& m_):
m(m_),locked(false)
{
lock();
}
void lock()
{
m.lock();
locked=true;
}
void unlock()
{
m.unlock();
locked=false;
}
~scoped_write_lock()
{
if(locked)
{
unlock();
}
}
};
class scoped_upgradeable_lock
{
read_write_mutex& m;
bool locked;
bool upgraded;
public:
scoped_upgradeable_lock(read_write_mutex& m_):
m(m_),
locked(false),upgraded(false)
{
lock();
}
void lock()
{
m.lock_upgradeable();
locked=true;
}
void upgrade()
{
m.unlock_upgradeable_and_lock();
upgraded=true;
}
void unlock()
{
if(upgraded)
{
m.unlock();
}
else
{
m.unlock_upgradeable();
}
}
~scoped_upgradeable_lock()
{
if(locked)
{
unlock();
}
}
};
};
}
#endif

View File

@@ -1,263 +0,0 @@
#ifndef BOOST_RECURSIVE_MUTEX_WIN32_HPP
#define BOOST_RECURSIVE_MUTEX_WIN32_HPP
// recursive_mutex.hpp
//
// (C) Copyright 2006 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/win32/basic_recursive_mutex.hpp>
#include <boost/utility.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/thread/exceptions.hpp>
namespace boost
{
class recursive_mutex:
noncopyable,
protected ::boost::detail::basic_recursive_mutex
{
public:
recursive_mutex()
{
::boost::detail::basic_recursive_mutex::initialize();
}
~recursive_mutex()
{
::boost::detail::basic_recursive_mutex::destroy();
}
class scoped_lock
{
protected:
recursive_mutex& m;
bool is_locked;
public:
scoped_lock(recursive_mutex& m_):
m(m_),is_locked(false)
{
lock();
}
scoped_lock(recursive_mutex& m_,bool do_lock):
m(m_),is_locked(false)
{
if(do_lock)
{
lock();
}
}
~scoped_lock()
{
if(locked())
{
m.unlock();
}
}
void lock()
{
if(locked())
{
throw boost::lock_error();
}
m.lock();
is_locked=true;
}
void unlock()
{
if(!locked())
{
throw boost::lock_error();
}
m.unlock();
is_locked=false;
}
operator void* () const
{
return is_locked?const_cast<void*>(static_cast<void const*>(this)):0;
}
bool locked() const
{
return is_locked;
}
};
};
class recursive_try_mutex:
noncopyable,
protected ::boost::detail::basic_recursive_mutex
{
public:
recursive_try_mutex()
{
::boost::detail::basic_recursive_mutex::initialize();
}
~recursive_try_mutex()
{
::boost::detail::basic_recursive_mutex::destroy();
}
class scoped_try_lock
{
protected:
recursive_try_mutex& m;
bool is_locked;
public:
scoped_try_lock(recursive_try_mutex& m_):
m(m_),is_locked(false)
{
lock();
}
scoped_try_lock(recursive_try_mutex& m_,bool do_lock):
m(m_),is_locked(false)
{
if(do_lock)
{
lock();
}
}
~scoped_try_lock()
{
if(locked())
{
m.unlock();
}
}
void lock()
{
if(locked())
{
throw boost::lock_error();
}
m.lock();
is_locked=true;
}
bool try_lock()
{
if(locked())
{
throw boost::lock_error();
}
is_locked=m.try_lock();
return is_locked;
}
void unlock()
{
if(!locked())
{
throw boost::lock_error();
}
m.unlock();
is_locked=false;
}
operator void* () const
{
return is_locked?const_cast<void*>(static_cast<void const*>(this)):0;
}
bool locked() const
{
return is_locked;
}
};
typedef scoped_try_lock scoped_lock;
};
class recursive_timed_mutex:
noncopyable,
protected ::boost::detail::basic_recursive_timed_mutex
{
public:
recursive_timed_mutex()
{
::boost::detail::basic_recursive_timed_mutex::initialize();
}
~recursive_timed_mutex()
{
::boost::detail::basic_recursive_timed_mutex::destroy();
}
class scoped_timed_lock
{
protected:
recursive_timed_mutex& m;
bool is_locked;
public:
scoped_timed_lock(recursive_timed_mutex& m_):
m(m_),is_locked(false)
{
lock();
}
scoped_timed_lock(recursive_timed_mutex& m_,::boost::xtime const& target):
m(m_),is_locked(false)
{
timed_lock(target);
}
scoped_timed_lock(recursive_timed_mutex& m_,bool do_lock):
m(m_),is_locked(false)
{
if(do_lock)
{
lock();
}
}
~scoped_timed_lock()
{
if(locked())
{
m.unlock();
}
}
void lock()
{
if(locked())
{
throw boost::lock_error();
}
m.lock();
is_locked=true;
}
bool try_lock()
{
is_locked=m.try_lock();
return is_locked;
}
bool timed_lock(::boost::xtime const& target)
{
is_locked=m.timed_lock(target);
return is_locked;
}
void unlock()
{
if(!locked())
{
throw boost::lock_error();
}
m.unlock();
is_locked=false;
}
operator void* () const
{
return is_locked?const_cast<void*>(static_cast<void const*>(this)):0;
}
bool locked() const
{
return is_locked;
}
};
typedef scoped_timed_lock scoped_try_lock;
typedef scoped_timed_lock scoped_lock;
};
}
#endif

View File

@@ -1,77 +0,0 @@
// Copyright 2006 Roland Schwarz.
// 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)
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
#ifndef BOOST_THREAD_RS06041007_HPP
#define BOOST_THREAD_RS06041007_HPP
#include <boost/thread/win32/config.hpp>
#include <boost/utility.hpp>
#include <boost/function.hpp>
#include <boost/thread/win32/mutex.hpp>
#include <list>
#include <memory>
namespace boost {
struct xtime;
// disable warnings about non dll import
// see: http://www.boost.org/more/separate_compilation.html#dlls
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4251 4231 4660 4275)
#endif
class BOOST_THREAD_DECL thread : private noncopyable
{
public:
thread();
explicit thread(const function0<void>& threadfunc);
~thread();
bool operator==(const thread& other) const;
bool operator!=(const thread& other) const;
void join();
static void sleep(const xtime& xt);
static void yield();
private:
void* m_thread;
unsigned int m_id;
bool m_joinable;
};
class BOOST_THREAD_DECL thread_group : private noncopyable
{
public:
thread_group();
~thread_group();
thread* create_thread(const function0<void>& threadfunc);
void add_thread(thread* thrd);
void remove_thread(thread* thrd);
void join_all();
int size();
private:
std::list<thread*> m_threads;
mutex m_mutex;
};
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
} // namespace boost
#endif // BOOST_THREAD_RS06041007_HPP

View File

@@ -1,198 +0,0 @@
#ifndef BOOST_WIN32_THREAD_PRIMITIVES_HPP
#define BOOST_WIN32_THREAD_PRIMITIVES_HPP
// win32_thread_primitives.hpp
//
// (C) Copyright 2005-6 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/thread/exceptions.hpp>
#if defined( BOOST_USE_WINDOWS_H )
# include <windows.h>
namespace boost
{
namespace detail
{
namespace win32
{
typedef ULONG_PTR ulong_ptr;
typedef HANDLE handle;
unsigned const infinite=INFINITE;
unsigned const timeout=WAIT_TIMEOUT;
using ::CreateMutexA;
using ::CreateEventA;
using ::CreateSemaphoreA;
using ::CloseHandle;
using ::ReleaseMutex;
using ::ReleaseSemaphore;
using ::SetEvent;
using ::ResetEvent;
using ::WaitForMultipleObjects;
using ::WaitForSingleObject;
using ::GetCurrentProcessId;
using ::GetCurrentThreadId;
using ::GetCurrentThread;
using ::GetCurrentProcess;
using ::DuplicateHandle;
using ::SleepEx;
using ::QueueUserAPC;
}
}
}
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
namespace boost
{
namespace detail
{
namespace win32
{
# ifdef _WIN64
typedef unsigned __int64 ulong_ptr;
# else
typedef unsigned long ulong_ptr;
# endif
typedef void* handle;
unsigned const infinite=~0U;
unsigned const timeout=258U;
extern "C"
{
struct _SECURITY_ATTRIBUTES;
__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) int __stdcall CloseHandle(void*);
__declspec(dllimport) int __stdcall ReleaseMutex(void*);
__declspec(dllimport) unsigned long __stdcall GetCurrentProcessId();
__declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();
__declspec(dllimport) unsigned long __stdcall WaitForSingleObject(void*,unsigned long);
__declspec(dllimport) int __stdcall ReleaseSemaphore(void*,long,long*);
__declspec(dllimport) void* __stdcall GetCurrentThread();
__declspec(dllimport) void* __stdcall GetCurrentProcess();
__declspec(dllimport) int __stdcall DuplicateHandle(void*,void*,void*,void**,unsigned long,int,unsigned long);
__declspec(dllimport) unsigned long __stdcall SleepEx(unsigned long,int);
typedef void (__stdcall *queue_user_apc_callback_function)(ulong_ptr);
__declspec(dllimport) unsigned long __stdcall QueueUserAPC(queue_user_apc_callback_function,void*,ulong_ptr);
__declspec(dllimport) int __stdcall SetEvent(void*);
__declspec(dllimport) int __stdcall ResetEvent(void*);
__declspec(dllimport) unsigned long __stdcall WaitForMultipleObjects(unsigned long nCount,void* const * lpHandles,int bWaitAll,unsigned long dwMilliseconds);
}
}
}
}
#else
# error "Win32 functions not available"
#endif
namespace boost
{
namespace detail
{
namespace win32
{
enum event_type
{
auto_reset_event=false,
manual_reset_event=true
};
enum initial_event_state
{
event_initially_reset=false,
event_initially_set=true
};
inline handle create_anonymous_event(event_type type,initial_event_state state)
{
handle const res=CreateEventA(0,type,state,0);
return res?res:throw thread_resource_error();
}
inline handle create_anonymous_semaphore(long initial_count,long max_count)
{
handle const res=CreateSemaphoreA(NULL,initial_count,max_count,NULL);
return res?res:throw thread_resource_error();
}
inline handle duplicate_handle(handle source)
{
handle const current_process=GetCurrentProcess();
long const same_access_flag=2;
handle new_handle=0;
bool const success=DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0;
return success?new_handle:throw thread_resource_error();
}
inline void release_semaphore(handle semaphore,long count)
{
bool const success=ReleaseSemaphore(semaphore,count,0)!=0;
BOOST_ASSERT(success);
}
class handle_manager
{
private:
handle handle_to_manage;
handle_manager(handle_manager&);
handle_manager& operator=(handle_manager&);
void cleanup()
{
if(handle_to_manage)
{
unsigned long result=CloseHandle(handle_to_manage);
BOOST_ASSERT(result);
}
}
public:
explicit handle_manager(handle handle_to_manage_):
handle_to_manage(handle_to_manage_)
{}
handle_manager():
handle_to_manage(0)
{}
handle_manager& operator=(handle new_handle)
{
cleanup();
handle_to_manage=new_handle;
}
operator handle() const
{
return handle_to_manage;
}
handle release()
{
handle const res=handle_to_manage;
handle_to_manage=0;
return res;
}
bool operator!() const
{
return !handle_to_manage;
}
~handle_manager()
{
cleanup();
}
};
}
}
}
#endif

View File

@@ -1,106 +0,0 @@
// Copyright (C) 2001-2003 William E. Kempf
// Copyright (C) 2006 Roland Schwarz
// 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)
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
#ifndef BOOST_TSS_RS06092305_HPP
#define BOOST_TSS_RS06092305_HPP
#include <boost/thread/win32/config.hpp>
#include <boost/utility.hpp>
#include <boost/function.hpp>
#include <boost/thread/win32/exceptions.hpp>
namespace boost {
// disable warnings about non dll import
// see: http://www.boost.org/more/separate_compilation.html#dlls
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4251 4231 4660 4275)
#endif
namespace detail {
class BOOST_THREAD_DECL tss : private noncopyable
{
public:
tss(boost::function1<void, void*>* pcleanup) {
if (pcleanup == 0) throw boost::thread_resource_error();
try
{
init(pcleanup);
}
catch (...)
{
delete pcleanup;
throw boost::thread_resource_error();
}
}
void* get() const;
void set(void* value);
void cleanup(void* p);
private:
unsigned int m_slot; //This is a "pseudo-slot", not a native slot
void init(boost::function1<void, void*>* pcleanup);
};
template <typename T>
struct tss_adapter
{
template <typename F>
tss_adapter(const F& cleanup) : m_cleanup(cleanup) { }
void operator()(void* p) { m_cleanup(static_cast<T*>(p)); }
boost::function1<void, T*> m_cleanup;
};
} // namespace detail
template <typename T>
class thread_specific_ptr : private noncopyable
{
public:
thread_specific_ptr()
: m_tss(new boost::function1<void, void*>(
boost::detail::tss_adapter<T>(
&thread_specific_ptr<T>::cleanup)))
{
}
thread_specific_ptr(void (*clean)(T*))
: m_tss(new boost::function1<void, void*>(
boost::detail::tss_adapter<T>(clean)))
{
}
~thread_specific_ptr() { reset(); }
T* get() const { return static_cast<T*>(m_tss.get()); }
T* operator->() const { return get(); }
T& operator*() const { return *get(); }
T* release() { T* temp = get(); if (temp) m_tss.set(0); return temp; }
void reset(T* p=0)
{
T* cur = get();
if (cur == p) return;
m_tss.set(p);
if (cur) m_tss.cleanup(cur);
}
private:
static void cleanup(T* p) { delete p; }
detail::tss m_tss;
};
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
} // namespace boost
#endif //BOOST_TSS_RS06092305_HPP

View File

@@ -1,74 +0,0 @@
// Copyright (C) 2001-2003 William E. Kempf
// Copyright (C) Michael Glassford 2004.
// Copyright (C) 2006 Roland Schwarz
// 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)
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
#ifndef BOOST_TLS_HOOKS_RS06092306_HPP
#define BOOST_TLS_HOOKS_RS06092306_HPP
#include <boost/thread/win32/config.hpp>
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.
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.
//Should be called only before the first call to
//on_thread_enter().
//Called automatically by Boost.Threads when
//a method for doing so has been discovered.
//May be omitted; may be called multiple times.
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.
//Should be called only after the last call to
//on_exit_thread().
//Called automatically by Boost.Threads when
//a method for doing so has been discovered.
//Must not be omitted; may be called multiple times.
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
//that is starting.
//Called automatically by Boost.Threads when
//a method for doing so has been discovered.
//May be omitted; may be called multiple times.
extern "C" BOOST_THREAD_DECL void 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
//that is ending.
//Called automatically by Boost.Threads when
//a method for doing so has been discovered.
//Must not be omitted; may be called multiple times.
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 //BOOST_TLS_HOOKS_RS06092306_HPP

View File

@@ -1,56 +0,0 @@
// Copyright 2006 Roland Schwarz.
// 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)
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
#ifndef BOOST_THREAD_RS06041006_HPP
#define BOOST_THREAD_RS06041006_HPP
#include <boost/thread/win32/config.hpp>
#include <boost/cstdint.hpp>
namespace boost {
enum xtime_clock_types
{
TIME_UTC=1
// TIME_TAI,
// TIME_MONOTONIC,
// TIME_PROCESS,
// TIME_THREAD,
// TIME_LOCAL,
// TIME_SYNC,
// TIME_RESOLUTION
};
struct xtime
{
#if defined(BOOST_NO_INT64_T)
typedef int_fast32_t xtime_sec_t; //INT_FAST32_MIN <= sec <= INT_FAST32_MAX
#else
typedef int_fast64_t xtime_sec_t; //INT_FAST64_MIN <= sec <= INT_FAST64_MAX
#endif
typedef int_fast32_t xtime_nsec_t; //0 <= xtime.nsec < NANOSECONDS_PER_SECOND
xtime_sec_t sec;
xtime_nsec_t nsec;
};
int BOOST_THREAD_DECL xtime_get(struct xtime* xtp, int clock_type);
inline int xtime_cmp(const xtime& xt1, const xtime& xt2)
{
if (xt1.sec == xt2.sec)
return (int)(xt1.nsec - xt2.nsec);
else
return (xt1.sec > xt2.sec) ? 1 : -1;
}
} // namespace boost
#endif //BOOST_THREAD_RS06041006_HPP

View File

@@ -1,85 +0,0 @@
#ifndef BOOST_THREAD_DETAIL_XTIME_UTILS_HPP
#define BOOST_THREAD_DETAIL_XTIME_UTILS_HPP
// xtime_utils.hpp
//
// (C) Copyright 2005 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/win32/xtime.hpp>
#include <limits>
namespace boost
{
namespace detail
{
inline ::boost::xtime get_xtime_sentinel()
{
boost::xtime const sentinel={
(std::numeric_limits<boost::xtime::xtime_sec_t>::max)(),
(std::numeric_limits<boost::xtime::xtime_nsec_t>::max)()
};
return sentinel;
}
// get the number of milliseconds from now to target
// if target is in the past, return 0
// if target cannot be represented as unsigned long, return
// the maximum instead
// 2006-08-04 <roland>
inline unsigned long get_milliseconds_until_time(::boost::xtime target)
{
if(!boost::xtime_cmp(target,get_xtime_sentinel()))
{
return (std::numeric_limits<unsigned long>::max)();
}
boost::xtime now;
boost::xtime_get(&now, boost::TIME_UTC);
if (target.sec < now.sec)
{
return 0;
}
else
{
boost::xtime::xtime_nsec_t const nanoseconds_per_second=1000000000;
boost::xtime::xtime_nsec_t const milliseconds_per_second=1000;
boost::xtime::xtime_nsec_t const nanoseconds_per_millisecond=nanoseconds_per_second/milliseconds_per_second;
if (target.nsec < now.nsec)
{
if (target.sec == now.sec)
{
return 0;
}
target.nsec += nanoseconds_per_second - now.nsec;
target.sec -= now.sec + 1;
}
else
{
target.nsec -= now.nsec;
target.sec -= now.sec;
}
// we are throwing away some bits, but one second after having
// waited for 49 years does not really matter ...
if (target.sec < (std::numeric_limits<unsigned long>::max)()/milliseconds_per_second)
{
return static_cast<unsigned long>(
target.sec*milliseconds_per_second +
(target.nsec+nanoseconds_per_millisecond/2)/nanoseconds_per_millisecond);
}
else
{
return (std::numeric_limits<unsigned long>::max)();
}
}
}
}
}
#endif

View File

@@ -1,16 +1,58 @@
// Copyright 2006 Roland Schwarz.
// 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)
// Copyright (C) 2001-2003
// William E. Kempf
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_THREAD_RS06040712_HPP
#define BOOST_THREAD_RS06040712_HPP
#ifndef BOOST_XTIME_WEK070601_HPP
#define BOOST_XTIME_WEK070601_HPP
#include <boost/thread/detail/platform.hpp>
#include BOOST_THREAD_PLATFORM(xtime.hpp)
#include <boost/thread/detail/config.hpp>
#endif // BOOST_THREAD_RS06040712_HPP
#include <boost/cstdint.hpp>
namespace boost {
enum xtime_clock_types
{
TIME_UTC=1
// TIME_TAI,
// TIME_MONOTONIC,
// TIME_PROCESS,
// TIME_THREAD,
// TIME_LOCAL,
// TIME_SYNC,
// TIME_RESOLUTION
};
struct xtime
{
#if defined(BOOST_NO_INT64_T)
int_fast32_t sec;
#else
int_fast64_t sec;
#endif
int_fast32_t nsec;
};
int BOOST_THREAD_DECL xtime_get(struct xtime* xtp, int clock_type);
inline int xtime_cmp(const xtime& xt1, const xtime& xt2)
{
int res = (int)(xt1.sec - xt2.sec);
if (res == 0)
res = (int)(xt1.nsec - xt2.nsec);
return res;
}
} // namespace boost
// Change Log:
// 8 Feb 01 WEKEMPF Initial version.
#endif // BOOST_XTIME_WEK070601_HPP

View File

@@ -5,4 +5,4 @@
<body>
Automatic redirection failed, please go to <a href="doc/index.html">doc/index.html</a>
</body>
</html>
</html>

49
src/barrier.cpp Normal file
View File

@@ -0,0 +1,49 @@
// Copyright (C) 2002-2003
// David Moore, William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/detail/config.hpp>
#include <boost/thread/barrier.hpp>
#include <boost/thread/thread.hpp>
namespace boost {
barrier::barrier(unsigned int count)
: m_threshold(count), m_count(count), m_generation(0)
{
if (count == 0)
throw std::invalid_argument("count cannot be zero.");
}
barrier::~barrier()
{
}
bool barrier::wait()
{
boost::mutex::scoped_lock lock(m_mutex);
unsigned int gen = m_generation;
if (--m_count == 0)
{
m_generation++;
m_count = m_threshold;
m_cond.notify_all();
return true;
}
boost::cancellation_guard guard;
while (gen == m_generation)
m_cond.wait(lock);
return false;
}
} // namespace boost

677
src/condition.cpp Normal file
View File

@@ -0,0 +1,677 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/detail/config.hpp>
#include <boost/thread/condition.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/limits.hpp>
#include <cassert>
#include "timeconv.inl"
#if defined(BOOST_HAS_WINTHREADS)
# ifndef NOMINMAX
# define NOMINMAX
# endif
# include <windows.h>
#elif defined(BOOST_HAS_PTHREADS)
# include <errno.h>
#elif defined(BOOST_HAS_MPTASKS)
# include <MacErrors.h>
# include "mac/init.hpp"
# include "mac/safe.hpp"
#endif
namespace boost {
namespace detail {
#if defined(BOOST_HAS_WINTHREADS)
condition_impl::condition_impl()
: m_gone(0), m_blocked(0), m_waiting(0)
{
m_gate = reinterpret_cast<void*>(CreateSemaphore(0, 1, 1, 0));
m_queue = reinterpret_cast<void*>(
CreateSemaphore(0, 0, (std::numeric_limits<long>::max)(), 0));
m_mutex = reinterpret_cast<void*>(CreateMutex(0, 0, 0));
if (!m_gate || !m_queue || !m_mutex)
{
int res = 0;
if (m_gate)
{
res = CloseHandle(reinterpret_cast<HANDLE>(m_gate));
assert(res);
}
if (m_queue)
{
res = CloseHandle(reinterpret_cast<HANDLE>(m_queue));
assert(res);
}
if (m_mutex)
{
res = CloseHandle(reinterpret_cast<HANDLE>(m_mutex));
assert(res);
}
throw thread_resource_error();
}
}
condition_impl::~condition_impl()
{
int res = 0;
res = CloseHandle(reinterpret_cast<HANDLE>(m_gate));
assert(res);
res = CloseHandle(reinterpret_cast<HANDLE>(m_queue));
assert(res);
res = CloseHandle(reinterpret_cast<HANDLE>(m_mutex));
assert(res);
}
void condition_impl::notify_one()
{
unsigned signals = 0;
int res = 0;
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_mutex), INFINITE);
assert(res == WAIT_OBJECT_0);
if (m_waiting != 0) // the m_gate is already closed
{
if (m_blocked == 0)
{
res = ReleaseMutex(reinterpret_cast<HANDLE>(m_mutex));
assert(res);
return;
}
++m_waiting;
--m_blocked;
signals = 1;
}
else
{
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_gate), INFINITE);
assert(res == WAIT_OBJECT_0);
if (m_blocked > m_gone)
{
if (m_gone != 0)
{
m_blocked -= m_gone;
m_gone = 0;
}
signals = m_waiting = 1;
--m_blocked;
}
else
{
res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0);
assert(res);
}
}
res = ReleaseMutex(reinterpret_cast<HANDLE>(m_mutex));
assert(res);
if (signals)
{
res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_queue), signals, 0);
assert(res);
}
}
void condition_impl::notify_all()
{
unsigned signals = 0;
int res = 0;
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_mutex), INFINITE);
assert(res == WAIT_OBJECT_0);
if (m_waiting != 0) // the m_gate is already closed
{
if (m_blocked == 0)
{
res = ReleaseMutex(reinterpret_cast<HANDLE>(m_mutex));
assert(res);
return;
}
m_waiting += (signals = m_blocked);
m_blocked = 0;
}
else
{
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_gate), INFINITE);
assert(res == WAIT_OBJECT_0);
if (m_blocked > m_gone)
{
if (m_gone != 0)
{
m_blocked -= m_gone;
m_gone = 0;
}
signals = m_waiting = m_blocked;
m_blocked = 0;
}
else
{
res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0);
assert(res);
}
}
res = ReleaseMutex(reinterpret_cast<HANDLE>(m_mutex));
assert(res);
if (signals)
{
res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_queue), signals, 0);
assert(res);
}
}
void condition_impl::enter_wait()
{
int res = 0;
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_gate), INFINITE);
assert(res == WAIT_OBJECT_0);
++m_blocked;
res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0);
assert(res);
}
void condition_impl::do_wait()
{
int res = 0;
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_queue), INFINITE);
assert(res == WAIT_OBJECT_0);
unsigned was_waiting=0;
unsigned was_gone=0;
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_mutex), INFINITE);
assert(res == WAIT_OBJECT_0);
was_waiting = m_waiting;
was_gone = m_gone;
if (was_waiting != 0)
{
if (--m_waiting == 0)
{
if (m_blocked != 0)
{
res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1,
0); // open m_gate
assert(res);
was_waiting = 0;
}
else if (m_gone != 0)
m_gone = 0;
}
}
else if (++m_gone == ((std::numeric_limits<unsigned>::max)() / 2))
{
// timeout occured, normalize the m_gone count
// this may occur if many calls to wait with a timeout are made and
// no call to notify_* is made
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_gate), INFINITE);
assert(res == WAIT_OBJECT_0);
m_blocked -= m_gone;
res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0);
assert(res);
m_gone = 0;
}
res = ReleaseMutex(reinterpret_cast<HANDLE>(m_mutex));
assert(res);
if (was_waiting == 1)
{
for (/**/ ; was_gone; --was_gone)
{
// better now than spurious later
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_queue),
INFINITE);
assert(res == WAIT_OBJECT_0);
}
res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0);
assert(res);
}
}
bool condition_impl::do_timed_wait(const xtime& xt)
{
bool ret = false;
unsigned int res = 0;
for (;;)
{
int milliseconds;
to_duration(xt, milliseconds);
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_queue),
milliseconds);
assert(res != WAIT_FAILED && res != WAIT_ABANDONED);
ret = (res == WAIT_OBJECT_0);
if (res == WAIT_TIMEOUT)
{
xtime cur;
xtime_get(&cur, TIME_UTC);
if (xtime_cmp(xt, cur) > 0)
continue;
}
break;
}
unsigned was_waiting=0;
unsigned was_gone=0;
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_mutex), INFINITE);
assert(res == WAIT_OBJECT_0);
was_waiting = m_waiting;
was_gone = m_gone;
if (was_waiting != 0)
{
if (!ret) // timeout
{
if (m_blocked != 0)
--m_blocked;
else
++m_gone; // count spurious wakeups
}
if (--m_waiting == 0)
{
if (m_blocked != 0)
{
res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1,
0); // open m_gate
assert(res);
was_waiting = 0;
}
else if (m_gone != 0)
m_gone = 0;
}
}
else if (++m_gone == ((std::numeric_limits<unsigned>::max)() / 2))
{
// timeout occured, normalize the m_gone count
// this may occur if many calls to wait with a timeout are made and
// no call to notify_* is made
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_gate), INFINITE);
assert(res == WAIT_OBJECT_0);
m_blocked -= m_gone;
res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0);
assert(res);
m_gone = 0;
}
res = ReleaseMutex(reinterpret_cast<HANDLE>(m_mutex));
assert(res);
if (was_waiting == 1)
{
for (/**/ ; was_gone; --was_gone)
{
// better now than spurious later
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_queue),
INFINITE);
assert(res == WAIT_OBJECT_0);
}
res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0);
assert(res);
}
return ret;
}
#elif defined(BOOST_HAS_PTHREADS)
condition_impl::condition_impl()
{
int res = 0;
res = pthread_cond_init(&m_condition, 0);
if (res != 0)
throw thread_resource_error();
}
condition_impl::~condition_impl()
{
int res = 0;
res = pthread_cond_destroy(&m_condition);
assert(res == 0);
}
void condition_impl::notify_one()
{
int res = 0;
res = pthread_cond_signal(&m_condition);
assert(res == 0);
}
void condition_impl::notify_all()
{
int res = 0;
res = pthread_cond_broadcast(&m_condition);
assert(res == 0);
}
void condition_impl::do_wait(pthread_mutex_t* pmutex)
{
int res = 0;
res = pthread_cond_wait(&m_condition, pmutex);
assert(res == 0);
}
bool condition_impl::do_timed_wait(const xtime& xt, pthread_mutex_t* pmutex)
{
timespec ts;
to_timespec(xt, ts);
int res = 0;
res = pthread_cond_timedwait(&m_condition, pmutex, &ts);
assert(res == 0 || res == ETIMEDOUT);
return res != ETIMEDOUT;
}
#elif defined(BOOST_HAS_MPTASKS)
using threads::mac::detail::safe_enter_critical_region;
using threads::mac::detail::safe_wait_on_semaphore;
condition_impl::condition_impl()
: m_gone(0), m_blocked(0), m_waiting(0)
{
threads::mac::detail::thread_init();
OSStatus lStatus = noErr;
lStatus = MPCreateSemaphore(1, 1, &m_gate);
if(lStatus == noErr)
lStatus = MPCreateSemaphore(ULONG_MAX, 0, &m_queue);
if(lStatus != noErr || !m_gate || !m_queue)
{
if (m_gate)
{
lStatus = MPDeleteSemaphore(m_gate);
assert(lStatus == noErr);
}
if (m_queue)
{
lStatus = MPDeleteSemaphore(m_queue);
assert(lStatus == noErr);
}
throw thread_resource_error();
}
}
condition_impl::~condition_impl()
{
OSStatus lStatus = noErr;
lStatus = MPDeleteSemaphore(m_gate);
assert(lStatus == noErr);
lStatus = MPDeleteSemaphore(m_queue);
assert(lStatus == noErr);
}
void condition_impl::notify_one()
{
unsigned signals = 0;
OSStatus lStatus = noErr;
lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
m_mutex_mutex);
assert(lStatus == noErr);
if (m_waiting != 0) // the m_gate is already closed
{
if (m_blocked == 0)
{
lStatus = MPExitCriticalRegion(m_mutex);
assert(lStatus == noErr);
return;
}
++m_waiting;
--m_blocked;
}
else
{
lStatus = safe_wait_on_semaphore(m_gate, kDurationForever);
assert(lStatus == noErr);
if (m_blocked > m_gone)
{
if (m_gone != 0)
{
m_blocked -= m_gone;
m_gone = 0;
}
signals = m_waiting = 1;
--m_blocked;
}
else
{
lStatus = MPSignalSemaphore(m_gate);
assert(lStatus == noErr);
}
lStatus = MPExitCriticalRegion(m_mutex);
assert(lStatus == noErr);
while (signals)
{
lStatus = MPSignalSemaphore(m_queue);
assert(lStatus == noErr);
--signals;
}
}
}
void condition_impl::notify_all()
{
unsigned signals = 0;
OSStatus lStatus = noErr;
lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
m_mutex_mutex);
assert(lStatus == noErr);
if (m_waiting != 0) // the m_gate is already closed
{
if (m_blocked == 0)
{
lStatus = MPExitCriticalRegion(m_mutex);
assert(lStatus == noErr);
return;
}
m_waiting += (signals = m_blocked);
m_blocked = 0;
}
else
{
lStatus = safe_wait_on_semaphore(m_gate, kDurationForever);
assert(lStatus == noErr);
if (m_blocked > m_gone)
{
if (m_gone != 0)
{
m_blocked -= m_gone;
m_gone = 0;
}
signals = m_waiting = m_blocked;
m_blocked = 0;
}
else
{
lStatus = MPSignalSemaphore(m_gate);
assert(lStatus == noErr);
}
lStatus = MPExitCriticalRegion(m_mutex);
assert(lStatus == noErr);
while (signals)
{
lStatus = MPSignalSemaphore(m_queue);
assert(lStatus == noErr);
--signals;
}
}
}
void condition_impl::enter_wait()
{
OSStatus lStatus = noErr;
lStatus = safe_wait_on_semaphore(m_gate, kDurationForever);
assert(lStatus == noErr);
++m_blocked;
lStatus = MPSignalSemaphore(m_gate);
assert(lStatus == noErr);
}
void condition_impl::do_wait()
{
OSStatus lStatus = noErr;
lStatus = safe_wait_on_semaphore(m_queue, kDurationForever);
assert(lStatus == noErr);
unsigned was_waiting=0;
unsigned was_gone=0;
lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
m_mutex_mutex);
assert(lStatus == noErr);
was_waiting = m_waiting;
was_gone = m_gone;
if (was_waiting != 0)
{
if (--m_waiting == 0)
{
if (m_blocked != 0)
{
lStatus = MPSignalSemaphore(m_gate); // open m_gate
assert(lStatus == noErr);
was_waiting = 0;
}
else if (m_gone != 0)
m_gone = 0;
}
}
else if (++m_gone == ((std::numeric_limits<unsigned>::max)() / 2))
{
// timeout occured, normalize the m_gone count
// this may occur if many calls to wait with a timeout are made and
// no call to notify_* is made
lStatus = safe_wait_on_semaphore(m_gate, kDurationForever);
assert(lStatus == noErr);
m_blocked -= m_gone;
lStatus = MPSignalSemaphore(m_gate);
assert(lStatus == noErr);
m_gone = 0;
}
lStatus = MPExitCriticalRegion(m_mutex);
assert(lStatus == noErr);
if (was_waiting == 1)
{
for (/**/ ; was_gone; --was_gone)
{
// better now than spurious later
lStatus = safe_wait_on_semaphore(m_queue, kDurationForever);
assert(lStatus == noErr);
}
lStatus = MPSignalSemaphore(m_gate);
assert(lStatus == noErr);
}
}
bool condition_impl::do_timed_wait(const xtime& xt)
{
int milliseconds;
to_duration(xt, milliseconds);
OSStatus lStatus = noErr;
lStatus = safe_wait_on_semaphore(m_queue, milliseconds);
assert(lStatus == noErr || lStatus == kMPTimeoutErr);
bool ret = (lStatus == noErr);
unsigned was_waiting=0;
unsigned was_gone=0;
lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
m_mutex_mutex);
assert(lStatus == noErr);
was_waiting = m_waiting;
was_gone = m_gone;
if (was_waiting != 0)
{
if (!ret) // timeout
{
if (m_blocked != 0)
--m_blocked;
else
++m_gone; // count spurious wakeups
}
if (--m_waiting == 0)
{
if (m_blocked != 0)
{
lStatus = MPSignalSemaphore(m_gate); // open m_gate
assert(lStatus == noErr);
was_waiting = 0;
}
else if (m_gone != 0)
m_gone = 0;
}
}
else if (++m_gone == ((std::numeric_limits<unsigned>::max)() / 2))
{
// timeout occured, normalize the m_gone count
// this may occur if many calls to wait with a timeout are made and
// no call to notify_* is made
lStatus = safe_wait_on_semaphore(m_gate, kDurationForever);
assert(lStatus == noErr);
m_blocked -= m_gone;
lStatus = MPSignalSemaphore(m_gate);
assert(lStatus == noErr);
m_gone = 0;
}
lStatus = MPExitCriticalRegion(m_mutex);
assert(lStatus == noErr);
if (was_waiting == 1)
{
for (/**/ ; was_gone; --was_gone)
{
// better now than spurious later
lStatus = safe_wait_on_semaphore(m_queue, kDurationForever);
assert(lStatus == noErr);
}
lStatus = MPSignalSemaphore(m_gate);
assert(lStatus == noErr);
}
return ret;
}
#endif
} // namespace detail
} // namespace boost
// Change Log:
// 8 Feb 01 WEKEMPF Initial version.
// 22 May 01 WEKEMPF Modified to use xtime for time outs.
// 3 Jan 03 WEKEMPF Modified for DLL implementation.

View File

@@ -1,13 +1,17 @@
// Copyright 2006 Roland Schwarz.
// 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)
// Copyright (C) 2001-2003
// William E. Kempf
//
// This work is a reimplementation along the design and ideas
// of William E. Kempf.
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/win32/config.hpp>
#include <boost/thread/win32/exceptions.hpp>
#include <boost/thread/detail/config.hpp>
#include <boost/thread/exceptions.hpp>
#include <cstring>
#include <string>
@@ -15,7 +19,20 @@
namespace std { using ::strerror; }
# endif
#include "windows.h"
// BOOST_POSIX or BOOST_WINDOWS specify which API to use.
# if !defined( BOOST_WINDOWS ) && !defined( BOOST_POSIX )
# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)
# define BOOST_WINDOWS
# else
# define BOOST_POSIX
# endif
# endif
# if defined( BOOST_WINDOWS )
# include "windows.h"
# else
# include <errno.h> // for POSIX error codes
# endif
namespace
{
@@ -23,6 +40,7 @@ namespace
std::string system_message(int sys_err_code)
{
std::string str;
# ifdef BOOST_WINDOWS
LPVOID lpMsgBuf;
::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
@@ -40,6 +58,9 @@ std::string system_message(int sys_err_code)
{
str.erase(str.size()-1);
}
# else
str += std::strerror(errno);
# endif
return str;
}
@@ -61,11 +82,6 @@ thread_exception::~thread_exception() throw()
{
}
int thread_exception::native_error() const
{
return m_sys_err;
}
const char* thread_exception::message() const
{
if (m_sys_err != 0)

14
src/mac/debug_prefix.hpp Normal file
View File

@@ -0,0 +1,14 @@
// Copyright (C) 2001
// Mac Murrett
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. Mac Murrett makes no representations
// about the suitability of this software for any purpose. It is
// provided "as is" without express or implied warranty.
//
// See http://www.boost.org for most recent version including documentation.
#define TARGET_CARBON 1

72
src/mac/delivery_man.cpp Normal file
View File

@@ -0,0 +1,72 @@
// Copyright (C) 2001
// Mac Murrett
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. Mac Murrett makes no representations
// about the suitability of this software for any purpose. It is
// provided "as is" without express or implied warranty.
//
// See http://www.boost.org for most recent version including documentation.
#include "delivery_man.hpp"
#include "os.hpp"
#include "execution_context.hpp"
namespace boost {
namespace threads {
namespace mac {
namespace detail {
delivery_man::delivery_man():
m_pPackage(NULL),
m_pSemaphore(kInvalidID),
m_bPackageWaiting(false)
{
assert(at_st());
OSStatus lStatus = MPCreateSemaphore(1UL, 0UL, &m_pSemaphore);
// TODO - throw on error here
assert(lStatus == noErr);
}
delivery_man::~delivery_man()
{
assert(m_bPackageWaiting == false);
OSStatus lStatus = MPDeleteSemaphore(m_pSemaphore);
assert(lStatus == noErr);
}
void delivery_man::accept_deliveries()
{
if(m_bPackageWaiting)
{
assert(m_pPackage != NULL);
m_pPackage->accept();
m_pPackage = NULL;
m_bPackageWaiting = false;
// signal to the thread making the call that we're done
OSStatus lStatus = MPSignalSemaphore(m_pSemaphore);
assert(lStatus == noErr);
}
}
} // namespace detail
} // namespace mac
} // namespace threads
} // namespace boost

90
src/mac/delivery_man.hpp Normal file
View File

@@ -0,0 +1,90 @@
// Copyright (C) 2001
// Mac Murrett
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. Mac Murrett makes no representations
// about the suitability of this software for any purpose. It is
// provided "as is" without express or implied warranty.
//
// See http://www.boost.org for most recent version including documentation.
#ifndef BOOST_DELIVERY_MAN_MJM012402_HPP
#define BOOST_DELIVERY_MAN_MJM012402_HPP
#include <boost/function.hpp>
#include <boost/utility.hpp>
#include <boost/thread/mutex.hpp>
#include "package.hpp"
#include <Multiprocessing.h>
namespace boost {
namespace threads {
namespace mac {
namespace detail {
// class delivery_man is intended to move boost::function objects from MP tasks to
// other execution contexts (such as deferred task time or system task time).
class delivery_man: private noncopyable
{
public:
delivery_man();
~delivery_man();
public:
template<class R>
R deliver(function<R> &rFunctor);
void accept_deliveries();
private:
base_package *m_pPackage;
mutex m_oMutex;
MPSemaphoreID m_pSemaphore;
bool m_bPackageWaiting;
};
template<class R>
R delivery_man::deliver(function<R> &rFunctor)
{
assert(at_mp());
// lock our mutex
mutex::scoped_lock oLock(m_oMutex);
// create a package and save it
package<R> oPackage(rFunctor);
m_pPackage = &oPackage;
m_bPackageWaiting = true;
// wait on the semaphore
OSStatus lStatus = MPWaitOnSemaphore(m_pSemaphore, kDurationForever);
assert(lStatus == noErr);
return(oPackage.return_value());
}
} // namespace detail
} // namespace mac
} // namespace threads
} // namespace boost
#endif // BOOST_DELIVERY_MAN_MJM012402_HPP

99
src/mac/dt_scheduler.cpp Normal file
View File

@@ -0,0 +1,99 @@
// Copyright (C) 2001
// Mac Murrett
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. Mac Murrett makes no representations
// about the suitability of this software for any purpose. It is
// provided "as is" without express or implied warranty.
//
// See http://www.boost.org for most recent version including documentation.
#include "dt_scheduler.hpp"
#include "ot_context.hpp"
#include <boost/thread/detail/singleton.hpp>
#include <OpenTransportProtocol.h>
namespace boost {
namespace threads {
namespace mac {
namespace detail {
const OTTimeout k_ulTimerTaskDelay = 1UL;
dt_scheduler::dt_scheduler():
m_bReschedule(false),
m_uppTask(NULL),
m_lTask(0UL)
{
using ::boost::detail::thread::singleton;
ot_context &rContext(singleton<ot_context>::instance());
m_uppTask = NewOTProcessUPP(task_entry);
m_lTask = OTCreateTimerTaskInContext(m_uppTask, this, rContext.get_context());
}
dt_scheduler::~dt_scheduler()
{
OTDestroyTimerTask(m_lTask);
m_lTask = 0UL;
DisposeOTProcessUPP(m_uppTask);
m_uppTask = NULL;
}
void dt_scheduler::start_polling()
{
m_bReschedule = true;
schedule_task();
}
void dt_scheduler::stop_polling()
{
m_bReschedule = false;
}
void dt_scheduler::schedule_task()
{
if(m_bReschedule)
{
OTScheduleTimerTask(m_lTask, k_ulTimerTaskDelay);
}
}
/*static*/ pascal void dt_scheduler::task_entry(void *pRefCon)
{
dt_scheduler *pThis = reinterpret_cast<dt_scheduler *>(pRefCon);
assert(pThis != NULL);
pThis->task();
}
void dt_scheduler::task()
{
periodic_function();
schedule_task();
}
} // namespace detail
} // namespace mac
} // namespace threads
} // namespace boost

69
src/mac/dt_scheduler.hpp Normal file
View File

@@ -0,0 +1,69 @@
// Copyright (C) 2001
// Mac Murrett
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. Mac Murrett makes no representations
// about the suitability of this software for any purpose. It is
// provided "as is" without express or implied warranty.
//
// See http://www.boost.org for most recent version including documentation.
#ifndef BOOST_DT_SCHEDULER_MJM012402_HPP
#define BOOST_DT_SCHEDULER_MJM012402_HPP
#include "periodical.hpp"
#include <OpenTransport.h>
namespace boost {
namespace threads {
namespace mac {
namespace detail {
// class dt_scheduler calls its pure-virtual periodic_function method periodically at
// deferred task time. This is generally 1kHz under Mac OS 9.
class dt_scheduler
{
public:
dt_scheduler();
virtual ~dt_scheduler();
protected:
void start_polling();
void stop_polling();
private:
virtual void periodic_function() = 0;
private:
void schedule_task();
static pascal void task_entry(void *pRefCon);
void task();
private:
bool m_bReschedule;
OTProcessUPP m_uppTask;
long m_lTask;
};
} // namespace detail
} // namespace mac
} // namespace threads
} // namespace boost
#endif // BOOST_DT_SCHEDULER_MJM012402_HPP

View File

@@ -0,0 +1,66 @@
// Copyright (C) 2001
// Mac Murrett
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. Mac Murrett makes no representations
// about the suitability of this software for any purpose. It is
// provided "as is" without express or implied warranty.
//
// See http://www.boost.org for most recent version including documentation.
#include <Debugging.h>
#include <Multiprocessing.h>
#include "execution_context.hpp"
#include "init.hpp"
namespace boost {
namespace threads {
namespace mac {
execution_context_t execution_context()
{
// make sure that MP services are available the first time through
static bool bIgnored = detail::thread_init();
// first check if we're an MP task
if(MPTaskIsPreemptive(kInvalidID))
{
return(k_eExecutionContextMPTask);
}
#if TARGET_CARBON
// Carbon has TaskLevel
UInt32 ulLevel = TaskLevel();
if(ulLevel == 0UL)
{
return(k_eExecutionContextSystemTask);
}
if(ulLevel & kInDeferredTaskMask)
{
return(k_eExecutionContextDeferredTask);
}
return(k_eExecutionContextOther);
#else
// this can be implemented using TaskLevel if you don't mind linking against
// DebugLib (and therefore breaking Mac OS 8.6 support), or CurrentExecutionLevel.
# error execution_context unimplimented
#endif
}
} // namespace mac
} // namespace threads
} // namespace boost

View File

@@ -0,0 +1,53 @@
// Copyright (C) 2001
// Mac Murrett
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. Mac Murrett makes no representations
// about the suitability of this software for any purpose. It is
// provided "as is" without express or implied warranty.
//
// See http://www.boost.org for most recent version including documentation.
#ifndef BOOST_EXECUTION_CONTEXT_MJM012402_HPP
#define BOOST_EXECUTION_CONTEXT_MJM012402_HPP
namespace boost {
namespace threads {
namespace mac {
// utility functions for figuring out what context your code is executing in.
// Bear in mind that at_mp and in_blue are the only functions guarenteed by
// Apple to work. There is simply no way of being sure that you will not get
// false readings about task level at interrupt time in blue.
typedef enum {
k_eExecutionContextSystemTask,
k_eExecutionContextDeferredTask,
k_eExecutionContextMPTask,
k_eExecutionContextOther
} execution_context_t;
execution_context_t execution_context();
inline bool at_st()
{ return(execution_context() == k_eExecutionContextSystemTask); }
inline bool at_mp()
{ return(execution_context() == k_eExecutionContextMPTask); }
inline bool in_blue()
{ return(!at_mp()); }
} // namespace mac
} // namespace threads
} // namespace boost
#endif // BOOST_EXECUTION_CONTEXT_MJM012402_HPP

Some files were not shown because too many files have changed in this diff Show More