mirror of
https://github.com/boostorg/thread.git
synced 2026-02-03 21:52:07 +00:00
Compare commits
30 Commits
boost-1.34
...
svn-branch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35b8104a7c | ||
|
|
a8daedac5e | ||
|
|
5fa26fb3ac | ||
|
|
ea3e297175 | ||
|
|
a11bd6ebd9 | ||
|
|
9889bf50a2 | ||
|
|
d75fb2deda | ||
|
|
6355a5b28d | ||
|
|
595bbee41e | ||
|
|
cb3f3a1f64 | ||
|
|
0e44838905 | ||
|
|
64cd268fc7 | ||
|
|
f048dd81f2 | ||
|
|
5746f2214c | ||
|
|
099af669d4 | ||
|
|
79cac706a7 | ||
|
|
df229074ac | ||
|
|
191c27e856 | ||
|
|
e5ee01b43c | ||
|
|
c46b040f6f | ||
|
|
72e4794f5b | ||
|
|
c30b65a0ea | ||
|
|
1cb08ff60c | ||
|
|
d3d7fd9317 | ||
|
|
acf0f97663 | ||
|
|
34bd87cea7 | ||
|
|
228f11262e | ||
|
|
9683e0f1cc | ||
|
|
674ae6d571 | ||
|
|
690d44e2e6 |
122
build/Jamfile
Normal file
122
build/Jamfile
Normal file
@@ -0,0 +1,122 @@
|
||||
# Copyright (C) 2001-2003
|
||||
# William E. Kempf
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# Boost.Threads build Jamfile
|
||||
#
|
||||
# Additional configuration variables used:
|
||||
# See threads.jam.
|
||||
|
||||
# Declare the location of this subproject relative to the root.
|
||||
subproject libs/thread/build ;
|
||||
|
||||
# Include threads.jam for Boost.Threads global build information.
|
||||
# This greatly simplifies the Jam code needed to configure the build
|
||||
# for the various Win32 build types.
|
||||
import ./threads ;
|
||||
|
||||
{
|
||||
CPP_SOURCES =
|
||||
barrier
|
||||
condition
|
||||
exceptions
|
||||
mutex
|
||||
once
|
||||
recursive_mutex
|
||||
read_write_mutex
|
||||
thread
|
||||
tss_hooks
|
||||
tss_dll
|
||||
tss_pe
|
||||
tss
|
||||
xtime
|
||||
;
|
||||
|
||||
template boost_thread_lib_base
|
||||
: ## sources ##
|
||||
<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
|
||||
# the common names rule ensures that the library will
|
||||
# be named according to the rules used by the install
|
||||
# and auto-link features:
|
||||
common-variant-tag
|
||||
: ## default build ##
|
||||
;
|
||||
|
||||
template boost_thread_dll_base
|
||||
: ## sources ##
|
||||
<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
|
||||
: ## default build ##
|
||||
;
|
||||
|
||||
lib $(boost_thread_lib_name)
|
||||
: ## sources ##
|
||||
<template>boost_thread_lib_base
|
||||
: ## requirements ##
|
||||
<define>BOOST_THREAD_LIB_NAME=$(boost_thread_lib_name)
|
||||
: ## default build ##
|
||||
;
|
||||
|
||||
dll $(boost_thread_lib_name)
|
||||
: ## sources ##
|
||||
<template>boost_thread_dll_base
|
||||
: ## requirements ##
|
||||
<define>BOOST_THREAD_LIB_NAME=$(boost_thread_lib_name)
|
||||
: ## default build ##
|
||||
;
|
||||
|
||||
stage bin-stage
|
||||
: <dll>$(boost_thread_lib_name)
|
||||
<lib>$(boost_thread_lib_name)
|
||||
;
|
||||
|
||||
install thread lib
|
||||
: <dll>$(boost_thread_lib_name)
|
||||
<lib>$(boost_thread_lib_name)
|
||||
;
|
||||
|
||||
if $(boost_thread_lib_settings_ptw32)
|
||||
{
|
||||
lib $(boost_thread_lib_name_ptw32)
|
||||
: ## sources ##
|
||||
<template>boost_thread_lib_base
|
||||
: ## requirements ##
|
||||
<define>BOOST_THREAD_LIB_NAME=$(boost_thread_lib_name_ptw32)
|
||||
$(boost_thread_lib_settings_ptw32)
|
||||
: ## default build ##
|
||||
;
|
||||
|
||||
dll $(boost_thread_lib_name_ptw32)
|
||||
: ## sources ##
|
||||
<template>boost_thread_dll_base
|
||||
: ## requirements ##
|
||||
<define>BOOST_THREAD_LIB_NAME=$(boost_thread_lib_name_ptw32)
|
||||
$(boost_thread_lib_settings_ptw32)
|
||||
: ## default build ##
|
||||
;
|
||||
|
||||
stage bin-stage
|
||||
: <dll>$(boost_thread_lib_name_ptw32)
|
||||
<lib>$(boost_thread_lib_name_ptw32)
|
||||
;
|
||||
|
||||
install thread lib
|
||||
: <dll>$(boost_thread_lib_name_ptw32)
|
||||
<lib>$(boost_thread_lib_name_ptw32)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ CPP_SOURCES =
|
||||
mutex
|
||||
once
|
||||
recursive_mutex
|
||||
# read_write_mutex
|
||||
read_write_mutex
|
||||
thread
|
||||
tss_hooks
|
||||
tss_dll
|
||||
|
||||
65
build/threads.jam
Normal file
65
build/threads.jam
Normal file
@@ -0,0 +1,65 @@
|
||||
# Copyright (C) 2001-2003
|
||||
# William E. Kempf
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# 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
|
||||
boost_thread_lib_name = boost_thread ;
|
||||
|
||||
#thread library name with "pthreads-win32" library
|
||||
boost_thread_lib_name_ptw32 = boost_thread_ptw32 ;
|
||||
|
||||
if $(NT)
|
||||
{
|
||||
if $(PTW32_DIR)
|
||||
{
|
||||
if $(PTW32_LIB)
|
||||
{
|
||||
boost_thread_lib_settings_ptw32 =
|
||||
<define>BOOST_HAS_PTHREADS
|
||||
<define>PtW32NoCatchWarn
|
||||
<include>$(PTW32_DIR)/pre-built/include
|
||||
<library-file>$(PTW32_DIR)/pre-built/lib/$(PTW32_LIB)
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template thread_base
|
||||
: ## sources ##
|
||||
: ## requirements ##
|
||||
<sysinclude>$(BOOST_ROOT)
|
||||
<threading>multi
|
||||
<borland><*><cxxflags>-w-8004
|
||||
<borland><*><cxxflags>-w-8057
|
||||
: ## default build ##
|
||||
;
|
||||
}
|
||||
BIN
build/threads.mcp
Normal file
BIN
build/threads.mcp
Normal file
Binary file not shown.
@@ -63,11 +63,6 @@ last-revision="$Date$">
|
||||
Steve Cleary, Steven Kirk, Thomas Holenstein, Thomas Matelich, Trevor
|
||||
Perrin, Valentin Bonnard, Vesa Karvonen, Wayne Miller, and William
|
||||
Kempf.</para>
|
||||
<para>
|
||||
As of February 2006 Anthony Williams and Roland Schwarz took over maintainance
|
||||
and further development of the library after it has been in an orphaned state
|
||||
for a rather long period of time.
|
||||
</para>
|
||||
<para>Apologies for anyone inadvertently missed.</para>
|
||||
</section>
|
||||
|
||||
|
||||
131
doc/build.xml
131
doc/build.xml
@@ -5,7 +5,6 @@
|
||||
%thread.entities;
|
||||
]>
|
||||
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford
|
||||
Copyright (c) 2007 Roland Schwarz
|
||||
Subject to the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
|
||||
-->
|
||||
@@ -26,112 +25,38 @@
|
||||
</para>
|
||||
<section id="thread.build.building">
|
||||
<title>Building the &Boost.Thread; Libraries</title>
|
||||
<para>
|
||||
Building the &Boost.Thread; Library depends on how you intend to use it. You have several options:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
Using as a <link linkend="thread.build.precompiled">precompiled</link> library, possibly
|
||||
with auto-linking, or for use from within an IDE.
|
||||
</listitem>
|
||||
<listitem>
|
||||
Use from a <link linkend="thread.build.bjam">&Boost.Build;</link> project.
|
||||
</listitem>
|
||||
<listitem>
|
||||
Using in <link linkend="thread.build.source">source</link> form.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<section id="thread.build.precompiled">
|
||||
<title>Precompiled</title>
|
||||
<para>
|
||||
Using the &Boost.Thread; library in precompiled form is the way to go if you want to
|
||||
install the library to a standard place, from where your linker is able to resolve code
|
||||
in binary form. You also will want this option if compile time is a concern. Multiple
|
||||
variants are available, for different toolsets and build variants (debug/release).
|
||||
The library files are named <emphasis>{lead}boost_thread{build-specific-tags}.{extension}</emphasis>,
|
||||
where the build-specific-tags indicate the toolset used to build the library, whether it's
|
||||
a debug or release build, what version of &Boost; was used, etc.; and the lead and extension
|
||||
are the appropriate extensions for a dynamic link library or static library for the platform
|
||||
for which &Boost.Thread; is being built.
|
||||
For instance, a debug build of the dynamic library built for Win32 with VC++ 7.1 using Boost 1.34 would
|
||||
be named <emphasis>boost_thread-vc71-mt-gd-1_34.dll</emphasis>.
|
||||
More information on this should be available from the &Boost.Build; documentation.
|
||||
</para>
|
||||
<para>
|
||||
Building should be possible with the default configuration. If you are running into problems,
|
||||
it might be wise to adjust your local settings of &Boost.Build; though. Typically you will
|
||||
need to get your user-config.jam file to reflect your environment, i.e. used toolsets. Please
|
||||
refer to the &Boost.Build; documentation to learn how to do this.
|
||||
</para>
|
||||
<para>
|
||||
To create the libraries you need to open a command shell and change to the
|
||||
<emphasis>boost_root</emphasis> directory. From there you give the command
|
||||
<programlisting>bjam --toolset=<emphasis>mytoolset</emphasis> stage --with-thread</programlisting>
|
||||
Replace <emphasis>mytoolset</emphasis> with the name of your toolset, e.g. msvc-7.1 .
|
||||
This will compile and put the libraries into the <emphasis>stage</emphasis> directory which is just below the
|
||||
<emphasis>boost_root</emphasis> directory. &Boost.Build; by default will generate static and
|
||||
dynamic variants for debug and release.
|
||||
</para>
|
||||
<note>
|
||||
Invoking the above command without the --with-thread switch &Boost.Build; will build all of
|
||||
the Boost distribution, including &Boost.Thread;.
|
||||
</note>
|
||||
<para>
|
||||
The next step is to copy your libraries to a place where your linker is able to pick them up.
|
||||
It is also quite possible to leave them in the stage directory and instruct your IDE to take them
|
||||
from there.
|
||||
</para>
|
||||
<para>
|
||||
In your IDE you then need to add <emphasis>boost_root</emphasis>/boost to the paths where the compiler
|
||||
expects to find files to be included. For toolsets that support <emphasis>auto-linking</emphasis>
|
||||
it is not necessary to explicitly specify the name of the library to link against, it is sufficient
|
||||
to specify the path of the stage directory. Typically this is true on Windows. For gcc you need
|
||||
to specify the exact library name (including all the tags). Please don't forget that threading
|
||||
support must be turned on to be able to use the library. You should be able now to build your
|
||||
project from the IDE.
|
||||
</para>
|
||||
</section>
|
||||
<section id="thread.build.bjam">
|
||||
<title>&Boost.Build; Project</title>
|
||||
<para>
|
||||
If you have decided to use &Boost.Build; as a build environment for your application, you simply
|
||||
need to add a single line to your <emphasis>Jamroot</emphasis> file:
|
||||
<programlisting>use-project /boost : {path-to-boost-root} ;</programlisting>
|
||||
where <emphasis>{path-to-boost-root}</emphasis> needs to be replaced with the location of
|
||||
your copy of the boost tree.
|
||||
Later when you specify a component that needs to link against &Boost.Thread; you specify this
|
||||
as e.g.:
|
||||
<programlisting>exe myapp : {myappsources} /boost//thread ;</programlisting>
|
||||
and you are done.
|
||||
</para>
|
||||
</section>
|
||||
<section id="thread.build.source">
|
||||
<title>Source Form</title>
|
||||
<para>
|
||||
Of course it is also possible to use the &Boost.Thread; library in source form.
|
||||
First you need to specify the <emphasis>boost_root</emphasis>/boost directory as
|
||||
a path where your compiler expects to find files to include. It is not easy
|
||||
to isolate the &Boost.Thread; include files from the rest of the boost
|
||||
library though. You would also need to isolate every include file that the thread
|
||||
library depends on. Next you need to copy the files from
|
||||
<emphasis>boost_root</emphasis>/libs/thread/src to your project and instruct your
|
||||
build system to compile them together with your project. Please look into the
|
||||
<emphasis>Jamfile</emphasis> in <emphasis>boost_root</emphasis>/libs/thread/build
|
||||
to find out which compiler options and defines you will need to get a clean compile.
|
||||
Using the boost library in this way is the least recommended, and should only be
|
||||
considered if avoiding dependency on &Boost.Build; is a requirement. Even if so
|
||||
it might be a better option to use the library in it's precompiled form.
|
||||
Precompiled downloads are available from the boost consulting web site, or as
|
||||
part of most linux distributions.
|
||||
</para>
|
||||
</section>
|
||||
<para>
|
||||
To build the &Boost.Thread; libraries using &Boost.Build;, simply change to the
|
||||
directory <emphasis>boost_root</emphasis>/libs/thread/build and execute the command:
|
||||
<programlisting>bjam -sTOOLS=<emphasis>toolset</emphasis></programlisting>
|
||||
This will create the debug and the release builds of the &Boost.Thread; library.
|
||||
<note>Invoking the above command in <emphasis>boost_root</emphasis> will build all of
|
||||
the Boost distribution, including &Boost.Thread;.</note>
|
||||
</para>
|
||||
<para>
|
||||
The Jamfile supplied with &Boost.Thread; produces a dynamic link library named
|
||||
<emphasis>boost_thread{build-specific-tags}.{extension}</emphasis>, where the build-specific
|
||||
tags indicate the toolset used to build the library, whether it's a debug or release
|
||||
build, what version of Boost was used, etc.; and the extension is the appropriate extension
|
||||
for a dynamic link library for the platform for which &Boost.Thread; is being built.
|
||||
For instance, a debug library built for Win32 with VC++ 7.1 using Boost 1.31 would
|
||||
be named <emphasis>boost_thread-vc71-mt-gd-1_31.dll</emphasis>.
|
||||
</para>
|
||||
<para>
|
||||
The source files that are used to create the &Boost.Thread; library
|
||||
are all of the *.cpp files found in <emphasis>boost_root</emphasis>/libs/thread/src.
|
||||
These need to be built with the compiler's and linker's multi-threading support enabled.
|
||||
If you want to create your own build solution you'll have to follow these same
|
||||
guidelines. One of the most frequently reported problems when trying to do this
|
||||
occurs from not enabling the compiler's and linker's support for multi-threading.
|
||||
</para>
|
||||
</section>
|
||||
<section id="thread.build.testing">
|
||||
<title>Testing the &Boost.Thread; Libraries</title>
|
||||
<para>
|
||||
To test the &Boost.Thread; libraries using &Boost.Build;, simply change to the
|
||||
directory <emphasis>boost_root</emphasis>/libs/thread/test and execute the command:
|
||||
<programlisting>bjam --toolset=<emphasis>mytoolset</emphasis> test</programlisting>
|
||||
To test the &Boost.Thread; libraries using &Boost.Build;, simply change to the
|
||||
directory <emphasis>boost_root</emphasis>/libs/thread/test and execute the command:
|
||||
<programlisting>bjam -sTOOLS=<emphasis>toolset</emphasis> test</programlisting>
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
@@ -18,17 +18,7 @@
|
||||
which allow only one thread at a time to access a resource when it is
|
||||
being modified (the "Write" part of Read/Write), but allows multiple threads
|
||||
to access a resource when it is only being referenced (the "Read" part of
|
||||
Read/Write).</para>
|
||||
<note> Unfortunately it turned out that the current implementation of Read/Write Mutex has
|
||||
some serious problems. So it was decided not to put this implementation into
|
||||
release grade code. Also discussions on the mailing list led to the
|
||||
conclusion that the current concepts need to be rethought. In particular
|
||||
the schedulings <link linkend="thread.concepts.read-write-scheduling-policies.inter-class">
|
||||
Inter-Class Scheduling Policies</link> are deemed unnecessary.
|
||||
There seems to be common belief that a fair scheme suffices.
|
||||
The following documentation has been retained however, to give
|
||||
readers of this document the opportunity to study the original design.
|
||||
</note>
|
||||
Read/Write).</para>
|
||||
|
||||
<section id="thread.concepts.mutexes">
|
||||
<title>Mutexes</title>
|
||||
@@ -749,18 +739,13 @@
|
||||
|
||||
<section id="thread.concepts.read-write-mutexes">
|
||||
<title>Read/Write Mutexes</title>
|
||||
<note> Unfortunately it turned out that the current implementation has
|
||||
some serious problems. So it was decided not to put this implementation into
|
||||
release grade code. Also discussions on the mailing list led to the
|
||||
conclusion that the current concepts need to be rethought. In particular
|
||||
the schedulings <link linkend="thread.concepts.read-write-scheduling-policies.inter-class">
|
||||
Inter-Class Scheduling Policies</link> are deemed unnecessary.
|
||||
There seems to be common belief that a fair scheme suffices.
|
||||
The following documentation has been retained however, to give
|
||||
readers of this document the opportunity to study the original design.
|
||||
</note>
|
||||
<note>Since the read/write mutex and related classes are new,
|
||||
both interface and implementation are liable to change
|
||||
in future releases of &Boost.Thread;.
|
||||
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
|
||||
<para>A read/write mutex (short for reader/writer mutual-exclusion) object
|
||||
is used to serialize access to a resource shared between multiple
|
||||
threads, where multiple "readers" can share simultaneous access, but
|
||||
"writers" require exclusive access. The
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
Subject to the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
|
||||
-->
|
||||
<!ENTITY Boost "<emphasis role='bold'>Boost</emphasis>">
|
||||
<!ENTITY Boost.Thread "<emphasis role='bold'>Boost.Thread</emphasis>">
|
||||
<!ENTITY Boost.Build "<emphasis role='bold'>Boost.Build</emphasis>">
|
||||
<!ENTITY cite.AndrewsSchneider83 "<citation><xref
|
||||
|
||||
@@ -17,12 +17,6 @@
|
||||
<xi:include href="mutex-ref.xml"/>
|
||||
<xi:include href="once-ref.xml"/>
|
||||
<xi:include href="recursive_mutex-ref.xml"/>
|
||||
<!--
|
||||
The read_write_mutex is held back from release, since the
|
||||
implementation suffers from a serious, yet unresolved bug.
|
||||
The implementation is likely to appear in a reworked
|
||||
form in the next release.
|
||||
-->
|
||||
<xi:include href="read_write_mutex-ref.xml"/>
|
||||
<xi:include href="thread-ref.xml"/>
|
||||
<xi:include href="tss-ref.xml"/>
|
||||
|
||||
@@ -10,63 +10,7 @@
|
||||
-->
|
||||
<section id="thread.release_notes" last-revision="$Date$">
|
||||
<title>Release Notes</title>
|
||||
<section id="thread.release_notes.boost_1_34_0">
|
||||
<title>Boost 1.34.0</title>
|
||||
|
||||
<section id="thread.release_notes.boost_1_34_0.change_log.maintainance">
|
||||
<title>New team of maintainers</title>
|
||||
|
||||
<para>
|
||||
Since the original author William E. Kempf no longer is available to
|
||||
maintain the &Boost.Thread; library, a new team has been formed
|
||||
in an attempt to continue the work on &Boost.Thread;.
|
||||
Fortunately William E. Kempf has given
|
||||
<ulink url="http://lists.boost.org/Archives/boost/2006/09/110143.php">
|
||||
permission </ulink>
|
||||
to use his work under the boost license.
|
||||
</para>
|
||||
<para>
|
||||
The team currently consists of
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
Anthony Williams, for the Win32 platform,
|
||||
</listitem>
|
||||
<listitem>
|
||||
Roland Schwarz, for the linux platform, and various "housekeeping" tasks.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
Volunteers for other platforms are welcome!
|
||||
</para>
|
||||
<para>
|
||||
As the &Boost.Thread; was kind of orphaned over the last release, this release
|
||||
attempts to fix the known bugs. Upcoming releases will bring in new things.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="thread.release_notes.boost_1_34_0.change_log.read_write_mutex">
|
||||
<title>read_write_mutex still broken</title>
|
||||
|
||||
<para>
|
||||
<note>
|
||||
It has been decided not to release the Read/Write Mutex, since the current
|
||||
implementation suffers from a serious bug. The documentation of the concepts
|
||||
has been included though, giving the interested reader an opportunity to study the
|
||||
original concepts. Please refer to the following links if you are interested
|
||||
which problems led to the decision to held back this mutex type.The issue
|
||||
has been discovered before 1.33 was released and the code has
|
||||
been omitted from that release. A reworked mutex is expected to appear in 1.35.
|
||||
Also see:
|
||||
<ulink url="http://lists.boost.org/Archives/boost/2005/08/92307.php">
|
||||
read_write_mutex bug</ulink>
|
||||
and
|
||||
<ulink url="http://lists.boost.org/Archives/boost/2005/09/93180.php">
|
||||
read_write_mutex fundamentally broken in 1.33</ulink>
|
||||
</note>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
<section id="thread.release_notes.boost_1_32_0">
|
||||
<section id="thread.release_notes.boost_1_32_0">
|
||||
<title>Boost 1.32.0</title>
|
||||
|
||||
<section id="thread.release_notes.boost_1_32_0.change_log.documentation">
|
||||
|
||||
@@ -264,7 +264,20 @@
|
||||
<effects>Calls <code>join()</code> on each of the managed
|
||||
<classname>thread</classname> objects.</effects>
|
||||
</method>
|
||||
</method-group>
|
||||
</method-group>
|
||||
|
||||
<method-group name="capacity">
|
||||
|
||||
<method name="size" cv="const">
|
||||
<type>int</type>
|
||||
|
||||
<returns>the number of <classname>thread</classname>
|
||||
objects in the group
|
||||
</returns>
|
||||
|
||||
</method>
|
||||
|
||||
</method-group>
|
||||
</class>
|
||||
</namespace>
|
||||
</header>
|
||||
|
||||
@@ -29,7 +29,7 @@ private:
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4251 4231 4660 4275)
|
||||
#endif
|
||||
#endif
|
||||
condition m_cond;
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
|
||||
@@ -28,7 +28,6 @@ struct xtime;
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4251 4231 4660 4275)
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
class BOOST_THREAD_DECL condition_impl : private noncopyable
|
||||
|
||||
@@ -29,7 +29,6 @@ struct xtime;
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4251 4231 4660 4275)
|
||||
#endif
|
||||
|
||||
class BOOST_THREAD_DECL mutex
|
||||
: private noncopyable
|
||||
{
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
#ifndef BOOST_READ_WRITE_MUTEX_JDM030602_HPP
|
||||
#define BOOST_READ_WRITE_MUTEX_JDM030602_HPP
|
||||
|
||||
#error Read Write Mutex is broken, do not include this header
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#include <boost/utility.hpp>
|
||||
@@ -55,7 +53,7 @@ struct read_write_mutex_impl
|
||||
typedef detail::thread::scoped_timed_lock<Mutex> scoped_timed_lock;
|
||||
|
||||
read_write_mutex_impl(read_write_scheduling_policy::read_write_scheduling_policy_enum sp);
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(582))
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__,<= 0x564)
|
||||
~read_write_mutex_impl();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ public:
|
||||
void add_thread(thread* thrd);
|
||||
void remove_thread(thread* thrd);
|
||||
void join_all();
|
||||
int size();
|
||||
int size() const;
|
||||
|
||||
private:
|
||||
std::list<thread*> m_threads;
|
||||
|
||||
@@ -45,7 +45,6 @@ public:
|
||||
throw boost::thread_resource_error();
|
||||
}
|
||||
}
|
||||
|
||||
~tss();
|
||||
void* get() const;
|
||||
void set(void* value);
|
||||
|
||||
@@ -27,12 +27,6 @@
|
||||
# include "mac/safe.hpp"
|
||||
#endif
|
||||
|
||||
// The following include can be removed after the bug on QNX
|
||||
// has been tracked down. I need this only for debugging
|
||||
//#if !defined(NDEBUG) && defined(BOOST_HAS_PTHREADS)
|
||||
#include <iostream>
|
||||
//#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail {
|
||||
@@ -379,20 +373,6 @@ bool condition_impl::do_timed_wait(const xtime& xt, pthread_mutex_t* pmutex)
|
||||
|
||||
int res = 0;
|
||||
res = pthread_cond_timedwait(&m_condition, pmutex, &ts);
|
||||
// Test code for QNX debugging, to get information during regressions
|
||||
#ifndef NDEBUG
|
||||
if (res == EINVAL) {
|
||||
boost::xtime now;
|
||||
boost::xtime_get(&now, boost::TIME_UTC);
|
||||
std::cerr << "now: " << now.sec << " " << now.nsec << std::endl;
|
||||
std::cerr << "time: " << time(0) << std::endl;
|
||||
std::cerr << "xtime: " << xt.sec << " " << xt.nsec << std::endl;
|
||||
std::cerr << "ts: " << ts.tv_sec << " " << ts.tv_nsec << std::endl;
|
||||
std::cerr << "pmutex: " << pmutex << std::endl;
|
||||
std::cerr << "condition: " << &m_condition << std::endl;
|
||||
assert(res != EINVAL);
|
||||
}
|
||||
#endif
|
||||
assert(res == 0 || res == ETIMEDOUT);
|
||||
|
||||
return res != ETIMEDOUT;
|
||||
|
||||
@@ -62,8 +62,10 @@ inline void* new_critical_section()
|
||||
inline void* new_mutex(const char* name)
|
||||
{
|
||||
#if defined(BOOST_NO_ANSI_APIS)
|
||||
USES_CONVERSION;
|
||||
HANDLE mutex = CreateMutexW(0, 0, A2CW(name));
|
||||
int num_wide_chars = (strlen(name) + 1);
|
||||
LPWSTR wide_name = (LPWSTR)_alloca( num_wide_chars * 2 );
|
||||
::MultiByteToWideChar(CP_ACP, 0, name, -1, wide_name, num_wide_chars);
|
||||
HANDLE mutex = CreateMutexW(0, 0, wide_name);
|
||||
#else
|
||||
HANDLE mutex = CreateMutexA(0, 0, name);
|
||||
#endif
|
||||
|
||||
16
src/once.cpp
16
src/once.cpp
@@ -9,6 +9,7 @@
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <boost/thread/once.hpp>
|
||||
#include <boost/thread/exceptions.hpp>
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
||||
@@ -18,6 +19,7 @@
|
||||
using std::size_t;
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# include "mutex.inl"
|
||||
# if defined(BOOST_NO_STRINGSTREAM)
|
||||
# include <strstream>
|
||||
|
||||
@@ -114,11 +116,8 @@ inline LONG ice_wrapper(LPVOID (__stdcall *ice)(LPVOID*, LPVOID, LPVOID),
|
||||
inline LONG compare_exchange(volatile LPLONG dest, LONG exch, LONG cmp)
|
||||
{
|
||||
#ifdef _WIN64
|
||||
// Original patch from Anthony Williams.
|
||||
// I (Roland Schwarz) am trying this for RC_1_34_0, since x64 regressions are
|
||||
// currently not run on x64 platforms for HEAD
|
||||
return InterlockedCompareExchange(dest, exch,cmp);
|
||||
#else
|
||||
return InterlockedCompareExchange(dest, exch, cmp);
|
||||
#else
|
||||
return ice_wrapper(&InterlockedCompareExchange, dest, exch, cmp);
|
||||
#endif
|
||||
}
|
||||
@@ -140,12 +139,7 @@ void call_once(void (*func)(), once_flag& flag)
|
||||
<< &flag
|
||||
<< std::ends;
|
||||
unfreezer unfreeze(strm);
|
||||
# if defined (BOOST_NO_ANSI_APIS)
|
||||
USES_CONVERSION;
|
||||
HANDLE mutex = CreateMutexW(NULL, FALSE, A2CW(strm.str()));
|
||||
# else
|
||||
HANDLE mutex = CreateMutexA(NULL, FALSE, strm.str());
|
||||
# endif
|
||||
HANDLE mutex=new_mutex(strm.str());
|
||||
#else
|
||||
# if defined (BOOST_NO_ANSI_APIS)
|
||||
std::wostringstream strm;
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
/*
|
||||
PROBLEMS:
|
||||
|
||||
The read write mutex currently is broken. Do not use it.
|
||||
The file is supplied just for reference.
|
||||
|
||||
The algorithms are not exception safe. For instance, if conditon::wait()
|
||||
or another call throws an exception, the lock state and other state data
|
||||
are not appropriately adjusted.
|
||||
@@ -377,10 +374,7 @@ read_write_mutex_impl<Mutex>::read_write_mutex_impl(read_write_scheduling_policy
|
||||
, m_readers_next(true)
|
||||
{}
|
||||
|
||||
// Borland requires base class destructors to be explicitly exported from DLL's
|
||||
// even if they're not explicitly called. As this only contains postconditions,
|
||||
// it's reasonably safe to comment it out - Nicola Musatti 5/5/2006
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(582))
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, <= 0x564)
|
||||
template<typename Mutex>
|
||||
read_write_mutex_impl<Mutex>::~read_write_mutex_impl()
|
||||
{
|
||||
|
||||
@@ -291,8 +291,7 @@ recursive_mutex::recursive_mutex()
|
||||
|
||||
res = pthread_mutex_init(&m_mutex, &attr);
|
||||
{
|
||||
int res = 0;
|
||||
res = pthread_mutexattr_destroy(&attr);
|
||||
int res = pthread_mutexattr_destroy(&attr);
|
||||
assert(res == 0);
|
||||
}
|
||||
if (res != 0)
|
||||
@@ -448,8 +447,7 @@ recursive_try_mutex::recursive_try_mutex()
|
||||
|
||||
res = pthread_mutex_init(&m_mutex, &attr);
|
||||
{
|
||||
int res = 0;
|
||||
res = pthread_mutexattr_destroy(&attr);
|
||||
int res = pthread_mutexattr_destroy(&attr);
|
||||
assert(res == 0);
|
||||
}
|
||||
if (res != 0)
|
||||
|
||||
@@ -89,6 +89,18 @@ public:
|
||||
bool m_started;
|
||||
};
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
|
||||
struct on_thread_exit_guard
|
||||
{
|
||||
~on_thread_exit_guard()
|
||||
{
|
||||
on_thread_exit();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
extern "C" {
|
||||
@@ -100,22 +112,25 @@ extern "C" {
|
||||
static OSStatus thread_proxy(void* param)
|
||||
#endif
|
||||
{
|
||||
//try
|
||||
//{
|
||||
// try
|
||||
{
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
|
||||
on_thread_exit_guard guard;
|
||||
|
||||
#endif
|
||||
|
||||
thread_param* p = static_cast<thread_param*>(param);
|
||||
boost::function0<void> threadfunc = p->m_threadfunc;
|
||||
p->started();
|
||||
threadfunc();
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
on_thread_exit();
|
||||
#endif
|
||||
//}
|
||||
//catch (...)
|
||||
//{
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
// on_thread_exit();
|
||||
#endif
|
||||
//}
|
||||
}
|
||||
// catch (...)
|
||||
// {
|
||||
//#if defined(BOOST_HAS_WINTHREADS)
|
||||
// on_thread_exit();
|
||||
//#endif
|
||||
// }
|
||||
#if defined(BOOST_HAS_MPTASKS)
|
||||
::boost::detail::thread_cleanup();
|
||||
#endif
|
||||
@@ -363,7 +378,7 @@ void thread_group::join_all()
|
||||
}
|
||||
}
|
||||
|
||||
int thread_group::size()
|
||||
int thread_group::size() const
|
||||
{
|
||||
return m_threads.size();
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// boostinspect:nounnamed
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -84,8 +84,7 @@ extern "C" void cleanup_slots(void* p)
|
||||
|
||||
void init_tss_data()
|
||||
{
|
||||
std::auto_ptr<tss_data_cleanup_handlers_type>
|
||||
temp(new tss_data_cleanup_handlers_type);
|
||||
std::auto_ptr<tss_data_cleanup_handlers_type> temp(new tss_data_cleanup_handlers_type);
|
||||
|
||||
std::auto_ptr<boost::mutex> temp_mutex(new boost::mutex);
|
||||
if (temp_mutex.get() == 0)
|
||||
@@ -99,6 +98,7 @@ void init_tss_data()
|
||||
tss_data_native_key = TlsAlloc();
|
||||
if (tss_data_native_key == 0xFFFFFFFF)
|
||||
return;
|
||||
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
int res = pthread_key_create(&tss_data_native_key, &cleanup_slots);
|
||||
if (res != 0)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// Copyright (C) 2004 Michael Glassford
|
||||
// Copyright (C) 2006 Roland Schwarz
|
||||
// (C) Copyright Michael Glassford 2004.
|
||||
// Copyright (c) 2006 Peter Dimov
|
||||
// Copyright (c) 2006 Anthony Williams
|
||||
//
|
||||
// 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)
|
||||
@@ -8,205 +10,152 @@
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
|
||||
#include <boost/thread/detail/tss_hooks.hpp>
|
||||
#include <boost/thread/detail/tss_hooks.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
// #include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/once.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/thread/once.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <list>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
namespace
|
||||
namespace
|
||||
{
|
||||
|
||||
typedef std::list<thread_exit_handler> thread_exit_handlers;
|
||||
|
||||
const DWORD invalid_tls_key = TLS_OUT_OF_INDEXES;
|
||||
DWORD tls_key = invalid_tls_key;
|
||||
|
||||
boost::once_flag once_init_tls_key = BOOST_ONCE_INIT;
|
||||
|
||||
void init_tls_key()
|
||||
{
|
||||
tls_key = TlsAlloc();
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
extern "C" BOOST_THREAD_DECL int at_thread_exit( thread_exit_handler exit_handler )
|
||||
{
|
||||
boost::call_once( init_tls_key, once_init_tls_key );
|
||||
|
||||
if( tls_key == invalid_tls_key )
|
||||
{
|
||||
class CScopedCSLock
|
||||
{
|
||||
public:
|
||||
CScopedCSLock(LPCRITICAL_SECTION cs) : cs(cs), lk(true) {
|
||||
::EnterCriticalSection(cs);
|
||||
}
|
||||
~CScopedCSLock() {
|
||||
if (lk) ::LeaveCriticalSection(cs);
|
||||
}
|
||||
void Unlock() {
|
||||
lk = false;
|
||||
::LeaveCriticalSection(cs);
|
||||
}
|
||||
private:
|
||||
bool lk;
|
||||
LPCRITICAL_SECTION cs;
|
||||
};
|
||||
|
||||
typedef std::list<thread_exit_handler> thread_exit_handlers;
|
||||
|
||||
boost::once_flag once_init_threadmon_mutex = BOOST_ONCE_INIT;
|
||||
//boost::mutex* threadmon_mutex;
|
||||
// We don't use boost::mutex here, to avoid a memory leak report,
|
||||
// because we cannot delete it again easily.
|
||||
CRITICAL_SECTION threadmon_mutex;
|
||||
void init_threadmon_mutex(void)
|
||||
{
|
||||
//threadmon_mutex = new boost::mutex;
|
||||
//if (!threadmon_mutex)
|
||||
// throw boost::thread_resource_error();
|
||||
::InitializeCriticalSection(&threadmon_mutex);
|
||||
}
|
||||
|
||||
const DWORD invalid_tls_key = TLS_OUT_OF_INDEXES;
|
||||
DWORD tls_key = invalid_tls_key;
|
||||
|
||||
unsigned long attached_thread_count = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
// Get the exit handlers list for the current thread from tls.
|
||||
|
||||
extern "C" BOOST_THREAD_DECL int at_thread_exit(
|
||||
thread_exit_handler exit_handler
|
||||
)
|
||||
thread_exit_handlers* exit_handlers =
|
||||
static_cast< thread_exit_handlers* >( TlsGetValue( tls_key ) );
|
||||
|
||||
if( exit_handlers == 0 )
|
||||
{
|
||||
boost::call_once(init_threadmon_mutex, once_init_threadmon_mutex);
|
||||
//boost::mutex::scoped_lock lock(*threadmon_mutex);
|
||||
CScopedCSLock 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.
|
||||
// No exit handlers list was created yet.
|
||||
|
||||
try
|
||||
{
|
||||
exit_handlers->push_front(exit_handler);
|
||||
// Attempt to create a new exit handlers list.
|
||||
|
||||
exit_handlers = new thread_exit_handlers;
|
||||
|
||||
if( exit_handlers == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Attempt to store the list pointer in tls.
|
||||
|
||||
if( !TlsSetValue( tls_key, exit_handlers ) )
|
||||
{
|
||||
delete exit_handlers;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
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);
|
||||
CScopedCSLock lock(&threadmon_mutex);
|
||||
// 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.
|
||||
|
||||
BOOST_ASSERT(attached_thread_count == 0);
|
||||
try
|
||||
{
|
||||
exit_handlers->push_front( exit_handler );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" BOOST_THREAD_DECL void on_process_exit(void)
|
||||
// Like the atexit() function, a result of zero
|
||||
// indicates success.
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" BOOST_THREAD_DECL void on_process_enter()
|
||||
{
|
||||
}
|
||||
|
||||
extern "C" BOOST_THREAD_DECL void on_process_exit()
|
||||
{
|
||||
if( tls_key != invalid_tls_key )
|
||||
{
|
||||
boost::call_once(init_threadmon_mutex, once_init_threadmon_mutex);
|
||||
// boost::mutex::scoped_lock lock(*threadmon_mutex);
|
||||
CScopedCSLock lock(&threadmon_mutex);
|
||||
TlsFree(tls_key);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_ASSERT(attached_thread_count == 0);
|
||||
extern "C" BOOST_THREAD_DECL void on_thread_enter()
|
||||
{
|
||||
}
|
||||
|
||||
//Free the tls slot if one was allocated.
|
||||
extern "C" BOOST_THREAD_DECL void on_thread_exit()
|
||||
{
|
||||
// Initializing tls_key here ensures its proper visibility
|
||||
boost::call_once( init_tls_key, once_init_tls_key );
|
||||
|
||||
if (tls_key != invalid_tls_key)
|
||||
// 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, invoke its handlers.
|
||||
|
||||
if( exit_handlers != 0 )
|
||||
{
|
||||
// Call each handler and remove it from the list
|
||||
|
||||
while( !exit_handlers->empty() )
|
||||
{
|
||||
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);
|
||||
CScopedCSLock 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();
|
||||
lock.Unlock();
|
||||
|
||||
//Call each handler and remove it from the list
|
||||
|
||||
while (!exit_handlers->empty())
|
||||
if( thread_exit_handler exit_handler = *exit_handlers->begin() )
|
||||
{
|
||||
if (thread_exit_handler exit_handler = *exit_handlers->begin())
|
||||
(*exit_handler)();
|
||||
exit_handlers->pop_front();
|
||||
(*exit_handler)();
|
||||
}
|
||||
|
||||
exit_handlers->pop_front();
|
||||
}
|
||||
|
||||
// If TlsSetValue fails, we can't delete the list,
|
||||
// since a second call to on_thread_exit will try
|
||||
// to access it.
|
||||
|
||||
if( TlsSetValue( tls_key, 0 ) )
|
||||
{
|
||||
delete exit_handlers;
|
||||
exit_handlers = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif //defined(BOOST_HAS_WINTHREADS)
|
||||
|
||||
@@ -40,6 +40,6 @@ rule thread-run ( sources )
|
||||
[ thread-run test_once.cpp ]
|
||||
[ thread-run test_xtime.cpp ]
|
||||
[ thread-run test_barrier.cpp ]
|
||||
# [ thread-run test_read_write_mutex.cpp ]
|
||||
[ thread-run test_read_write_mutex.cpp ]
|
||||
;
|
||||
}
|
||||
|
||||
@@ -144,11 +144,12 @@ void do_test_tss()
|
||||
<< "\n";
|
||||
std::cout.flush();
|
||||
|
||||
// The following is not really an error. TSS cleanup support still is available for boost threads.
|
||||
// Also this usually will be triggered only when bound to the static version of thread lib.
|
||||
// 2006-10-02 Roland Schwarz
|
||||
// The following is not really an error. TSS cleanup support still is available
|
||||
// for threads, launched via the boost API. Also this usually will be triggered
|
||||
// only when bound to the static version of the thread lib.
|
||||
// 2006-10-15 Roland Schwarz
|
||||
//BOOST_CHECK_EQUAL(tss_instances, 0);
|
||||
BOOST_CHECK_MESSAGE(tss_instances == 0, "Support of automatic tss cleanup for native threading API not available");
|
||||
BOOST_CHECK_MESSAGE(tss_instances ==0, "Support of automatic tss cleanup for native threading API not available");
|
||||
BOOST_CHECK_EQUAL(tss_total, 5);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
# define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_condition
|
||||
#endif
|
||||
|
||||
// boostinspect:nounnamed
|
||||
|
||||
namespace
|
||||
{
|
||||
inline boost::xtime delay(int secs, int msecs=0, int nsecs=0)
|
||||
|
||||
34
tutorial/Jamfile
Normal file
34
tutorial/Jamfile
Normal file
@@ -0,0 +1,34 @@
|
||||
# Copyright (C) 2001-2003
|
||||
# William E. Kempf
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# Boost.Threads tutorial 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"
|
||||
|
||||
project
|
||||
: requirements <library>/boost/thread//boost_thread
|
||||
<threading>multi
|
||||
;
|
||||
|
||||
exe helloworld : helloworld.cpp ;
|
||||
exe helloworld2 : helloworld2.cpp ;
|
||||
exe helloworld3 : helloworld3.cpp ;
|
||||
exe helloworld4 : helloworld4.cpp ;
|
||||
exe factorial : factorial.cpp ;
|
||||
exe factorial2 : factorial2.cpp ;
|
||||
exe factorial3 : factorial3.cpp ;
|
||||
exe counter : counter.cpp ;
|
||||
exe bounded_buffer : bounded_buffer.cpp ;
|
||||
exe once : once.cpp ;
|
||||
|
||||
Reference in New Issue
Block a user