mirror of
https://github.com/boostorg/thread.git
synced 2026-02-03 09:42:16 +00:00
Compare commits
110 Commits
boost-1.32
...
svn-branch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f9292e2e3 | ||
|
|
0a88a53a33 | ||
|
|
0bce1befd9 | ||
|
|
9f354c98ab | ||
|
|
274b04bcf7 | ||
|
|
539d19468d | ||
|
|
fff6d9eddd | ||
|
|
5472ebdfde | ||
|
|
50c034f650 | ||
|
|
2a5e1a36b5 | ||
|
|
2e10da00ba | ||
|
|
af4b2d5d2a | ||
|
|
a89ec945c0 | ||
|
|
08eb9eed48 | ||
|
|
7ed1a79ab8 | ||
|
|
18974b3cb4 | ||
|
|
c973faf627 | ||
|
|
6ffcde749a | ||
|
|
42840199aa | ||
|
|
1addb6ad9b | ||
|
|
1dbdb77ed7 | ||
|
|
430ebf66f9 | ||
|
|
97562928a8 | ||
|
|
45aabefb4d | ||
|
|
b0e970863b | ||
|
|
3468fb61bc | ||
|
|
5982a97bdf | ||
|
|
ffef009696 | ||
|
|
c8f181e461 | ||
|
|
7b84d69915 | ||
|
|
bbb8efe58f | ||
|
|
63209e3c69 | ||
|
|
2272c322f9 | ||
|
|
36acb80412 | ||
|
|
b72142cef7 | ||
|
|
6dd6f51faa | ||
|
|
82630dc9bb | ||
|
|
3402aea7c1 | ||
|
|
5c4bd8e9c9 | ||
|
|
a11748d187 | ||
|
|
dc906613dc | ||
|
|
b69bdd3918 | ||
|
|
d90ef5eeef | ||
|
|
641d658a10 | ||
|
|
fef99d3db2 | ||
|
|
0fc8d8897d | ||
|
|
ad9f6244b0 | ||
|
|
59d082202c | ||
|
|
b7549a5bae | ||
|
|
f0dce755bb | ||
|
|
c1261d6df3 | ||
|
|
1fb0dac16d | ||
|
|
424d02fafa | ||
|
|
52717aaa75 | ||
|
|
335f85ad5b | ||
|
|
7da456edca | ||
|
|
f50176946d | ||
|
|
aeafcbb822 | ||
|
|
171b890972 | ||
|
|
89a9531d34 | ||
|
|
3259f681a4 | ||
|
|
17f72cf580 | ||
|
|
e03f0ed008 | ||
|
|
0804944002 | ||
|
|
8e5d5002cd | ||
|
|
008aaeaeee | ||
|
|
c1283bb731 | ||
|
|
46b1a4d1e3 | ||
|
|
ff6e0df2bc | ||
|
|
9cb9224b3c | ||
|
|
5ea5494172 | ||
|
|
e4c27981d0 | ||
|
|
fe61772d47 | ||
|
|
a437d6d7f6 | ||
|
|
c9f52098b9 | ||
|
|
a15a35a4b6 | ||
|
|
14c8137ba6 | ||
|
|
5caf9ed169 | ||
|
|
5da4a7b105 | ||
|
|
91c4af37ad | ||
|
|
5848dc2f56 | ||
|
|
efa12b1db9 | ||
|
|
58b6eba0ea | ||
|
|
f73253fcf5 | ||
|
|
3627dfc3b7 | ||
|
|
f8ebb9a127 | ||
|
|
2a0f57a8de | ||
|
|
da7278acef | ||
|
|
b17eb23f2e | ||
|
|
8e01ac5d04 | ||
|
|
5d6a1633e0 | ||
|
|
2e6f9a785e | ||
|
|
4e1acef27e | ||
|
|
73e482832d | ||
|
|
949b332337 | ||
|
|
244cfd3f01 | ||
|
|
3239fe0c22 | ||
|
|
ca10110aa7 | ||
|
|
fd4c76c7a5 | ||
|
|
60d7c84aa2 | ||
|
|
c043efa346 | ||
|
|
dab1961b5a | ||
|
|
6f94d26c50 | ||
|
|
83baf142f2 | ||
|
|
88bb39e3ce | ||
|
|
48ad27558a | ||
|
|
a0ba7f174c | ||
|
|
6e60d33181 | ||
|
|
bc69926604 | ||
|
|
d90825f7f9 |
@@ -1,2 +1,3 @@
|
||||
bin*
|
||||
*.pdb
|
||||
bjam.log
|
||||
@@ -12,7 +12,14 @@
|
||||
# Boost.Threads build Jamfile
|
||||
#
|
||||
# Additional configuration variables used:
|
||||
# See threads.jam.
|
||||
# 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 ;
|
||||
@@ -23,20 +30,21 @@ subproject libs/thread/build ;
|
||||
import ./threads ;
|
||||
|
||||
{
|
||||
CPP_SOURCES =
|
||||
barrier
|
||||
condition
|
||||
exceptions
|
||||
mutex
|
||||
CPP_SOURCES =
|
||||
barrier
|
||||
condition
|
||||
exceptions
|
||||
mutex
|
||||
named
|
||||
once
|
||||
recursive_mutex
|
||||
recursive_mutex
|
||||
read_write_mutex
|
||||
thread
|
||||
tss_hooks
|
||||
tss_dll
|
||||
tss_pe
|
||||
tss
|
||||
xtime
|
||||
shared_memory
|
||||
thread
|
||||
threadmon
|
||||
thread_pool
|
||||
tss
|
||||
xtime
|
||||
;
|
||||
|
||||
template boost_thread_lib_base
|
||||
@@ -44,28 +52,26 @@ import ./threads ;
|
||||
<template>thread_base
|
||||
../src/$(CPP_SOURCES).cpp
|
||||
: ## requirements ##
|
||||
<sysinclude>$(BOOST_ROOT) #:should be unnecessary (because already included in thread_base)
|
||||
<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
|
||||
common-variant-tag
|
||||
: ## default build ##
|
||||
;
|
||||
|
||||
template boost_thread_dll_base
|
||||
template thread_dll_base
|
||||
: ## sources ##
|
||||
<template>thread_base
|
||||
<template>thread_base
|
||||
../src/$(CPP_SOURCES).cpp
|
||||
: ## requirements ##
|
||||
<sysinclude>$(BOOST_ROOT) #:should be unnecessary (because already included in thread_base)
|
||||
<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
|
||||
common-variant-tag
|
||||
: ## default build ##
|
||||
;
|
||||
|
||||
@@ -79,7 +85,7 @@ import ./threads ;
|
||||
|
||||
dll $(boost_thread_lib_name)
|
||||
: ## sources ##
|
||||
<template>boost_thread_dll_base
|
||||
<template>thread_dll_base
|
||||
: ## requirements ##
|
||||
<define>BOOST_THREAD_LIB_NAME=$(boost_thread_lib_name)
|
||||
: ## default build ##
|
||||
@@ -107,7 +113,7 @@ import ./threads ;
|
||||
|
||||
dll $(boost_thread_lib_name_ptw32)
|
||||
: ## sources ##
|
||||
<template>boost_thread_dll_base
|
||||
<template>thread_dll_base
|
||||
: ## requirements ##
|
||||
<define>BOOST_THREAD_LIB_NAME=$(boost_thread_lib_name_ptw32)
|
||||
$(pthreads-win32)
|
||||
|
||||
@@ -1,26 +1,12 @@
|
||||
import os ;
|
||||
|
||||
if [ os.name ] = NT
|
||||
{
|
||||
reqts = <link>shared:<define>BOOST_THREAD_BUILD_DLL=1 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
# Declare the uses system library
|
||||
lib pthread : : <name>pthread ;
|
||||
usage = <library>pthread ;
|
||||
}
|
||||
# Declare the uses system library
|
||||
lib pthread : : <name>pthread ;
|
||||
|
||||
project boost/thread
|
||||
: source-location ../src
|
||||
: usage-requirements $(usage)
|
||||
: requirements $(reqts) <threading>multi
|
||||
: default-build <threading>multi
|
||||
: usage-requirements <library>pthread
|
||||
;
|
||||
|
||||
CPP_SOURCES = condition mutex recursive_mutex thread xtime once
|
||||
exceptions barrier tss tss_hooks tss_dll tss_pe ;
|
||||
CPP_SOURCES = condition mutex recursive_mutex thread tss xtime once exceptions ;
|
||||
|
||||
lib boost_thread
|
||||
: $(CPP_SOURCES).cpp
|
||||
;
|
||||
lib boost_thread : $(CPP_SOURCES).cpp ;
|
||||
|
||||
@@ -9,31 +9,6 @@
|
||||
# about the suitability of this software for any purpose.
|
||||
# It is provided "as is" without express or implied warranty.
|
||||
|
||||
# Additional configuration variables used:
|
||||
# 1. PTW32_DIR and PTW32_LIB may be used on Win32 platforms to specify that
|
||||
# a version of Boost.Threads should be built that uses the
|
||||
# the pthreads-win32 library instead of the Win32 native threading APIs.
|
||||
# This feature is mostly used for testing and it's generally recommended
|
||||
# that you use the Win32 native threading libraries instead.
|
||||
#
|
||||
# PTW32_Dir should be set to the installation path of the
|
||||
# pthreads-win32 library and PTW32_LIB should be set to the name of the
|
||||
# library variant to link against (see the pthreads-win32 documentation).
|
||||
# Example: jam -sPTW32_DIR="c:\pthreads-win32" -sPTW32_LIB="pthreadVCE.lib"
|
||||
# Alternately, environment variables having the names PTW32_DIR and PTW32_LIB
|
||||
# can be set instead of passing these values on the command line.
|
||||
#
|
||||
# In either case, libraries having the names boost_thread_ptw32<tags>.dll
|
||||
# and libboost_thread_ptw32<tags>.lib will be built
|
||||
# in addition to the usual boost_thread<tags>.dll and
|
||||
# libboost_thread<tags>.lib. Link with one of the ptw32 versions
|
||||
# of the Boost.Threads libraries to use the version of Boost.Threads
|
||||
# that is implemented using pthreads-win32 (you will need to #define
|
||||
# BOOST_THREAD_NO_LIB or BOOST_ALL_NO_LIB to disable auto-linking
|
||||
# if your platform supports auto-linking in order to prevent
|
||||
# your build from attempting to link to two different versions of
|
||||
# the Boost.Threads library).
|
||||
|
||||
# Do some OS-specific setup
|
||||
{
|
||||
#thread library name
|
||||
|
||||
3
doc/.cvsignore
Normal file
3
doc/.cvsignore
Normal file
@@ -0,0 +1,3 @@
|
||||
bin
|
||||
html
|
||||
catalog.xml
|
||||
@@ -1,6 +1,5 @@
|
||||
project boost/doc ;
|
||||
import boostbook : boostbook ;
|
||||
|
||||
import toolset ;
|
||||
toolset.using doxygen ;
|
||||
|
||||
boostbook thread : thread.xml ;
|
||||
boostbook doc : thread.xml ;
|
||||
|
||||
|
||||
@@ -75,4 +75,4 @@
|
||||
</method-group>
|
||||
</class>
|
||||
</namespace>
|
||||
</header>
|
||||
</header>
|
||||
@@ -55,4 +55,4 @@
|
||||
<programlisting>bjam -sTOOLS=<emphasis>toolset</emphasis> test</programlisting>
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
147
doc/concepts.xml
147
doc/concepts.xml
@@ -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>
|
||||
@@ -89,4 +89,4 @@
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
@@ -55,4 +55,4 @@
|
||||
</constructor>
|
||||
</class>
|
||||
</namespace>
|
||||
</header>
|
||||
</header>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -83,4 +83,4 @@ void thread_proc()
|
||||
</postconditions>
|
||||
</function>
|
||||
</namespace>
|
||||
</header>
|
||||
</header>
|
||||
@@ -431,4 +431,4 @@
|
||||
and will be less likely to contain latent defects.</para>
|
||||
<para>[Rationale provided by Beman Dawes]</para>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
@@ -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>
|
||||
@@ -299,4 +299,4 @@
|
||||
</destructor>
|
||||
</class>
|
||||
</namespace>
|
||||
</header>
|
||||
</header>
|
||||
@@ -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>
|
||||
|
||||
@@ -263,4 +263,4 @@
|
||||
</method-group>
|
||||
</class>
|
||||
</namespace>
|
||||
</header>
|
||||
</header>
|
||||
@@ -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,8 +30,11 @@ 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>
|
||||
|
||||
13
doc/thread_pool-ref.xml
Normal file
13
doc/thread_pool-ref.xml
Normal 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
207
doc/thread_pool.html
Normal 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 <boost/thread/thread_pool.hpp></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 <<a href="../../../boost/thread/thread_pool.hpp">boost/thread/thread_pool.hpp</a>></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 <<a href="../../../boost/thread/thread_pool.hpp">boost/thread/thread_pool.hpp</a>>
|
||||
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 an interface for running
|
||||
jobs on a dynamically managed set of worker threads called a pool.
|
||||
When a job is added, it can execute on any available thread in the pool.
|
||||
This class controls both the maximum and minimum number of threads in
|
||||
the pool. If a thread in the pool is sitting idle for a period of
|
||||
time, it 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<int>::max(),
|
||||
int min_threads=0,
|
||||
int timeout_secs=5);
|
||||
~thread_pool();
|
||||
|
||||
void add(const boost::function0<void> &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<int>::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. 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<void>& 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. 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. 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. That new thread will execute this job
|
||||
as soon as it is scheduled by the operating system. If no threads are
|
||||
idle and the thread count is at the maximum, this job will be queued until
|
||||
a thread becomes available. 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. 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() 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. 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. 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. When join()
|
||||
returns, no running threads will remain in the pool, and this object is invalid
|
||||
for anything except destruction. 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 <boost/thread/thread_pool.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <iostream>
|
||||
|
||||
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 << param << " squared is " << (param*param) << "\n";
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
boost::thread_pool tp;
|
||||
for (int i = 1; i <= 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>© 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 "as is" without express or implied warranty.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -199,4 +199,4 @@
|
||||
</method-group>
|
||||
</class>
|
||||
</namespace>
|
||||
</header>
|
||||
</header>
|
||||
@@ -75,4 +75,4 @@
|
||||
</data-member>
|
||||
</struct>
|
||||
</namespace>
|
||||
</header>
|
||||
</header>
|
||||
@@ -1,2 +1,2 @@
|
||||
bin
|
||||
*.pdb
|
||||
*.pdb
|
||||
@@ -19,7 +19,7 @@
|
||||
namespace
|
||||
{
|
||||
boost::mutex iomx;
|
||||
} // namespace
|
||||
}
|
||||
|
||||
class canteen
|
||||
{
|
||||
|
||||
@@ -22,47 +22,23 @@
|
||||
# define BOOST_THREAD_DECL __declspec(dllexport)
|
||||
# elif defined(BOOST_THREAD_BUILD_LIB) //Build lib
|
||||
# define BOOST_THREAD_DECL
|
||||
# elif defined(BOOST_THREAD_USE_DLL) //Use dll
|
||||
# define BOOST_THREAD_DECL __declspec(dllimport)
|
||||
# define BOOST_DYN_LINK
|
||||
# elif defined(BOOST_THREAD_USE_LIB) //Use lib
|
||||
# define BOOST_THREAD_DECL
|
||||
# else //Use default
|
||||
# if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)
|
||||
//For VC++, choose according to threading library setting
|
||||
# if defined(_DLL)
|
||||
//Threading library is dll: use Boost.Threads dll
|
||||
# define BOOST_THREAD_USE_DLL
|
||||
# define BOOST_THREAD_DECL __declspec(dllimport)
|
||||
# define BOOST_DYN_LINK
|
||||
# else
|
||||
//Threading library is lib: used Boost.Threads lib
|
||||
# define BOOST_THREAD_USE_LIB
|
||||
# define BOOST_THREAD_DECL
|
||||
# endif
|
||||
# else
|
||||
//For compilers not yet supporting auto-tss cleanup
|
||||
//with Boost.Threads lib, use Boost.Threads dll
|
||||
# define BOOST_THREAD_USE_DLL
|
||||
# define BOOST_THREAD_DECL __declspec(dllimport)
|
||||
# define BOOST_DYN_LINK
|
||||
# endif
|
||||
# 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 dll
|
||||
# define BOOST_THREAD_USE_DLL
|
||||
# if defined(BOOST_THREAD_USE_LIB) //Use lib
|
||||
# else //Use dll
|
||||
# define BOOST_DYN_LINK
|
||||
# elif defined(BOOST_THREAD_USE_DLL) //Use lib
|
||||
# define BOOST_THREAD_USE_LIB
|
||||
# else //Use default
|
||||
# define BOOST_THREAD_USE_LIB
|
||||
# endif
|
||||
#endif // BOOST_HAS_WINTHREADS
|
||||
|
||||
//
|
||||
// Automatically link to the correct build variant where possible.
|
||||
//
|
||||
// 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
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
// Copyright (C) 2001-2003
|
||||
// Mac Murrett
|
||||
//
|
||||
// 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. 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.
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -1108,4 +1108,4 @@ private:
|
||||
// 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.
|
||||
// Add mutex_type typdef.
|
||||
@@ -1,9 +1,13 @@
|
||||
// Copyright (C) 2001-2003
|
||||
// Mac Murrett
|
||||
//
|
||||
// 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. 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.
|
||||
|
||||
|
||||
35
include/boost/thread/detail/threadmon.hpp
Normal file
35
include/boost/thread/detail/threadmon.hpp
Normal 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
|
||||
@@ -1,78 +0,0 @@
|
||||
// (C) Copyright Michael Glassford 2004.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(BOOST_TLS_HOOKS_HPP)
|
||||
#define BOOST_TLS_HOOKS_HPP
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
|
||||
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 peform cleanup.
|
||||
//Like the C runtime library atexit() function,
|
||||
//which it mimics, at_thread_exit() returns
|
||||
//zero if successful and a nonzero
|
||||
//value if an error occurs.
|
||||
|
||||
#endif //defined(BOOST_HAS_WINTHREADS)
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
|
||||
extern "C" BOOST_THREAD_DECL void on_process_enter(void);
|
||||
//Function to be called when the exe or dll
|
||||
//that uses Boost.Threads first starts
|
||||
//or is first loaded.
|
||||
//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 //defined(BOOST_HAS_WINTHREADS)
|
||||
|
||||
#endif //!defined(BOOST_TLS_HOOKS_HPP)
|
||||
@@ -20,7 +20,6 @@
|
||||
// given the include guards, but regardless it makes sense to
|
||||
// seperate this out any way.
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace boost {
|
||||
@@ -34,7 +33,7 @@ protected:
|
||||
public:
|
||||
~thread_exception() throw();
|
||||
|
||||
int native_error() const;
|
||||
int native_error() const { return m_sys_err; }
|
||||
|
||||
const char* message() const;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/thread/detail/lock.hpp>
|
||||
#include <boost/thread/detail/named.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_PTHREADS)
|
||||
# include <pthread.h>
|
||||
@@ -31,13 +32,14 @@ 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();
|
||||
mutex(const char* name=0);
|
||||
~mutex();
|
||||
|
||||
private:
|
||||
@@ -71,6 +73,7 @@ private:
|
||||
|
||||
class BOOST_THREAD_DECL try_mutex
|
||||
: private noncopyable
|
||||
, public boost::detail::named_object
|
||||
{
|
||||
public:
|
||||
friend class detail::thread::lock_ops<try_mutex>;
|
||||
@@ -78,7 +81,7 @@ public:
|
||||
typedef detail::thread::scoped_lock<try_mutex> scoped_lock;
|
||||
typedef detail::thread::scoped_try_lock<try_mutex> scoped_try_lock;
|
||||
|
||||
try_mutex();
|
||||
try_mutex(const char* name=0);
|
||||
~try_mutex();
|
||||
|
||||
private:
|
||||
@@ -113,6 +116,7 @@ private:
|
||||
|
||||
class BOOST_THREAD_DECL timed_mutex
|
||||
: private noncopyable
|
||||
, public boost::detail::named_object
|
||||
{
|
||||
public:
|
||||
friend class detail::thread::lock_ops<timed_mutex>;
|
||||
@@ -121,7 +125,7 @@ public:
|
||||
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(const char* name=0);
|
||||
~timed_mutex();
|
||||
|
||||
private:
|
||||
|
||||
@@ -97,10 +97,8 @@ struct read_write_mutex_impl
|
||||
private:
|
||||
|
||||
void do_unlock_scheduling_impl();
|
||||
void do_timeout_scheduling_impl();
|
||||
void do_demote_scheduling_impl();
|
||||
void do_scheduling_impl();
|
||||
|
||||
bool do_demote_to_read_lock_impl();
|
||||
};
|
||||
|
||||
@@ -270,4 +268,4 @@ private:
|
||||
// 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.
|
||||
// Add mutex_type typdef.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/thread/detail/lock.hpp>
|
||||
#include <boost/thread/detail/named.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_PTHREADS)
|
||||
# include <pthread.h>
|
||||
@@ -31,13 +32,14 @@ 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();
|
||||
recursive_mutex(const char* name=0);
|
||||
~recursive_mutex();
|
||||
|
||||
private:
|
||||
@@ -76,6 +78,7 @@ private:
|
||||
|
||||
class BOOST_THREAD_DECL recursive_try_mutex
|
||||
: private noncopyable
|
||||
, public boost::detail::named_object
|
||||
{
|
||||
public:
|
||||
friend class detail::thread::lock_ops<recursive_try_mutex>;
|
||||
@@ -84,7 +87,7 @@ public:
|
||||
typedef detail::thread::scoped_try_lock<
|
||||
recursive_try_mutex> scoped_try_lock;
|
||||
|
||||
recursive_try_mutex();
|
||||
recursive_try_mutex(const char* name=0);
|
||||
~recursive_try_mutex();
|
||||
|
||||
private:
|
||||
@@ -124,6 +127,7 @@ private:
|
||||
|
||||
class BOOST_THREAD_DECL recursive_timed_mutex
|
||||
: private noncopyable
|
||||
, public boost::detail::named_object
|
||||
{
|
||||
public:
|
||||
friend class detail::thread::lock_ops<recursive_timed_mutex>;
|
||||
@@ -134,7 +138,7 @@ public:
|
||||
typedef detail::thread::scoped_timed_lock<
|
||||
recursive_timed_mutex> scoped_timed_lock;
|
||||
|
||||
recursive_timed_mutex();
|
||||
recursive_timed_mutex(const char* name=0);
|
||||
~recursive_timed_mutex();
|
||||
|
||||
private:
|
||||
@@ -179,4 +183,4 @@ private:
|
||||
// 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.
|
||||
// 3 Jan 03 WEKEMPF Modified for DLL implementation.
|
||||
58
include/boost/thread/shared_memory.hpp
Normal file
58
include/boost/thread/shared_memory.hpp
Normal 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
|
||||
@@ -14,9 +14,9 @@
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
@@ -31,56 +31,163 @@ namespace boost {
|
||||
|
||||
struct xtime;
|
||||
|
||||
class BOOST_THREAD_DECL thread : private noncopyable
|
||||
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);
|
||||
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();
|
||||
|
||||
private:
|
||||
static const int stack_min;
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
void* m_thread;
|
||||
unsigned int m_id;
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
private:
|
||||
pthread_t m_thread;
|
||||
#elif defined(BOOST_HAS_MPTASKS)
|
||||
MPQueueID m_pJoinQueueID;
|
||||
MPTaskID m_pTaskID;
|
||||
typedef unsigned int id_type;
|
||||
#else
|
||||
typedef const void* id_type;
|
||||
#endif
|
||||
bool m_joinable;
|
||||
|
||||
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 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;
|
||||
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.
|
||||
|
||||
#endif // BOOST_THREAD_WEK070601_HPP
|
||||
|
||||
44
include/boost/thread/thread_pool.hpp
Normal file
44
include/boost/thread/thread_pool.hpp
Normal 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
|
||||
@@ -118,4 +118,4 @@ private:
|
||||
// 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().
|
||||
// reset()/release() and once on ~thread_specific_ptr().
|
||||
@@ -33,27 +33,26 @@ enum xtime_clock_types
|
||||
struct xtime
|
||||
{
|
||||
#if defined(BOOST_NO_INT64_T)
|
||||
typedef int_fast32_t xtime_sec_t; //INT_FAST32_MIN <= sec <= INT_FAST32_MAX
|
||||
int_fast32_t sec;
|
||||
#else
|
||||
typedef int_fast64_t xtime_sec_t; //INT_FAST64_MIN <= sec <= INT_FAST64_MAX
|
||||
int_fast64_t sec;
|
||||
#endif
|
||||
|
||||
typedef int_fast32_t xtime_nsec_t; //0 <= xtime.nsec < NANOSECONDS_PER_SECOND
|
||||
|
||||
xtime_sec_t sec;
|
||||
xtime_nsec_t nsec;
|
||||
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)
|
||||
{
|
||||
if (xt1.sec == xt2.sec)
|
||||
return (int)(xt1.nsec - xt2.nsec);
|
||||
else
|
||||
return (xt1.sec > xt2.sec) ? 1 : -1;
|
||||
int res = (int)(xt1.sec - xt2.sec);
|
||||
if (res == 0)
|
||||
res = (int)(xt1.nsec - xt2.nsec);
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif //BOOST_XTIME_WEK070601_HPP
|
||||
// Change Log:
|
||||
// 8 Feb 01 WEKEMPF Initial version.
|
||||
|
||||
#endif // BOOST_XTIME_WEK070601_HPP
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; URL=../../doc/html/threads.html">
|
||||
<meta http-equiv="refresh" content="0; URL=doc/index.html">
|
||||
</head>
|
||||
<body>
|
||||
Automatic redirection failed, please go to <a href="../../doc/html/threads.html">../../doc/html/threads.html</a>
|
||||
Automatic redirection failed, please go to <a href="doc/index.html">doc/index.html</a>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
@@ -10,8 +10,9 @@
|
||||
// It is provided "as is" without express or implied warranty.
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#include <boost/thread/barrier.hpp>
|
||||
#include <string> // see http://article.gmane.org/gmane.comp.lib.boost.devel/106981
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -39,6 +40,7 @@ bool barrier::wait()
|
||||
return true;
|
||||
}
|
||||
|
||||
boost::cancellation_guard guard;
|
||||
while (gen == m_generation)
|
||||
m_cond.wait(lock);
|
||||
return false;
|
||||
|
||||
@@ -82,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)
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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"
|
||||
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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"
|
||||
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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>
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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 "init.hpp"
|
||||
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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_INIT_MJM012402_HPP
|
||||
#define BOOST_INIT_MJM012402_HPP
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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 <cassert>
|
||||
#include <cstdio>
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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.
|
||||
|
||||
//
|
||||
// includes
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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.
|
||||
|
||||
//
|
||||
// includes
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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.
|
||||
|
||||
//
|
||||
// includes
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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 <cassert>
|
||||
// we include timesize.mac.h to get whether or not __TIMESIZE_DOUBLE__ is
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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 "os.hpp"
|
||||
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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_OS_MJM012402_HPP
|
||||
#define BOOST_OS_MJM012402_HPP
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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 "ot_context.hpp"
|
||||
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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_OT_CONTEXT_MJM012402_HPP
|
||||
#define BOOST_OT_CONTEXT_MJM012402_HPP
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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_PACKAGE_MJM012402_HPP
|
||||
#define BOOST_PACKAGE_MJM012402_HPP
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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_PERIODICAL_MJM012402_HPP
|
||||
#define BOOST_PERIODICAL_MJM012402_HPP
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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 NDEBUG
|
||||
#define TARGET_CARBON 1
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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 "remote_call_manager.hpp"
|
||||
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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_REMOTE_CALL_MANAGER_MJM012402_HPP
|
||||
#define BOOST_REMOTE_CALL_MANAGER_MJM012402_HPP
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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_REMOTE_CALLS_MJM012402_HPP
|
||||
#define BOOST_REMOTE_CALLS_MJM012402_HPP
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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 <DriverServices.h>
|
||||
#include <Events.h>
|
||||
@@ -165,7 +171,7 @@ OSStatus safe_wait(function<OSStatus, Duration> &rFunction, Duration lDuration)
|
||||
// get the expiration time in UpTime units
|
||||
if(lDuration == kDurationForever)
|
||||
{
|
||||
ullExpiration = (::std::numeric_limits<uint64_t>::max)();
|
||||
ullExpiration = ::std::numeric_limits<uint64_t>::max();
|
||||
}
|
||||
else if(lDuration == kDurationImmediate)
|
||||
{
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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_SAFE_MJM012402_HPP
|
||||
#define BOOST_SAFE_MJM012402_HPP
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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 "scoped_critical_region.hpp"
|
||||
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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_SCOPED_CRITICAL_REGION_MJM012402_HPP
|
||||
#define BOOST_SCOPED_CRITICAL_REGION_MJM012402_HPP
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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 "st_scheduler.hpp"
|
||||
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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_ST_SCHEDULER_MJM012402_HPP
|
||||
#define BOOST_ST_SCHEDULER_MJM012402_HPP
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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 "thread_cleanup.hpp"
|
||||
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
// 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_THREAD_CLEANUP_MJM012402_HPP
|
||||
#define BOOST_THREAD_CLEANUP_MJM012402_HPP
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/thread/exceptions.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <cassert>
|
||||
#include "timeconv.inl"
|
||||
@@ -39,15 +38,16 @@ namespace boost {
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
|
||||
mutex::mutex()
|
||||
: m_mutex(0)
|
||||
mutex::mutex(const char* name)
|
||||
: boost::detail::named_object(name)
|
||||
, m_mutex(0)
|
||||
, m_critical_section(false)
|
||||
{
|
||||
m_critical_section = true;
|
||||
m_critical_section = !name;
|
||||
if (m_critical_section)
|
||||
m_mutex = new_critical_section();
|
||||
else
|
||||
m_mutex = new_mutex(0);
|
||||
m_mutex = new_mutex(effective_name()); //:add special name that creates a mutex instead of a critical section, but doesn't name the mutex?
|
||||
}
|
||||
|
||||
mutex::~mutex()
|
||||
@@ -84,15 +84,16 @@ void mutex::do_unlock(cv_state&)
|
||||
do_unlock();
|
||||
}
|
||||
|
||||
try_mutex::try_mutex()
|
||||
: m_mutex(0)
|
||||
try_mutex::try_mutex(const char* name)
|
||||
: boost::detail::named_object(name)
|
||||
, m_mutex(0)
|
||||
, m_critical_section(false)
|
||||
{
|
||||
m_critical_section = has_TryEnterCriticalSection();
|
||||
m_critical_section = !name && has_TryEnterCriticalSection();
|
||||
if (m_critical_section)
|
||||
m_mutex = new_critical_section();
|
||||
else
|
||||
m_mutex = new_mutex(0);
|
||||
m_mutex = new_mutex(effective_name());
|
||||
}
|
||||
|
||||
try_mutex::~try_mutex()
|
||||
@@ -137,10 +138,11 @@ void try_mutex::do_unlock(cv_state&)
|
||||
do_unlock();
|
||||
}
|
||||
|
||||
timed_mutex::timed_mutex()
|
||||
: m_mutex(0)
|
||||
timed_mutex::timed_mutex(const char* name)
|
||||
: boost::detail::named_object(name)
|
||||
, m_mutex(0)
|
||||
{
|
||||
m_mutex = new_mutex(0);
|
||||
m_mutex = new_mutex(effective_name());
|
||||
}
|
||||
|
||||
timed_mutex::~timed_mutex()
|
||||
@@ -196,8 +198,10 @@ void timed_mutex::do_unlock(cv_state&)
|
||||
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
|
||||
mutex::mutex()
|
||||
mutex::mutex(const char* name)
|
||||
{
|
||||
//:Use name parameter
|
||||
|
||||
int res = 0;
|
||||
res = pthread_mutex_init(&m_mutex, 0);
|
||||
if (res != 0)
|
||||
@@ -236,8 +240,10 @@ void mutex::do_unlock(cv_state& state)
|
||||
state.pmutex = &m_mutex;
|
||||
}
|
||||
|
||||
try_mutex::try_mutex()
|
||||
try_mutex::try_mutex(const char* name)
|
||||
{
|
||||
//:Use name parameter
|
||||
|
||||
int res = 0;
|
||||
res = pthread_mutex_init(&m_mutex, 0);
|
||||
if (res != 0)
|
||||
@@ -285,9 +291,11 @@ void try_mutex::do_unlock(cv_state& state)
|
||||
state.pmutex = &m_mutex;
|
||||
}
|
||||
|
||||
timed_mutex::timed_mutex()
|
||||
timed_mutex::timed_mutex(const char* name)
|
||||
: m_locked(false)
|
||||
{
|
||||
//:Use name parameter
|
||||
|
||||
int res = 0;
|
||||
res = pthread_mutex_init(&m_mutex, 0);
|
||||
if (res != 0)
|
||||
@@ -430,8 +438,9 @@ void timed_mutex::do_unlock(cv_state& state)
|
||||
|
||||
using threads::mac::detail::safe_enter_critical_region;
|
||||
|
||||
mutex::mutex()
|
||||
mutex::mutex(const char* name)
|
||||
{
|
||||
//:Use name parameter
|
||||
}
|
||||
|
||||
mutex::~mutex()
|
||||
@@ -463,8 +472,9 @@ void mutex::do_unlock(cv_state& /*state*/)
|
||||
do_unlock();
|
||||
}
|
||||
|
||||
try_mutex::try_mutex()
|
||||
try_mutex::try_mutex(const char* name)
|
||||
{
|
||||
//:Use name parameter
|
||||
}
|
||||
|
||||
try_mutex::~try_mutex()
|
||||
@@ -504,8 +514,9 @@ void try_mutex::do_unlock(cv_state& /*state*/)
|
||||
do_unlock();
|
||||
}
|
||||
|
||||
timed_mutex::timed_mutex()
|
||||
timed_mutex::timed_mutex(const char* name)
|
||||
{
|
||||
//:Use name parameter
|
||||
}
|
||||
|
||||
timed_mutex::~timed_mutex()
|
||||
|
||||
248
src/mutex.inl
248
src/mutex.inl
@@ -1,124 +1,124 @@
|
||||
// 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.
|
||||
|
||||
namespace {
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
//:PREVENT THIS FROM BEING DUPLICATED
|
||||
typedef BOOL (WINAPI* TryEnterCriticalSection_type)(LPCRITICAL_SECTION lpCriticalSection);
|
||||
TryEnterCriticalSection_type g_TryEnterCriticalSection = 0;
|
||||
boost::once_flag once_init_TryEnterCriticalSection = BOOST_ONCE_INIT;
|
||||
|
||||
void init_TryEnterCriticalSection()
|
||||
{
|
||||
//TryEnterCriticalSection is only available on WinNT 4.0 or later;
|
||||
//it is not available on Win9x.
|
||||
|
||||
OSVERSIONINFO version_info = {sizeof(OSVERSIONINFO)};
|
||||
::GetVersionEx(&version_info);
|
||||
if (version_info.dwPlatformId == VER_PLATFORM_WIN32_NT &&
|
||||
version_info.dwMajorVersion >= 4)
|
||||
{
|
||||
if (HMODULE kernel_module = GetModuleHandle(TEXT("KERNEL32.DLL")))
|
||||
g_TryEnterCriticalSection = reinterpret_cast<TryEnterCriticalSection_type>(GetProcAddress(kernel_module, "TryEnterCriticalSection"));
|
||||
}
|
||||
}
|
||||
|
||||
inline bool has_TryEnterCriticalSection()
|
||||
{
|
||||
boost::call_once(init_TryEnterCriticalSection, once_init_TryEnterCriticalSection);
|
||||
return g_TryEnterCriticalSection != 0;
|
||||
}
|
||||
|
||||
inline HANDLE mutex_cast(void* p)
|
||||
{
|
||||
return reinterpret_cast<HANDLE>(p);
|
||||
}
|
||||
|
||||
inline LPCRITICAL_SECTION critical_section_cast(void* p)
|
||||
{
|
||||
return reinterpret_cast<LPCRITICAL_SECTION>(p);
|
||||
}
|
||||
|
||||
inline void* new_critical_section()
|
||||
{
|
||||
try
|
||||
{
|
||||
LPCRITICAL_SECTION critical_section = new CRITICAL_SECTION;
|
||||
if (critical_section == 0) throw boost::thread_resource_error();
|
||||
InitializeCriticalSection(critical_section);
|
||||
return critical_section;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
throw boost::thread_resource_error();
|
||||
}
|
||||
}
|
||||
|
||||
inline void* new_mutex(const char* name)
|
||||
{
|
||||
#if defined(BOOST_NO_ANSI_APIS)
|
||||
USES_CONVERSION;
|
||||
HANDLE mutex = CreateMutexW(0, 0, A2CW(name));
|
||||
#else
|
||||
HANDLE mutex = CreateMutexA(0, 0, name);
|
||||
#endif
|
||||
if (mutex == 0 || mutex == INVALID_HANDLE_VALUE) //:xxx (check for both values?)
|
||||
throw boost::thread_resource_error();
|
||||
return reinterpret_cast<void*>(mutex);
|
||||
}
|
||||
|
||||
inline void delete_critical_section(void* mutex)
|
||||
{
|
||||
DeleteCriticalSection(critical_section_cast(mutex));
|
||||
delete critical_section_cast(mutex);
|
||||
}
|
||||
|
||||
inline void delete_mutex(void* mutex)
|
||||
{
|
||||
int res = 0;
|
||||
res = CloseHandle(mutex_cast(mutex));
|
||||
assert(res);
|
||||
}
|
||||
|
||||
inline void wait_critical_section_infinite(void* mutex)
|
||||
{
|
||||
EnterCriticalSection(critical_section_cast(mutex)); //:xxx Can throw an exception under low memory conditions
|
||||
}
|
||||
|
||||
inline bool wait_critical_section_try(void* mutex)
|
||||
{
|
||||
BOOL res = g_TryEnterCriticalSection(critical_section_cast(mutex));
|
||||
return res != 0;
|
||||
}
|
||||
|
||||
inline int wait_mutex(void* mutex, int time)
|
||||
{
|
||||
unsigned int res = 0;
|
||||
res = WaitForSingleObject(mutex_cast(mutex), time);
|
||||
//:xxx assert(res != WAIT_FAILED && res != WAIT_ABANDONED);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline void release_critical_section(void* mutex)
|
||||
{
|
||||
LeaveCriticalSection(critical_section_cast(mutex));
|
||||
}
|
||||
|
||||
inline void release_mutex(void* mutex)
|
||||
{
|
||||
BOOL res = FALSE;
|
||||
res = ReleaseMutex(mutex_cast(mutex));
|
||||
assert(res);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
// 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.
|
||||
|
||||
namespace {
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
//:PREVENT THIS FROM BEING DUPLICATED
|
||||
typedef BOOL (WINAPI* TryEnterCriticalSection_type)(LPCRITICAL_SECTION lpCriticalSection);
|
||||
TryEnterCriticalSection_type g_TryEnterCriticalSection = 0;
|
||||
boost::once_flag once_init_TryEnterCriticalSection = BOOST_ONCE_INIT;
|
||||
|
||||
void init_TryEnterCriticalSection()
|
||||
{
|
||||
//TryEnterCriticalSection is only available on WinNT 4.0 or later;
|
||||
//it is not available on Win9x.
|
||||
|
||||
OSVERSIONINFO version_info = {sizeof(OSVERSIONINFO)};
|
||||
::GetVersionEx(&version_info);
|
||||
if (version_info.dwPlatformId == VER_PLATFORM_WIN32_NT &&
|
||||
version_info.dwMajorVersion >= 4)
|
||||
{
|
||||
if (HMODULE kernel_module = GetModuleHandle(TEXT("KERNEL32.DLL")))
|
||||
g_TryEnterCriticalSection = reinterpret_cast<TryEnterCriticalSection_type>(GetProcAddress(kernel_module, "TryEnterCriticalSection"));
|
||||
}
|
||||
}
|
||||
|
||||
inline bool has_TryEnterCriticalSection()
|
||||
{
|
||||
boost::call_once(init_TryEnterCriticalSection, once_init_TryEnterCriticalSection);
|
||||
return g_TryEnterCriticalSection != 0;
|
||||
}
|
||||
|
||||
inline HANDLE mutex_cast(void* p)
|
||||
{
|
||||
return reinterpret_cast<HANDLE>(p);
|
||||
}
|
||||
|
||||
inline LPCRITICAL_SECTION critical_section_cast(void* p)
|
||||
{
|
||||
return reinterpret_cast<LPCRITICAL_SECTION>(p);
|
||||
}
|
||||
|
||||
inline void* new_critical_section()
|
||||
{
|
||||
try
|
||||
{
|
||||
LPCRITICAL_SECTION critical_section = new CRITICAL_SECTION;
|
||||
if (critical_section == 0) throw boost::thread_resource_error();
|
||||
InitializeCriticalSection(critical_section);
|
||||
return critical_section;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
throw boost::thread_resource_error();
|
||||
}
|
||||
}
|
||||
|
||||
inline void* new_mutex(const char* name)
|
||||
{
|
||||
#if defined(BOOST_NO_ANSI_APIS)
|
||||
USES_CONVERSION;
|
||||
HANDLE mutex = CreateMutexW(0, 0, A2CW(name));
|
||||
#else
|
||||
HANDLE mutex = CreateMutexA(0, 0, name);
|
||||
#endif
|
||||
if (mutex == 0 || mutex == INVALID_HANDLE_VALUE) //:xxx (check for both values?)
|
||||
throw boost::thread_resource_error();
|
||||
return reinterpret_cast<void*>(mutex);
|
||||
}
|
||||
|
||||
inline void delete_critical_section(void* mutex)
|
||||
{
|
||||
DeleteCriticalSection(critical_section_cast(mutex));
|
||||
delete critical_section_cast(mutex);
|
||||
}
|
||||
|
||||
inline void delete_mutex(void* mutex)
|
||||
{
|
||||
int res = 0;
|
||||
res = CloseHandle(mutex_cast(mutex));
|
||||
assert(res);
|
||||
}
|
||||
|
||||
inline void wait_critical_section_infinite(void* mutex)
|
||||
{
|
||||
EnterCriticalSection(critical_section_cast(mutex)); //:xxx Can throw an exception under low memory conditions
|
||||
}
|
||||
|
||||
inline bool wait_critical_section_try(void* mutex)
|
||||
{
|
||||
BOOL res = g_TryEnterCriticalSection(critical_section_cast(mutex));
|
||||
return res != 0;
|
||||
}
|
||||
|
||||
inline int wait_mutex(void* mutex, int time)
|
||||
{
|
||||
unsigned int res = 0;
|
||||
res = WaitForSingleObject(mutex_cast(mutex), time);
|
||||
//:xxx assert(res != WAIT_FAILED && res != WAIT_ABANDONED);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline void release_critical_section(void* mutex)
|
||||
{
|
||||
LeaveCriticalSection(critical_section_cast(mutex));
|
||||
}
|
||||
|
||||
inline void release_mutex(void* mutex)
|
||||
{
|
||||
BOOL res = FALSE;
|
||||
res = ReleaseMutex(mutex_cast(mutex));
|
||||
assert(res);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
135
src/named.cpp
Normal file
135
src/named.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
// 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/detail/named.hpp>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
namespace {
|
||||
|
||||
char* concat(char* result, const char* buf)
|
||||
{
|
||||
if (result == 0)
|
||||
return strdup(buf);
|
||||
|
||||
int len = strlen(result) + strlen(buf) + 1;
|
||||
result = (char*)realloc(result, len);
|
||||
strcat(result, buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
char* get_root()
|
||||
{
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
return "";
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
return "/";
|
||||
#else
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
|
||||
char* encode(const char* str)
|
||||
{
|
||||
const char* digits="0123456789abcdef";
|
||||
char* result=0;
|
||||
static char buf[100];
|
||||
char* ebuf = buf + 100;
|
||||
char* p = buf;
|
||||
*p = 0;
|
||||
strcat(p, get_root());
|
||||
p = p + strlen(p);
|
||||
while (*str)
|
||||
{
|
||||
if (((*str >= '0') && (*str <= '9')) ||
|
||||
((*str >= 'a') && (*str <= 'z')) ||
|
||||
((*str >= 'A') && (*str <= 'Z')) ||
|
||||
(*str == '/') || (*str == '.') || (*str == '_'))
|
||||
{
|
||||
*p = *str;
|
||||
}
|
||||
else if (*str == ' ')
|
||||
{
|
||||
*p = '+';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p + 3 >= ebuf)
|
||||
{
|
||||
*p = 0;
|
||||
result = concat(result, buf);
|
||||
p = buf;
|
||||
}
|
||||
*p = '%';
|
||||
char* e = p + 2;
|
||||
int v = *str;
|
||||
while (e > p)
|
||||
{
|
||||
*e-- = digits[v % 16];
|
||||
v /= 16;
|
||||
}
|
||||
p += 2;
|
||||
}
|
||||
if (++p == ebuf)
|
||||
{
|
||||
*p = 0;
|
||||
result = concat(result, buf);
|
||||
p = buf;
|
||||
}
|
||||
++str;
|
||||
}
|
||||
*p = 0;
|
||||
result = concat(result, buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
|
||||
named_object::named_object(const char* name)
|
||||
: m_name(0), m_ename(0)
|
||||
{
|
||||
if (name)
|
||||
{
|
||||
m_name = strdup(name);
|
||||
if (*m_name == '%')
|
||||
m_ename = m_name + 1;
|
||||
else
|
||||
m_ename = encode(name);
|
||||
}
|
||||
}
|
||||
|
||||
named_object::~named_object()
|
||||
{
|
||||
if (m_name)
|
||||
{
|
||||
if (*m_name != '%')
|
||||
free(m_ename);
|
||||
free(m_name);
|
||||
}
|
||||
}
|
||||
|
||||
const char* named_object::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const char* named_object::effective_name() const
|
||||
{
|
||||
return m_ename;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
@@ -178,12 +178,10 @@ void read_write_mutex_impl<Mutex>::do_write_lock()
|
||||
}
|
||||
else if (m_sp == read_write_scheduling_policy::writer_priority)
|
||||
{
|
||||
//Shut down extra readers that were scheduled only because of no waiting writers
|
||||
//Writer priority: wait while locked
|
||||
|
||||
m_num_readers_to_wake = 0;
|
||||
|
||||
//Writer priority: wait while locked
|
||||
|
||||
int loop_count = 0;
|
||||
while (m_state != 0)
|
||||
{
|
||||
@@ -344,7 +342,7 @@ bool read_write_mutex_impl<Mutex>::do_timed_read_lock(const boost::xtime &xt)
|
||||
if (!l.locked())
|
||||
return false;
|
||||
|
||||
bool fail = false;
|
||||
bool fail;
|
||||
|
||||
if (m_sp == read_write_scheduling_policy::reader_priority)
|
||||
{
|
||||
@@ -424,28 +422,11 @@ bool read_write_mutex_impl<Mutex>::do_timed_read_lock(const boost::xtime &xt)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_num_readers_to_wake > 0)
|
||||
{
|
||||
//If there were readers scheduled to wake,
|
||||
//decrement the number in case we were that reader.
|
||||
//If only one was scheduled to wake, the scheduling
|
||||
//algorithm will schedule another if one is available;
|
||||
//if more than one, one fewer reader will run before
|
||||
//the scheduling algorithm is called again. This last
|
||||
//case is not ideal, especially if a lot of waiting
|
||||
//readers timeout, but without knowing whether
|
||||
//we were actually one of the readers that was
|
||||
//scheduled to wake it's difficult to come up
|
||||
//with a better plan.
|
||||
--m_num_readers_to_wake;
|
||||
}
|
||||
BOOST_ASSERT(valid_write_lock(m_state) || m_num_waiting_writers > 0);
|
||||
//Should be write-locked or
|
||||
//writer should be waiting
|
||||
|
||||
if (m_state == 0)
|
||||
{
|
||||
//If there is no thread with a lock that will
|
||||
//call do_scheduling_impl() when it unlocks, call it ourselves
|
||||
do_timeout_scheduling_impl();
|
||||
}
|
||||
//:Call do_xxx_scheduling_impl() in case we were the scheduled thread and we timed out?
|
||||
}
|
||||
|
||||
return !fail;
|
||||
@@ -460,7 +441,7 @@ bool read_write_mutex_impl<Mutex>::do_timed_write_lock(const boost::xtime &xt)
|
||||
if (!l.locked())
|
||||
return false;
|
||||
|
||||
bool fail = false;
|
||||
bool fail;
|
||||
|
||||
if (m_sp == read_write_scheduling_policy::reader_priority)
|
||||
{
|
||||
@@ -482,12 +463,10 @@ bool read_write_mutex_impl<Mutex>::do_timed_write_lock(const boost::xtime &xt)
|
||||
}
|
||||
else if (m_sp == read_write_scheduling_policy::writer_priority)
|
||||
{
|
||||
//Shut down extra readers that were scheduled only because of no waiting writers
|
||||
//Writer priority: wait while locked
|
||||
|
||||
m_num_readers_to_wake = 0;
|
||||
|
||||
//Writer priority: wait while locked
|
||||
|
||||
int loop_count = 0;
|
||||
while (m_state != 0)
|
||||
{
|
||||
@@ -543,12 +522,11 @@ bool read_write_mutex_impl<Mutex>::do_timed_write_lock(const boost::xtime &xt)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_state == 0)
|
||||
{
|
||||
//If there is no thread with a lock that will
|
||||
//call do_scheduling_impl() when it unlocks, call it ourselves
|
||||
do_timeout_scheduling_impl();
|
||||
}
|
||||
BOOST_ASSERT(valid_read_write_lock(m_state) || m_num_readers_to_wake > 0);
|
||||
//Should be read-locked or write-locked, or
|
||||
//reader should be waking
|
||||
|
||||
//:Call do_xxx_scheduling_impl() in case we were the scheduled thread and we timed out?
|
||||
}
|
||||
|
||||
return !fail;
|
||||
@@ -831,13 +809,6 @@ void read_write_mutex_impl<Mutex>::do_unlock_scheduling_impl()
|
||||
do_scheduling_impl();
|
||||
}
|
||||
|
||||
template<typename Mutex>
|
||||
void read_write_mutex_impl<Mutex>::do_timeout_scheduling_impl()
|
||||
{
|
||||
BOOST_ASSERT(m_state == 0);
|
||||
do_scheduling_impl();
|
||||
}
|
||||
|
||||
template<typename Mutex>
|
||||
void read_write_mutex_impl<Mutex>::do_demote_scheduling_impl()
|
||||
{
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <boost/thread/xtime.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <cassert>
|
||||
#include "timeconv.inl"
|
||||
@@ -37,16 +36,17 @@ namespace boost {
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
|
||||
recursive_mutex::recursive_mutex()
|
||||
: m_mutex(0)
|
||||
, m_critical_section(false)
|
||||
recursive_mutex::recursive_mutex(const char* name)
|
||||
: boost::detail::named_object(name)
|
||||
, m_mutex(0)
|
||||
, m_count(0)
|
||||
, m_critical_section(false)
|
||||
{
|
||||
m_critical_section = true;
|
||||
m_critical_section = !name;
|
||||
if (m_critical_section)
|
||||
m_mutex = new_critical_section();
|
||||
else
|
||||
m_mutex = new_mutex(0);
|
||||
m_mutex = new_mutex(effective_name()); //:add special name that creates a mutex instead of a critical section, but doesn't name the mutex?
|
||||
}
|
||||
|
||||
recursive_mutex::~recursive_mutex()
|
||||
@@ -105,16 +105,17 @@ void recursive_mutex::do_unlock(cv_state& state)
|
||||
release_mutex(m_mutex);
|
||||
}
|
||||
|
||||
recursive_try_mutex::recursive_try_mutex()
|
||||
: m_mutex(0)
|
||||
, m_critical_section(false)
|
||||
recursive_try_mutex::recursive_try_mutex(const char* name)
|
||||
: boost::detail::named_object(name)
|
||||
, m_mutex(0)
|
||||
, m_count(0)
|
||||
, m_critical_section(false)
|
||||
{
|
||||
m_critical_section = has_TryEnterCriticalSection();
|
||||
m_critical_section = !name && has_TryEnterCriticalSection();
|
||||
if (m_critical_section)
|
||||
m_mutex = new_critical_section();
|
||||
else
|
||||
m_mutex = new_mutex(0);
|
||||
m_mutex = new_mutex(effective_name());
|
||||
}
|
||||
|
||||
recursive_try_mutex::~recursive_try_mutex()
|
||||
@@ -195,11 +196,12 @@ void recursive_try_mutex::do_unlock(cv_state& state)
|
||||
release_mutex(m_mutex);
|
||||
}
|
||||
|
||||
recursive_timed_mutex::recursive_timed_mutex()
|
||||
: m_mutex(0)
|
||||
recursive_timed_mutex::recursive_timed_mutex(const char* name)
|
||||
: boost::detail::named_object(name)
|
||||
, m_mutex(0)
|
||||
, m_count(0)
|
||||
{
|
||||
m_mutex = new_mutex(0);
|
||||
m_mutex = new_mutex(effective_name());
|
||||
}
|
||||
|
||||
recursive_timed_mutex::~recursive_timed_mutex()
|
||||
@@ -279,12 +281,14 @@ void recursive_timed_mutex::do_unlock(cv_state& state)
|
||||
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
|
||||
recursive_mutex::recursive_mutex()
|
||||
recursive_mutex::recursive_mutex(const char* name)
|
||||
: m_count(0)
|
||||
# if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
|
||||
, m_valid_id(false)
|
||||
# endif
|
||||
{
|
||||
//:Use name parameter
|
||||
|
||||
pthread_mutexattr_t attr;
|
||||
int res = pthread_mutexattr_init(&attr);
|
||||
assert(res == 0);
|
||||
@@ -432,15 +436,16 @@ void recursive_mutex::do_unlock(cv_state& state)
|
||||
|
||||
state.pmutex = &m_mutex;
|
||||
state.count = m_count;
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
recursive_try_mutex::recursive_try_mutex()
|
||||
recursive_try_mutex::recursive_try_mutex(const char* name)
|
||||
: m_count(0)
|
||||
# if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
|
||||
, m_valid_id(false)
|
||||
# endif
|
||||
{
|
||||
//:Use name parameter
|
||||
|
||||
pthread_mutexattr_t attr;
|
||||
int res = pthread_mutexattr_init(&attr);
|
||||
assert(res == 0);
|
||||
@@ -632,12 +637,13 @@ void recursive_try_mutex::do_unlock(cv_state& state)
|
||||
|
||||
state.pmutex = &m_mutex;
|
||||
state.count = m_count;
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
recursive_timed_mutex::recursive_timed_mutex()
|
||||
recursive_timed_mutex::recursive_timed_mutex(const char* name)
|
||||
: m_valid_id(false), m_count(0)
|
||||
{
|
||||
//:Use name parameter
|
||||
|
||||
int res = 0;
|
||||
res = pthread_mutex_init(&m_mutex, 0);
|
||||
if (res != 0)
|
||||
@@ -812,16 +818,17 @@ void recursive_timed_mutex::do_unlock(cv_state& state)
|
||||
|
||||
state.pmutex = &m_mutex;
|
||||
state.count = m_count;
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
#elif defined(BOOST_HAS_MPTASKS)
|
||||
|
||||
using threads::mac::detail::safe_enter_critical_region;
|
||||
|
||||
|
||||
recursive_mutex::recursive_mutex()
|
||||
recursive_mutex::recursive_mutex(const char* name)
|
||||
: m_count(0)
|
||||
{
|
||||
//:Use name parameter
|
||||
}
|
||||
|
||||
recursive_mutex::~recursive_mutex()
|
||||
@@ -872,9 +879,10 @@ void recursive_mutex::do_unlock(cv_state& state)
|
||||
assert(lStatus == noErr);
|
||||
}
|
||||
|
||||
recursive_try_mutex::recursive_try_mutex()
|
||||
recursive_try_mutex::recursive_try_mutex(const char* name)
|
||||
: m_count(0)
|
||||
{
|
||||
//:Use name parameter
|
||||
}
|
||||
|
||||
recursive_try_mutex::~recursive_try_mutex()
|
||||
@@ -943,9 +951,10 @@ void recursive_try_mutex::do_unlock(cv_state& state)
|
||||
assert(lStatus == noErr);
|
||||
}
|
||||
|
||||
recursive_timed_mutex::recursive_timed_mutex()
|
||||
recursive_timed_mutex::recursive_timed_mutex(const char* name)
|
||||
: m_count(0)
|
||||
{
|
||||
//:Use name parameter
|
||||
}
|
||||
|
||||
recursive_timed_mutex::~recursive_timed_mutex()
|
||||
@@ -1035,6 +1044,7 @@ void recursive_timed_mutex::do_unlock(cv_state& state)
|
||||
lStatus = MPExitCriticalRegion(m_mutex);
|
||||
assert(lStatus == noErr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
191
src/shared_memory.cpp
Normal file
191
src/shared_memory.cpp
Normal file
@@ -0,0 +1,191 @@
|
||||
// Copyright (C) 2002
|
||||
// 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.
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#include <boost/thread/shared_memory.hpp>
|
||||
#include <boost/thread/once.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
|
||||
// Next line should really be BOOST_HAS_POSIX_xxx
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
|
||||
//#include <sys/shm.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
shared_memory::shared_memory(const char *name, size_t len, int flags)
|
||||
: boost::detail::named_object(name)
|
||||
{
|
||||
init(len, flags, 0);
|
||||
}
|
||||
|
||||
shared_memory::shared_memory(const char *name, size_t len, int flags,
|
||||
const boost::function1<void, void *>& initfunc)
|
||||
: boost::detail::named_object(name)
|
||||
{
|
||||
init(len, flags & create, &initfunc);
|
||||
}
|
||||
|
||||
shared_memory::~shared_memory()
|
||||
{
|
||||
if (m_ptr)
|
||||
{
|
||||
int res = 0;
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
res = UnmapViewOfFile(m_ptr);
|
||||
assert(res);
|
||||
res = CloseHandle(reinterpret_cast<HANDLE>(m_hmap));
|
||||
assert(res);
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
res = munmap(reinterpret_cast<char*>(m_ptr), m_len);
|
||||
assert(res == 0);
|
||||
res = close(m_hmap);
|
||||
assert(res == 0);
|
||||
res = shm_unlink(effective_name());
|
||||
assert(res == 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void shared_memory::init(size_t len, int flags,
|
||||
const boost::function1<void,void *>* initfunc)
|
||||
{
|
||||
int res = 0;
|
||||
bool should_init = false;
|
||||
|
||||
std::string ename = effective_name();
|
||||
std::string mxname = ename + "mx94543CBD1523443dB128451E51B5103E";
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
HANDLE mutex = CreateMutexA(0, FALSE, mxname.c_str());
|
||||
if (mutex == INVALID_HANDLE_VALUE)
|
||||
throw thread_resource_error();
|
||||
res = WaitForSingleObject(mutex, INFINITE);
|
||||
assert(res == WAIT_OBJECT_0);
|
||||
|
||||
if (flags & create)
|
||||
{
|
||||
DWORD protect = (flags & write) ? PAGE_READWRITE : PAGE_READONLY;
|
||||
m_hmap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, protect,
|
||||
0, len, ename.c_str());
|
||||
if (m_hmap == INVALID_HANDLE_VALUE ||
|
||||
((flags & exclusive) && GetLastError() == ERROR_ALREADY_EXISTS))
|
||||
{
|
||||
res = ReleaseMutex(mutex);
|
||||
assert(res);
|
||||
res = CloseHandle(mutex);
|
||||
assert(res);
|
||||
if (m_hmap != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
res = CloseHandle(m_hmap);
|
||||
assert(res);
|
||||
}
|
||||
throw thread_resource_error();
|
||||
}
|
||||
should_init = GetLastError() != ERROR_ALREADY_EXISTS;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD protect = (flags & write) ? FILE_MAP_WRITE : FILE_MAP_READ;
|
||||
m_hmap = OpenFileMapping(protect, FALSE, ename.c_str());
|
||||
if (m_hmap == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
res = ReleaseMutex(mutex);
|
||||
assert(res);
|
||||
res = CloseHandle(mutex);
|
||||
assert(res);
|
||||
throw thread_resource_error();
|
||||
}
|
||||
}
|
||||
m_ptr = MapViewOfFile(m_hmap, FILE_MAP_WRITE, 0, 0, 0);
|
||||
assert(m_ptr);
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
m_len = len;
|
||||
|
||||
sem_t* sem = sem_open(mxname.c_str(), O_CREAT);
|
||||
if (sem == SEM_FAILED)
|
||||
throw thread_resource_error();
|
||||
res = sem_wait(sem);
|
||||
assert(res == 0);
|
||||
|
||||
int oflag = (flags & write) ? O_RDWR : O_RDONLY;
|
||||
int cflag = (flags & create) ? O_CREAT|O_TRUNC|O_EXCL : 0;
|
||||
for (;;)
|
||||
{
|
||||
m_hmap = shm_open(m_name.c_str(), oflag|cflag, 0);
|
||||
if (m_hmap == -1)
|
||||
{
|
||||
if (errno != EEXIST || (flags & exclusive))
|
||||
{
|
||||
res = sem_post(sem);
|
||||
assert(res == 0);
|
||||
res = sem_close(sem);
|
||||
assert(res == 0);
|
||||
res = sem_unlink(mxname.c_str());
|
||||
assert(res);
|
||||
throw thread_resource_error();
|
||||
}
|
||||
m_hmap = shm_open(m_name.c_str(), oflag, 0);
|
||||
if (m_hmap == -1)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
continue;
|
||||
res = sem_post(sem);
|
||||
assert(res == 0);
|
||||
res = sem_close(sem);
|
||||
assert(res);
|
||||
res = sem_unlink(mxname.c_str());
|
||||
assert(res);
|
||||
throw thread_resource_error();
|
||||
}
|
||||
}
|
||||
else
|
||||
should_init = true;
|
||||
break;
|
||||
}
|
||||
|
||||
ftruncate(m_hmap, len);
|
||||
int prot = (flags & write) ? PROT_READ|PROT_WRITE : PROT_READ;
|
||||
m_ptr = mmap(0, m_len, prot, MAP_SHARED, m_hmap, 0);
|
||||
#endif
|
||||
|
||||
if (should_init && initfunc)
|
||||
(*initfunc)(m_ptr);
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
res = ReleaseMutex(mutex);
|
||||
assert(res);
|
||||
res = CloseHandle(mutex);
|
||||
assert(res);
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
res = sem_post(sem);
|
||||
assert(res == 0);
|
||||
res = sem_close(sem);
|
||||
assert(res == 0);
|
||||
res = sem_unlink(mxname.c_str());
|
||||
assert(res == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
882
src/thread.cpp
882
src/thread.cpp
File diff suppressed because it is too large
Load Diff
321
src/thread_pool.cpp
Normal file
321
src/thread_pool.cpp
Normal file
@@ -0,0 +1,321 @@
|
||||
// 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.
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#include <boost/thread/thread_pool.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/thread/condition.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/xtime.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <list>
|
||||
#include <queue>
|
||||
#include <stdexcept>
|
||||
#include <cassert>
|
||||
|
||||
namespace boost {
|
||||
|
||||
class thread_pool::impl
|
||||
{
|
||||
public:
|
||||
impl(int max_threads, int min_threads, int timeout_secs,
|
||||
int timeout_nsecs);
|
||||
~impl();
|
||||
|
||||
void add(const boost::function0<void> &job);
|
||||
void join();
|
||||
void cancel();
|
||||
void detach();
|
||||
void worker_harness();
|
||||
|
||||
private:
|
||||
typedef enum
|
||||
{
|
||||
RUNNING,
|
||||
CANCELLING,
|
||||
JOINING,
|
||||
JOINED,
|
||||
DETACHED
|
||||
} thread_pool_state;
|
||||
|
||||
typedef std::queue<boost::function0<void> > job_q;
|
||||
|
||||
condition m_more_work;
|
||||
condition m_done;
|
||||
mutex m_prot;
|
||||
job_q m_jobs;
|
||||
thread_group m_workers;
|
||||
thread_pool_state m_state;
|
||||
int m_max_threads; // Max threads allowed
|
||||
int m_min_threads;
|
||||
int m_thread_count; // Current number of threads
|
||||
int m_idle_count; // Number of idle threads
|
||||
int m_timeout_secs; // How long to keep idle threads
|
||||
int m_timeout_nsecs;
|
||||
};
|
||||
|
||||
thread_pool::impl::impl(int max_threads, int min_threads, int timeout_secs,
|
||||
int timeout_nsecs)
|
||||
: m_state(RUNNING), m_max_threads(max_threads), m_min_threads(min_threads),
|
||||
m_thread_count(0), m_idle_count(0), m_timeout_secs(timeout_secs),
|
||||
m_timeout_nsecs(timeout_nsecs)
|
||||
{
|
||||
// Immediately launch some worker threads.
|
||||
//
|
||||
// Not an exception safe implementation, yet.
|
||||
while (min_threads-- > 0)
|
||||
{
|
||||
m_workers.create_thread(
|
||||
bind(&thread_pool::impl::worker_harness, this));
|
||||
m_thread_count++;
|
||||
}
|
||||
}
|
||||
|
||||
thread_pool::impl::~impl()
|
||||
{
|
||||
// Join in the destructor, unless they have already
|
||||
// joined or detached.
|
||||
mutex::scoped_lock lock(m_prot);
|
||||
if (m_state == RUNNING)
|
||||
{
|
||||
lock.unlock();
|
||||
join();
|
||||
}
|
||||
}
|
||||
|
||||
void thread_pool::impl::add(const boost::function0<void> &job)
|
||||
{
|
||||
mutex::scoped_lock lock(m_prot);
|
||||
|
||||
// Note - can never reach this point if m_state == CANCELLED
|
||||
// because the m_prot is held during the entire cancel operation.
|
||||
|
||||
assert(m_state == RUNNING);
|
||||
|
||||
m_jobs.push(job);
|
||||
if (m_idle_count > 0)
|
||||
m_more_work.notify_one();
|
||||
else if (m_thread_count < m_max_threads)
|
||||
{
|
||||
// No idle threads, and we're below our limit. Spawn a new
|
||||
// worker.
|
||||
|
||||
// What we really need is thread::detach(), or "create suspended"
|
||||
m_workers.create_thread(
|
||||
bind(&thread_pool::impl::worker_harness, this));
|
||||
m_thread_count++;
|
||||
}
|
||||
}
|
||||
|
||||
void thread_pool::impl::join()
|
||||
{
|
||||
mutex::scoped_lock lock(m_prot);
|
||||
|
||||
assert(m_state == RUNNING);
|
||||
|
||||
if (m_thread_count > 0)
|
||||
{
|
||||
m_state = JOINING;
|
||||
|
||||
// if any threads are idling, wake them.
|
||||
if (m_idle_count > 0)
|
||||
m_more_work.notify_all();
|
||||
|
||||
// Track the shutdown progress of the threads.
|
||||
while (m_thread_count > 0)
|
||||
m_done.wait(lock);
|
||||
}
|
||||
|
||||
m_workers.join_all();
|
||||
m_state = JOINED;
|
||||
}
|
||||
|
||||
// This is a "weak" form of cancel which empties out the job queue and takes
|
||||
// the thread count down to zero.
|
||||
//
|
||||
// Upon receiving more work, the thread count would grow back up to
|
||||
// min_threads.
|
||||
//
|
||||
// Cancel will be much stronger once full thread cancellation is in place!
|
||||
|
||||
void thread_pool::impl::cancel()
|
||||
{
|
||||
mutex::scoped_lock lock(m_prot);
|
||||
|
||||
assert(m_state == RUNNING);
|
||||
|
||||
if (m_thread_count > 0)
|
||||
{
|
||||
m_state = CANCELLING;
|
||||
|
||||
// Cancelling kills any unexecuted jobs.
|
||||
while (!m_jobs.empty())
|
||||
m_jobs.pop();
|
||||
|
||||
/* If we had cancel, this would be something like....
|
||||
m_workers.cancel_all();
|
||||
while(m_cancel_count > 0)
|
||||
m_all_cancelled.wait(lock);
|
||||
*/
|
||||
}
|
||||
|
||||
m_state = RUNNING; // Go back to accepting work.
|
||||
}
|
||||
|
||||
void thread_pool::impl::detach()
|
||||
{
|
||||
mutex::scoped_lock lock(m_prot);
|
||||
if (m_state == RUNNING)
|
||||
{
|
||||
m_min_threads = 0;
|
||||
m_state = DETACHED;
|
||||
}
|
||||
else
|
||||
{
|
||||
// detach during/after a join has no effect - the join will
|
||||
// complete.
|
||||
}
|
||||
}
|
||||
|
||||
void thread_pool::impl::worker_harness()
|
||||
{
|
||||
boost::thread me;
|
||||
|
||||
xtime timeout;
|
||||
int timedout;
|
||||
|
||||
mutex::scoped_lock lock(m_prot);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
timedout = 0;
|
||||
|
||||
xtime_get(&timeout, boost::TIME_UTC);
|
||||
timeout.sec += m_timeout_secs;
|
||||
timeout.nsec += m_timeout_nsecs;
|
||||
|
||||
while (m_jobs.empty() && (m_state == RUNNING))
|
||||
{
|
||||
m_idle_count++;
|
||||
bool status = m_more_work.timed_wait(lock, timeout);
|
||||
m_idle_count--;
|
||||
if (!status)
|
||||
{
|
||||
timedout = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_jobs.empty() && m_state != CANCELLING)
|
||||
{
|
||||
boost::function0<void> jobfunc = m_jobs.front();
|
||||
m_jobs.pop();
|
||||
lock.unlock();
|
||||
jobfunc();
|
||||
lock.lock();
|
||||
}
|
||||
else if (m_jobs.empty() && m_state == JOINING)
|
||||
{
|
||||
m_thread_count--;
|
||||
|
||||
// If we are the last worker exiting, let everyone know about it!
|
||||
if (m_thread_count == 0)
|
||||
m_done.notify_all();
|
||||
|
||||
return;
|
||||
}
|
||||
else if (m_jobs.empty() && m_state == DETACHED)
|
||||
{
|
||||
m_thread_count--;
|
||||
|
||||
// If we are the last worker exiting, let everyone know about it!
|
||||
if (m_thread_count == 0)
|
||||
{
|
||||
lock.unlock();
|
||||
delete this;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there's no more work, and we wait for as long as
|
||||
* we're allowed, then terminate this server thread.
|
||||
*/
|
||||
if (m_jobs.empty() && timedout)
|
||||
{
|
||||
if (m_thread_count > m_min_threads)
|
||||
{
|
||||
m_thread_count--;
|
||||
|
||||
if (m_state == DETACHED &&
|
||||
m_thread_count == 0)
|
||||
{
|
||||
lock.unlock();
|
||||
delete this;
|
||||
return;
|
||||
}
|
||||
|
||||
// We aren't in a JOINING or CANCELLING state, so trim
|
||||
// down our resource usage and clean ourselves up.
|
||||
// thread* thrd = m_workers.find(me);
|
||||
m_workers.remove_thread(me);
|
||||
// delete thrd;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
thread_pool::thread_pool(int max_threads, int min_threads, int timeout_secs,
|
||||
int timeout_nsecs)
|
||||
: m_pimpl(new impl(max_threads, min_threads, timeout_secs, timeout_nsecs))
|
||||
{
|
||||
}
|
||||
|
||||
thread_pool::~thread_pool()
|
||||
{
|
||||
if (m_pimpl != NULL)
|
||||
delete m_pimpl;
|
||||
}
|
||||
|
||||
void thread_pool::add(const boost::function0<void> &job)
|
||||
{
|
||||
assert(m_pimpl);
|
||||
m_pimpl->add(job);
|
||||
}
|
||||
|
||||
void thread_pool::join()
|
||||
{
|
||||
assert(m_pimpl);
|
||||
m_pimpl->join();
|
||||
}
|
||||
|
||||
void thread_pool::cancel()
|
||||
{
|
||||
assert(m_pimpl);
|
||||
m_pimpl->cancel();
|
||||
}
|
||||
|
||||
void thread_pool::detach()
|
||||
{
|
||||
assert(m_pimpl);
|
||||
|
||||
// Tell our implementation it is running detached.
|
||||
m_pimpl->detach();
|
||||
m_pimpl = NULL;
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
185
src/threadmon.cpp
Normal file
185
src/threadmon.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
// 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>
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
extern "C" void tss_cleanup_implemented(void);
|
||||
|
||||
void require_tss_cleanup_implemented(void)
|
||||
{
|
||||
tss_cleanup_implemented();
|
||||
}
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
//Exclude rarely-used stuff from Windows headers
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(disable : 4786)
|
||||
#endif
|
||||
|
||||
#include <list>
|
||||
#include <boost/thread/detail/threadmon.hpp>
|
||||
|
||||
typedef void (__cdecl * handler)(void);
|
||||
typedef std::list<handler> exit_handlers;
|
||||
|
||||
namespace
|
||||
{
|
||||
const DWORD invalid_key = TLS_OUT_OF_INDEXES;
|
||||
static DWORD key = invalid_key;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
BOOST_THREAD_DECL int at_thread_exit(void (__cdecl * func)(void))
|
||||
{
|
||||
//Get the exit handlers for the current thread,
|
||||
//creating and registering one if it doesn't exist.
|
||||
|
||||
if (key == invalid_key)
|
||||
key = TlsAlloc();
|
||||
|
||||
if (key == invalid_key)
|
||||
return -1;
|
||||
|
||||
exit_handlers* handlers =
|
||||
static_cast<exit_handlers*>(TlsGetValue(key));
|
||||
|
||||
if (!handlers)
|
||||
{
|
||||
try
|
||||
{
|
||||
handlers = new exit_handlers;
|
||||
|
||||
//Handle broken implementations
|
||||
//of operator new that don't throw
|
||||
if (!handlers)
|
||||
return -1;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Attempt to set a TLS value for the new handlers.
|
||||
if (!TlsSetValue(key, handlers))
|
||||
{
|
||||
delete handlers;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//Attempt to add the handler to the list of exit handlers.
|
||||
try
|
||||
{
|
||||
handlers->push_front(func);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" BOOST_THREAD_DECL void on_process_enter(void)
|
||||
{
|
||||
if (key == invalid_key)
|
||||
key = TlsAlloc();
|
||||
}
|
||||
|
||||
extern "C" BOOST_THREAD_DECL void on_thread_exit(void)
|
||||
{
|
||||
if (key == invalid_key)
|
||||
return;
|
||||
|
||||
exit_handlers* handlers =
|
||||
static_cast<exit_handlers*>(TlsGetValue(key));
|
||||
|
||||
if (handlers)
|
||||
{
|
||||
for (exit_handlers::iterator it = handlers->begin();
|
||||
it != handlers->end();
|
||||
++it)
|
||||
{
|
||||
//Call each exit handler
|
||||
(*it)();
|
||||
}
|
||||
|
||||
//Destroy the exit handlers
|
||||
delete handlers;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" BOOST_THREAD_DECL void on_process_exit(void)
|
||||
{
|
||||
if (key != invalid_key)
|
||||
{
|
||||
TlsFree(key);
|
||||
key = invalid_key;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BOOST_THREAD_BUILD_DLL)
|
||||
extern "C" void tss_cleanup_implemented(void)
|
||||
{
|
||||
//Don't need to do anything; this function's
|
||||
//sole purpose is to cause a link error in cases
|
||||
//where tss cleanup is not implemented by Boost.Threads
|
||||
//as a reminder that user code is responsible for calling
|
||||
//on_process_enter(), on_thread_exit(), and
|
||||
//on_process_exit() at the appropriate times
|
||||
//and implementing an empty tss_cleanup_implemented()
|
||||
//function to eliminate the link error.
|
||||
}
|
||||
|
||||
#if defined(__BORLANDC__)
|
||||
#define DllMain DllEntryPoint
|
||||
#endif
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HANDLE /*module*/, DWORD reason, LPVOID)
|
||||
{
|
||||
switch (reason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
{
|
||||
on_process_enter();
|
||||
break;
|
||||
}
|
||||
case DLL_THREAD_ATTACH:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case DLL_THREAD_DETACH:
|
||||
{
|
||||
on_thread_exit();
|
||||
break;
|
||||
}
|
||||
case DLL_PROCESS_DETACH:
|
||||
{
|
||||
on_thread_exit();
|
||||
on_process_exit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif // BOOST_THREAD_BUILD_DLL
|
||||
#endif // BOOST_HAS_WINTHREADS
|
||||
|
||||
// Change Log:
|
||||
// 20 Mar 04 GLASSFORM for WEKEMPF
|
||||
// Removed uneccessary critical section:
|
||||
// Windows already serializes calls to DllMain.
|
||||
// Removed registered_handlers.
|
||||
@@ -27,7 +27,7 @@ inline void to_time(int milliseconds, boost::xtime& xt)
|
||||
xt.nsec += ((milliseconds % MILLISECONDS_PER_SECOND) *
|
||||
NANOSECONDS_PER_MILLISECOND);
|
||||
|
||||
if (xt.nsec > NANOSECONDS_PER_SECOND)
|
||||
if (xt.nsec > static_cast<const int>(NANOSECONDS_PER_SECOND))
|
||||
{
|
||||
++xt.sec;
|
||||
xt.nsec -= NANOSECONDS_PER_SECOND;
|
||||
@@ -39,7 +39,7 @@ inline void to_timespec(const boost::xtime& xt, timespec& ts)
|
||||
{
|
||||
ts.tv_sec = static_cast<int>(xt.sec);
|
||||
ts.tv_nsec = static_cast<int>(xt.nsec);
|
||||
if(ts.tv_nsec > NANOSECONDS_PER_SECOND)
|
||||
if(ts.tv_nsec > static_cast<const int>(NANOSECONDS_PER_SECOND))
|
||||
{
|
||||
ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
|
||||
ts.tv_nsec %= NANOSECONDS_PER_SECOND;
|
||||
@@ -75,7 +75,7 @@ inline void to_timespec_duration(const boost::xtime& xt, timespec& ts)
|
||||
ts.tv_sec -= 1;
|
||||
ts.tv_nsec += NANOSECONDS_PER_SECOND;
|
||||
}
|
||||
if(ts.tv_nsec > NANOSECONDS_PER_SECOND)
|
||||
if(ts.tv_nsec > static_cast<const int>(NANOSECONDS_PER_SECOND))
|
||||
{
|
||||
ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
|
||||
ts.tv_nsec %= NANOSECONDS_PER_SECOND;
|
||||
|
||||
20
src/tss.cpp
20
src/tss.cpp
@@ -18,13 +18,12 @@
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/exceptions.hpp>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <cassert>
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
# include <windows.h>
|
||||
# include <boost/thread/detail/tss_hooks.hpp>
|
||||
# include <boost/thread/detail/threadmon.hpp>
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
@@ -63,10 +62,6 @@ void init_tss_data()
|
||||
std::auto_ptr<tss_data_t> temp(new tss_data_t);
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
//Force the cleanup implementation library to be linked in
|
||||
tss_cleanup_implemented();
|
||||
|
||||
//Allocate tls slot
|
||||
temp->native_key = TlsAlloc();
|
||||
if (temp->native_key == 0xFFFFFFFF)
|
||||
return;
|
||||
@@ -204,3 +199,16 @@ void tss::cleanup(void* value)
|
||||
} // namespace boost
|
||||
|
||||
#endif //BOOST_THREAD_NO_TSS_CLEANUP
|
||||
|
||||
// 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().
|
||||
@@ -1,70 +0,0 @@
|
||||
// (C) Copyright Michael Glassford 2004.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_DLL)
|
||||
|
||||
#include <boost/thread/detail/tss_hooks.hpp>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#if defined(__BORLANDC__)
|
||||
extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE /*hInstance*/, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||
#else
|
||||
extern "C" BOOL WINAPI DllMain(HINSTANCE /*hInstance*/, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||
#endif
|
||||
{
|
||||
switch(dwReason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
{
|
||||
on_process_enter();
|
||||
on_thread_enter();
|
||||
break;
|
||||
}
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
{
|
||||
on_thread_enter();
|
||||
break;
|
||||
}
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
{
|
||||
on_thread_exit();
|
||||
break;
|
||||
}
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
{
|
||||
on_thread_exit();
|
||||
on_process_exit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
extern "C" void tss_cleanup_implemented(void)
|
||||
{
|
||||
/*
|
||||
This function's sole purpose is to cause a link error in cases where
|
||||
automatic tss cleanup is not implemented by Boost.Threads as a
|
||||
reminder that user code is responsible for calling the necessary
|
||||
functions at the appropriate times (and for implementing an a
|
||||
tss_cleanup_implemented() function to eliminate the linker's
|
||||
missing symbol error).
|
||||
|
||||
If Boost.Threads later implements automatic tss cleanup in cases
|
||||
where it currently doesn't (which is the plan), the duplicate
|
||||
symbol error will warn the user that their custom solution is no
|
||||
longer needed and can be removed.
|
||||
*/
|
||||
}
|
||||
|
||||
#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_DLL)
|
||||
@@ -1,184 +0,0 @@
|
||||
// (C) Copyright Michael Glassford 2004.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
|
||||
#include <boost/thread/detail/tss_hooks.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/once.hpp>
|
||||
|
||||
#include <list>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
typedef std::list<thread_exit_handler> thread_exit_handlers;
|
||||
|
||||
boost::once_flag once_init_threadmon_mutex = BOOST_ONCE_INIT;
|
||||
boost::mutex* threadmon_mutex;
|
||||
void init_threadmon_mutex(void)
|
||||
{
|
||||
threadmon_mutex = new boost::mutex;
|
||||
if (!threadmon_mutex)
|
||||
throw boost::thread_resource_error();
|
||||
}
|
||||
|
||||
const DWORD invalid_tls_key = TLS_OUT_OF_INDEXES;
|
||||
DWORD tls_key = invalid_tls_key;
|
||||
|
||||
unsigned long attached_thread_count = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Calls to DllMain() and tls_callback() are serialized by the OS;
|
||||
however, calls to at_thread_exit are not, so it must be protected
|
||||
by a mutex. Since we already need a mutex for at_thread_exit(),
|
||||
and since there is no guarantee that on_process_enter(),
|
||||
on_process_exit(), on_thread_enter(), and on_thread_exit()
|
||||
will be called only from DllMain() or tls_callback(), it makes
|
||||
sense to protect those, too.
|
||||
*/
|
||||
|
||||
extern "C" BOOST_THREAD_DECL int at_thread_exit(
|
||||
thread_exit_handler exit_handler
|
||||
)
|
||||
{
|
||||
boost::call_once(init_threadmon_mutex, once_init_threadmon_mutex);
|
||||
boost::mutex::scoped_lock lock(*threadmon_mutex);
|
||||
|
||||
//Allocate a tls slot if necessary.
|
||||
|
||||
if (tls_key == invalid_tls_key)
|
||||
tls_key = TlsAlloc();
|
||||
|
||||
if (tls_key == invalid_tls_key)
|
||||
return -1;
|
||||
|
||||
//Get the exit handlers list for the current thread from tls.
|
||||
|
||||
thread_exit_handlers* exit_handlers =
|
||||
static_cast<thread_exit_handlers*>(TlsGetValue(tls_key));
|
||||
|
||||
if (!exit_handlers)
|
||||
{
|
||||
//No exit handlers list was created yet.
|
||||
|
||||
try
|
||||
{
|
||||
//Attempt to create a new exit handlers list.
|
||||
|
||||
exit_handlers = new thread_exit_handlers;
|
||||
if (!exit_handlers)
|
||||
return -1;
|
||||
|
||||
//Attempt to store the list pointer in tls.
|
||||
|
||||
if (TlsSetValue(tls_key, exit_handlers))
|
||||
++attached_thread_count;
|
||||
else
|
||||
{
|
||||
delete exit_handlers;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//Like the C runtime library atexit() function,
|
||||
//functions should be called in the reverse of
|
||||
//the order they are added, so push them on the
|
||||
//front of the list.
|
||||
|
||||
try
|
||||
{
|
||||
exit_handlers->push_front(exit_handler);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Like the atexit() function, a result of zero
|
||||
//indicates success.
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" BOOST_THREAD_DECL void on_process_enter(void)
|
||||
{
|
||||
boost::call_once(init_threadmon_mutex, once_init_threadmon_mutex);
|
||||
boost::mutex::scoped_lock lock(*threadmon_mutex);
|
||||
|
||||
BOOST_ASSERT(attached_thread_count == 0);
|
||||
}
|
||||
|
||||
extern "C" BOOST_THREAD_DECL void on_process_exit(void)
|
||||
{
|
||||
boost::call_once(init_threadmon_mutex, once_init_threadmon_mutex);
|
||||
boost::mutex::scoped_lock lock(*threadmon_mutex);
|
||||
|
||||
BOOST_ASSERT(attached_thread_count == 0);
|
||||
|
||||
//Free the tls slot if one was allocated.
|
||||
|
||||
if (tls_key != invalid_tls_key)
|
||||
{
|
||||
TlsFree(tls_key);
|
||||
tls_key = invalid_tls_key;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" BOOST_THREAD_DECL void on_thread_enter(void)
|
||||
{
|
||||
//boost::call_once(init_threadmon_mutex, once_init_threadmon_mutex);
|
||||
//boost::mutex::scoped_lock lock(*threadmon_mutex);
|
||||
}
|
||||
|
||||
extern "C" BOOST_THREAD_DECL void on_thread_exit(void)
|
||||
{
|
||||
boost::call_once(init_threadmon_mutex, once_init_threadmon_mutex);
|
||||
boost::mutex::scoped_lock lock(*threadmon_mutex);
|
||||
|
||||
//Get the exit handlers list for the current thread from tls.
|
||||
|
||||
if (tls_key == invalid_tls_key)
|
||||
return;
|
||||
|
||||
thread_exit_handlers* exit_handlers =
|
||||
static_cast<thread_exit_handlers*>(TlsGetValue(tls_key));
|
||||
|
||||
//If a handlers list was found, use it.
|
||||
|
||||
if (exit_handlers && TlsSetValue(tls_key, 0))
|
||||
{
|
||||
BOOST_ASSERT(attached_thread_count > 0);
|
||||
--attached_thread_count;
|
||||
|
||||
lock.unlock();
|
||||
|
||||
//Call each handler and remove it from the list
|
||||
|
||||
while (!exit_handlers->empty())
|
||||
{
|
||||
if (thread_exit_handler exit_handler = *exit_handlers->begin())
|
||||
(*exit_handler)();
|
||||
exit_handlers->pop_front();
|
||||
}
|
||||
|
||||
delete exit_handlers;
|
||||
exit_handlers = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif //defined(BOOST_HAS_WINTHREADS)
|
||||
@@ -1,33 +0,0 @@
|
||||
// (C) Copyright Michael Glassford 2004.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS) && (defined(BOOST_THREAD_BUILD_LIB) || defined(BOOST_THREAD_TEST)) && !defined(_MSC_VER)
|
||||
|
||||
/*
|
||||
This file is a "null" implementation of tss cleanup; it's
|
||||
purpose is to to eliminate link errors in cases
|
||||
where it is known that tss cleanup is not needed.
|
||||
*/
|
||||
|
||||
extern "C" void tss_cleanup_implemented(void)
|
||||
{
|
||||
/*
|
||||
This function's sole purpose is to cause a link error in cases where
|
||||
automatic tss cleanup is not implemented by Boost.Threads as a
|
||||
reminder that user code is responsible for calling the necessary
|
||||
functions at the appropriate times (and for implementing an a
|
||||
tss_cleanup_implemented() function to eliminate the linker's
|
||||
missing symbol error).
|
||||
|
||||
If Boost.Threads later implements automatic tss cleanup in cases
|
||||
where it currently doesn't (which is the plan), the duplicate
|
||||
symbol error will warn the user that their custom solution is no
|
||||
longer needed and can be removed.
|
||||
*/
|
||||
}
|
||||
|
||||
#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB) && !defined(_MSC_VER)
|
||||
179
src/tss_pe.cpp
179
src/tss_pe.cpp
@@ -1,179 +0,0 @@
|
||||
// (C) Copyright Aaron W. LaFramboise, Roland Schwarz, Michael Glassford 2004.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB) && defined(_MSC_VER)
|
||||
|
||||
#include <boost/thread/detail/tss_hooks.hpp>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
//Definitions required by implementation
|
||||
|
||||
#if (_MSC_VER < 1310) // 1310 == VC++ 7.1
|
||||
typedef void (__cdecl *_PVFV)(void);
|
||||
#define INIRETSUCCESS
|
||||
#define PVAPI void
|
||||
#else
|
||||
typedef int (__cdecl *_PVFV)(void);
|
||||
#define INIRETSUCCESS 0
|
||||
#define PVAPI int
|
||||
#endif
|
||||
|
||||
typedef void (NTAPI* _TLSCB)(HINSTANCE, DWORD, PVOID);
|
||||
|
||||
//Symbols for connection to the runtime environment
|
||||
|
||||
extern "C"
|
||||
{
|
||||
extern DWORD _tls_used; //the tls directory (located in .rdata segment)
|
||||
extern _TLSCB __xl_a[], __xl_z[]; //tls initializers */
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
//Forward declarations
|
||||
|
||||
static PVAPI on_tls_prepare(void);
|
||||
static PVAPI on_process_init(void);
|
||||
static PVAPI on_process_term(void);
|
||||
static void NTAPI on_tls_callback(HINSTANCE, DWORD, PVOID);
|
||||
|
||||
//The .CRT$Xxx information is taken from Codeguru:
|
||||
//http://www.codeguru.com/Cpp/misc/misc/threadsprocesses/article.php/c6945__2/
|
||||
|
||||
#if (_MSC_VER >= 1310) // 1310 == VC++ 7.1
|
||||
# pragma data_seg(push, old_seg)
|
||||
#endif
|
||||
//Callback to run tls glue code first.
|
||||
//I don't think it is necessary to run it
|
||||
//at .CRT$XIB level, since we are only
|
||||
//interested in thread detachement. But
|
||||
//this could be changed easily if required.
|
||||
|
||||
#pragma data_seg(".CRT$XIU")
|
||||
static _PVFV p_tls_prepare = on_tls_prepare;
|
||||
#pragma data_seg()
|
||||
|
||||
//Callback after all global ctors.
|
||||
|
||||
#pragma data_seg(".CRT$XCU")
|
||||
static _PVFV p_process_init = on_process_init;
|
||||
#pragma data_seg()
|
||||
|
||||
//Callback for tls notifications.
|
||||
|
||||
#pragma data_seg(".CRT$XLB")
|
||||
_TLSCB p_thread_callback = on_tls_callback;
|
||||
#pragma data_seg()
|
||||
|
||||
//Callback for termination.
|
||||
|
||||
#pragma data_seg(".CRT$XTU")
|
||||
static _PVFV p_process_term = on_process_term;
|
||||
#pragma data_seg()
|
||||
#if (_MSC_VER >= 1310) // 1310 == VC++ 7.1
|
||||
# pragma data_seg(pop, old_seg)
|
||||
#endif
|
||||
|
||||
PVAPI on_tls_prepare(void)
|
||||
{
|
||||
//The following line has an important side effect:
|
||||
//if the TLS directory is not already there, it will
|
||||
//be created by the linker. In other words, it forces a tls
|
||||
//directory to be generated by the linker even when static tls
|
||||
//(i.e. __declspec(thread)) is not used.
|
||||
//The volatile should prevent the optimizer
|
||||
//from removing the reference.
|
||||
|
||||
DWORD volatile dw = _tls_used;
|
||||
|
||||
#if (_MSC_VER < 1310) // 1310 == VC++ 7.1
|
||||
_TLSCB* pfbegin = __xl_a;
|
||||
_TLSCB* pfend = __xl_z;
|
||||
_TLSCB* pfdst = pfbegin;
|
||||
//pfdst = (_TLSCB*)_tls_used.AddressOfCallBacks;
|
||||
|
||||
//The following loop will merge the address pointers
|
||||
//into a contiguous area, since the tlssup code seems
|
||||
//to require this (at least on MSVC 6)
|
||||
|
||||
while (pfbegin < pfend)
|
||||
{
|
||||
if (*pfbegin != 0)
|
||||
{
|
||||
*pfdst = *pfbegin;
|
||||
++pfdst;
|
||||
}
|
||||
++pfbegin;
|
||||
}
|
||||
|
||||
*pfdst = 0;
|
||||
#endif
|
||||
|
||||
return INIRETSUCCESS;
|
||||
}
|
||||
|
||||
PVAPI on_process_init(void)
|
||||
{
|
||||
//Schedule on_thread_exit() to be called for the main
|
||||
//thread before destructors of global objects have been
|
||||
//called.
|
||||
|
||||
//It will not be run when 'quick' exiting the
|
||||
//library; however, this is the standard behaviour
|
||||
//for destructors of global objects, so that
|
||||
//shouldn't be a problem.
|
||||
|
||||
atexit(on_thread_exit);
|
||||
|
||||
//Call Boost process entry callback here
|
||||
|
||||
on_process_enter();
|
||||
|
||||
return INIRETSUCCESS;
|
||||
}
|
||||
|
||||
PVAPI on_process_term(void)
|
||||
{
|
||||
on_process_exit();
|
||||
return INIRETSUCCESS;
|
||||
}
|
||||
|
||||
void NTAPI on_tls_callback(HINSTANCE h, DWORD dwReason, PVOID pv)
|
||||
{
|
||||
switch (dwReason)
|
||||
{
|
||||
case DLL_THREAD_DETACH:
|
||||
{
|
||||
on_thread_exit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} //namespace
|
||||
|
||||
extern "C" void tss_cleanup_implemented(void)
|
||||
{
|
||||
/*
|
||||
This function's sole purpose is to cause a link error in cases where
|
||||
automatic tss cleanup is not implemented by Boost.Threads as a
|
||||
reminder that user code is responsible for calling the necessary
|
||||
functions at the appropriate times (and for implementing an a
|
||||
tss_cleanup_implemented() function to eliminate the linker's
|
||||
missing symbol error).
|
||||
|
||||
If Boost.Threads later implements automatic tss cleanup in cases
|
||||
where it currently doesn't (which is the plan), the duplicate
|
||||
symbol error will warn the user that their custom solution is no
|
||||
longer needed and can be removed.
|
||||
*/
|
||||
}
|
||||
|
||||
#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB)
|
||||
@@ -11,15 +11,10 @@
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_FTIME)
|
||||
# define __STDC_CONSTANT_MACROS
|
||||
#endif
|
||||
|
||||
#include <boost/thread/xtime.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_FTIME)
|
||||
# include <windows.h>
|
||||
# include <boost/cstdint.hpp>
|
||||
#elif defined(BOOST_HAS_GETTIMEOFDAY)
|
||||
# include <sys/time.h>
|
||||
#elif defined(BOOST_HAS_MPTASKS)
|
||||
@@ -93,21 +88,13 @@ int xtime_get(struct xtime* xtp, int clock_type)
|
||||
# else
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
# endif
|
||||
static const boost::uint64_t TIMESPEC_TO_FILETIME_OFFSET =
|
||||
UINT64_C(116444736000000000);
|
||||
|
||||
const boost::uint64_t ft64 =
|
||||
(static_cast<boost::uint64_t>(ft.dwHighDateTime) << 32)
|
||||
+ ft.dwLowDateTime;
|
||||
|
||||
xtp->sec = static_cast<xtime::xtime_sec_t>(
|
||||
(ft64 - TIMESPEC_TO_FILETIME_OFFSET) / 10000000
|
||||
);
|
||||
|
||||
xtp->nsec = static_cast<xtime::xtime_nsec_t>(
|
||||
((ft64 - TIMESPEC_TO_FILETIME_OFFSET) % 10000000) * 100
|
||||
);
|
||||
|
||||
const boost::uint64_t TIMESPEC_TO_FILETIME_OFFSET =
|
||||
((boost::uint64_t)27111902UL << 32) +
|
||||
(boost::uint64_t)3577643008UL;
|
||||
xtp->sec = (int)((*(__int64*)&ft - TIMESPEC_TO_FILETIME_OFFSET) /
|
||||
10000000);
|
||||
xtp->nsec = (int)((*(__int64*)&ft - TIMESPEC_TO_FILETIME_OFFSET -
|
||||
((__int64)xtp->sec * (__int64)10000000)) * 100);
|
||||
return clock_type;
|
||||
#elif defined(BOOST_HAS_GETTIMEOFDAY)
|
||||
struct timeval tv;
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
bin
|
||||
*.pdb
|
||||
.jamdeps
|
||||
@@ -1,18 +1 @@
|
||||
/*
|
||||
* Permit this Carbon application to launch on OS X
|
||||
*
|
||||
* © 1997-2000 Metrowerks Corp.
|
||||
*
|
||||
* Questions and comments to:
|
||||
* <mailto:support@metrowerks.com>
|
||||
* <http://www.metrowerks.com/>
|
||||
*/
|
||||
|
||||
|
||||
/*----------------------------carb ¥ Carbon on OS X launch information --------------------------*/
|
||||
type 'carb' {
|
||||
};
|
||||
|
||||
|
||||
resource 'carb'(0) {
|
||||
};
|
||||
/*
|
||||
83
test/Jamfile
83
test/Jamfile
@@ -12,7 +12,14 @@
|
||||
# Boost.Threads test Jamfile
|
||||
#
|
||||
# Additional configuration variables used:
|
||||
# See threads.jam.
|
||||
# 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/test ;
|
||||
@@ -26,58 +33,26 @@ import ../build/threads ;
|
||||
import testing ;
|
||||
|
||||
{
|
||||
template boost_thread_test_lib
|
||||
: ## sources ##
|
||||
<template>thread_base
|
||||
../src/tss_null.cpp
|
||||
<lib>../build/boost_thread
|
||||
<lib>../../test/build/boost_unit_test_framework
|
||||
#<lib>../../test/build/boost_test_exec_monitor
|
||||
: ## requirements ##
|
||||
<sysinclude>$(BOOST_ROOT) #:should be unnecessary (because already included in thread_base)
|
||||
<define>BOOST_ALL_NO_LIB=1
|
||||
<define>BOOST_THREAD_USE_LIB=1
|
||||
<define>BOOST_THREAD_TEST=1
|
||||
<runtime-link>static
|
||||
<threading>multi
|
||||
: ## default build ##
|
||||
;
|
||||
|
||||
template boost_thread_test_dll
|
||||
: ## sources ##
|
||||
<template>thread_base
|
||||
../src/tss_null.cpp
|
||||
<dll>../build/boost_thread
|
||||
<lib>../../test/build/boost_unit_test_framework
|
||||
#<lib>../../test/build/boost_test_exec_monitor
|
||||
: ## requirements ##
|
||||
<sysinclude>$(BOOST_ROOT) #:should be unnecessary (because already included in thread_base)
|
||||
<define>BOOST_ALL_NO_LIB=1
|
||||
<define>BOOST_THREAD_USE_DLL=1
|
||||
<define>BOOST_THREAD_TEST=1
|
||||
<runtime-link>dynamic
|
||||
<threading>multi
|
||||
: ## default build ##
|
||||
;
|
||||
template test
|
||||
## sources ##
|
||||
: <template>thread_base
|
||||
<dll>../build/boost_thread
|
||||
<lib>../../test/build/boost_unit_test_framework
|
||||
## requirements ##
|
||||
:
|
||||
## default build ##
|
||||
:
|
||||
;
|
||||
|
||||
test-suite "threads"
|
||||
:
|
||||
[ run test_thread.cpp <template>boost_thread_test_dll ]
|
||||
[ run test_mutex.cpp <template>boost_thread_test_dll ]
|
||||
[ run test_condition.cpp <template>boost_thread_test_dll ]
|
||||
[ run test_tss.cpp <template>boost_thread_test_dll ]
|
||||
[ run test_once.cpp <template>boost_thread_test_dll ]
|
||||
[ run test_xtime.cpp <template>boost_thread_test_dll ]
|
||||
[ run test_barrier.cpp <template>boost_thread_test_dll ]
|
||||
[ run test_read_write_mutex.cpp <template>boost_thread_test_dll ]
|
||||
|
||||
[ run test_thread.cpp <template>boost_thread_test_lib : : : : test_thread_lib ]
|
||||
[ run test_mutex.cpp <template>boost_thread_test_lib : : : : test_mutex_lib ]
|
||||
[ run test_condition.cpp <template>boost_thread_test_lib : : : : test_condition_lib ]
|
||||
[ run test_tss.cpp <template>boost_thread_test_lib : : : : test_tss_lib ]
|
||||
[ run test_once.cpp <template>boost_thread_test_lib : : : : test_once_lib ]
|
||||
[ run test_xtime.cpp <template>boost_thread_test_lib : : : : test_xtime_lib ]
|
||||
[ run test_barrier.cpp <template>boost_thread_test_lib : : : : test_barrier_lib ]
|
||||
[ run test_read_write_mutex.cpp <template>boost_thread_test_lib : : : : test_read_write_mutex_lib ]
|
||||
;
|
||||
test-suite "threads"
|
||||
: [ run test_thread.cpp <template>test ]
|
||||
[ run test_mutex.cpp <template>test ]
|
||||
[ run test_condition.cpp <template>test ]
|
||||
[ run test_tss.cpp <template>test ]
|
||||
[ run test_once.cpp <template>test ]
|
||||
[ run test_xtime.cpp <template>test ]
|
||||
[ run test_barrier.cpp <template>test ]
|
||||
# [ run test_read_write_mutex.cpp <template>test ]
|
||||
[ run test_thread_pool.cpp <template>test ]
|
||||
;
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
# (C) Copyright William E. Kempf 2001. Permission to copy, use, modify, sell
|
||||
# and distribute this software is granted provided this copyright notice
|
||||
# appears in all copies. This software is provided "as is" without express or
|
||||
# implied warranty, and with no claim as to its suitability for any purpose.
|
||||
#
|
||||
# Boost.Threads test 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"
|
||||
|
||||
# bring in rules for testing
|
||||
import testing ;
|
||||
|
||||
project
|
||||
: requirements <library>../build//boost_thread
|
||||
<library>../../test/build//boost_unit_test_framework
|
||||
<threading>multi
|
||||
;
|
||||
{
|
||||
test-suite "threads"
|
||||
: [ run test_thread.cpp ]
|
||||
[ run test_mutex.cpp ]
|
||||
[ run test_condition.cpp ]
|
||||
[ run test_tss.cpp ]
|
||||
[ run test_once.cpp ]
|
||||
[ run test_xtime.cpp ]
|
||||
[ run test_barrier.cpp ]
|
||||
;
|
||||
}
|
||||
@@ -9,8 +9,6 @@
|
||||
// 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/thread.hpp>
|
||||
#include <boost/thread/barrier.hpp>
|
||||
|
||||
|
||||
@@ -9,15 +9,13 @@
|
||||
// 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/thread.hpp>
|
||||
#include <boost/thread/xtime.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <libs/thread/test/util.inl>
|
||||
#include "util.inl"
|
||||
|
||||
struct condition_test_data
|
||||
{
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
// 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/mutex.hpp>
|
||||
#include <boost/thread/recursive_mutex.hpp>
|
||||
#include <boost/thread/xtime.hpp>
|
||||
@@ -20,7 +18,7 @@
|
||||
#include <boost/test/unit_test_suite_ex.hpp>
|
||||
|
||||
#define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_sleep_only
|
||||
#include <libs/thread/test/util.inl>
|
||||
#include "util.inl"
|
||||
|
||||
template <typename M>
|
||||
struct test_lock
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user