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

Compare commits

..

6 Commits

Author SHA1 Message Date
nobody
52a53be89b This commit was manufactured by cvs2svn to create tag
'Version_1_32_0'.

[SVN r26264]
2004-11-19 19:19:18 +00:00
Aleksey Gurtovoy
701a8fc4b5 fix invalid <p> tags
[SVN r26236]
2004-11-18 23:55:33 +00:00
Aleksey Gurtovoy
606fabcbd6 fix line endings
[SVN r26003]
2004-10-31 09:38:17 +00:00
Aleksey Gurtovoy
6d41e62c1c fix BoostBook/broken links/invalid filenames/etc.
[SVN r25933]
2004-10-29 10:23:48 +00:00
Aleksey Gurtovoy
643b8e7b79 fix BoostBook/broken links/invalid filenames/etc.
[SVN r25931]
2004-10-29 09:40:12 +00:00
nobody
76c5ae79b5 This commit was manufactured by cvs2svn to create branch 'RC_1_32_0'.
[SVN r25797]
2004-10-20 08:26:43 +00:00
97 changed files with 2171 additions and 3024 deletions

View File

@@ -1,8 +1,13 @@
# Copyright (C) 2001-2003 # Copyright (C) 2001-2003
# William E. Kempf # William E. Kempf
# #
# Distributed under the Boost Software License, Version 1.0. (See accompanying # Permission to use, copy, modify, distribute and sell this software
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # and its documentation for any purpose is hereby granted without fee,
# provided that the above copyright notice appear in all copies and
# that both that copyright notice and this permission notice appear
# in supporting documentation. William E. Kempf makes no representations
# about the suitability of this software for any purpose.
# It is provided "as is" without express or implied warranty.
# #
# Boost.Threads build Jamfile # Boost.Threads build Jamfile
# #
@@ -41,6 +46,7 @@ import ./threads ;
: ## requirements ## : ## requirements ##
<sysinclude>$(BOOST_ROOT) #:should be unnecessary (because already included in thread_base) <sysinclude>$(BOOST_ROOT) #:should be unnecessary (because already included in thread_base)
<define>BOOST_THREAD_BUILD_LIB=1 <define>BOOST_THREAD_BUILD_LIB=1
<runtime-link>static
# the common names rule ensures that the library will # the common names rule ensures that the library will
# be named according to the rules used by the install # be named according to the rules used by the install
# and auto-link features: # and auto-link features:
@@ -96,8 +102,7 @@ import ./threads ;
<template>boost_thread_lib_base <template>boost_thread_lib_base
: ## requirements ## : ## requirements ##
<define>BOOST_THREAD_LIB_NAME=$(boost_thread_lib_name_ptw32) <define>BOOST_THREAD_LIB_NAME=$(boost_thread_lib_name_ptw32)
$(boost_thread_lib_settings_ptw32) $(pthreads-win32)
: ## default build ##
; ;
dll $(boost_thread_lib_name_ptw32) dll $(boost_thread_lib_name_ptw32)
@@ -105,8 +110,7 @@ import ./threads ;
<template>boost_thread_dll_base <template>boost_thread_dll_base
: ## requirements ## : ## requirements ##
<define>BOOST_THREAD_LIB_NAME=$(boost_thread_lib_name_ptw32) <define>BOOST_THREAD_LIB_NAME=$(boost_thread_lib_name_ptw32)
$(boost_thread_lib_settings_ptw32) $(pthreads-win32)
: ## default build ##
; ;
stage bin-stage stage bin-stage

View File

@@ -1,39 +1,26 @@
# (C) Copyright Vladimir Prus, David Abrahams, Michael Stevens, Hartmut Kaiser,
# William E Kempf 2002-2006
# 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)
import os ; 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 ;
}
project boost/thread project boost/thread
: source-location ../src : source-location ../src
: requirements <link>shared:<define>BOOST_THREAD_BUILD_DLL=1 <threading>multi : usage-requirements $(usage)
: requirements $(reqts) <threading>multi
: default-build <threading>multi : default-build <threading>multi
; ;
CPP_SOURCES = CPP_SOURCES = condition mutex recursive_mutex thread xtime once
barrier exceptions barrier tss tss_hooks tss_dll tss_pe ;
condition
exceptions
mutex
once
recursive_mutex
read_write_mutex
thread
tss_hooks
tss_dll
tss_pe
tss
xtime
;
lib boost_thread lib boost_thread
: $(CPP_SOURCES).cpp : $(CPP_SOURCES).cpp
: <link>shared:<define>BOOST_THREAD_BUILD_DLL=1
<link>static:<define>BOOST_THREAD_BUILD_LIB=1
: # default build
: <link>shared:<define>BOOST_THREAD_BUILD_DLL=1
<link>static:<define>BOOST_THREAD_BUILD_LIB=1
; ;

View File

@@ -1,8 +1,13 @@
# Copyright (C) 2001-2003 # Copyright (C) 2001-2003
# William E. Kempf # William E. Kempf
# #
# Distributed under the Boost Software License, Version 1.0. (See accompanying # Permission to use, copy, modify, distribute and sell this software
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # 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.
# Additional configuration variables used: # Additional configuration variables used:
# 1. PTW32_DIR and PTW32_LIB may be used on Win32 platforms to specify that # 1. PTW32_DIR and PTW32_LIB may be used on Win32 platforms to specify that

View File

@@ -1,8 +1,3 @@
# 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)
import toolset ; import toolset ;
toolset.using doxygen ; toolset.using doxygen ;

View File

@@ -1,18 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<section id="thread.acknowledgements" <section id="thread.acknowledgements"
last-revision="$Date$"> last-revision="$Date$">
<title>Acknowledgements</title> <title>Acknowledgements</title>
<para>William E. Kempf was the architect, designer, and implementor of <para>William E. Kempf was the architect, designer, and implementor of
&Boost.Thread;.</para> &Boost.Threads;.</para>
<para>Mac OS Carbon implementation written by Mac Murrett.</para> <para>Mac OS Carbon implementation written by Mac Murrett.</para>
<para>Dave Moore provided initial submissions and further comments on the <para>Dave Moore provided initial submissions and further comments on the
<code>barrier</code> <code>barrier</code>
@@ -32,7 +28,7 @@ last-revision="$Date$">
on the design), Paul Mclachlan, Thomas Matelich and Iain Hanson (for help on the design), Paul Mclachlan, Thomas Matelich and Iain Hanson (for help
in trying to get the build to work on other platforms), and Kevin S. Van in trying to get the build to work on other platforms), and Kevin S. Van
Horn (for several updates/corrections to the documentation).</para> Horn (for several updates/corrections to the documentation).</para>
<para>Mike Glassford finished changes to &Boost.Thread; that were begun <para>Mike Glassford finished changes to &Boost.Threads; that were begun
by William Kempf and moved them into the main CVS branch. by William Kempf and moved them into the main CVS branch.
He also addressed a number of issues that were brought up on the Boost He also addressed a number of issues that were brought up on the Boost
developer's mailing list and provided some additions and changes to the developer's mailing list and provided some additions and changes to the
@@ -42,7 +38,7 @@ last-revision="$Date$">
Mike Glassford finished William Kempf's conversion of the documentation to Mike Glassford finished William Kempf's conversion of the documentation to
BoostBook format and added a number of new sections.</para> BoostBook format and added a number of new sections.</para>
<para>Discussions on the boost.org mailing list were essential in the <para>Discussions on the boost.org mailing list were essential in the
development of &Boost.Thread; development of &Boost.Threads;
. As of August 1, 2001, participants included Alan Griffiths, Albrecht . As of August 1, 2001, participants included Alan Griffiths, Albrecht
Fritzsche, Aleksey Gurtovoy, Alexander Terekhov, Andrew Green, Andy Sawyer, Fritzsche, Aleksey Gurtovoy, Alexander Terekhov, Andrew Green, Andy Sawyer,
Asger Alstrup Nielsen, Beman Dawes, Bill Klein, Bill Rutiser, Bill Wade, Asger Alstrup Nielsen, Beman Dawes, Bill Klein, Bill Rutiser, Bill Wade,

View File

@@ -1,13 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<header name="boost/thread/barrier.hpp" <header name="boost/thread/barrier.hpp"
last-revision="$Date$"> last-revision="$Date$">
<namespace name="boost"> <namespace name="boost">
@@ -36,9 +32,9 @@
and reset the barrier. This functionality allows the same set of N threads to re-use and reset the barrier. This functionality allows the same set of N threads to re-use
a barrier object to synchronize their execution at multiple points during their a barrier object to synchronize their execution at multiple points during their
execution.</para> execution.</para>
<para>See <xref linkend="thread.glossary"/> for definitions of thread <para>See <xref linkend="threads.glossary"/> for definitions of thread
states <link linkend="thread.glossary.thread-state">blocked</link> states <link linkend="threads.glossary.thread-state">blocked</link>
and <link linkend="thread.glossary.thread-state">ready</link>. and <link linkend="threads.glossary.thread-state">ready</link>.
Note that "waiting" is a synonym for blocked.</para> Note that "waiting" is a synonym for blocked.</para>
</description> </description>

View File

@@ -1,18 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford <bibliography id="threads.bibliography"
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<bibliography id="thread.bibliography"
last-revision="$Date$"> last-revision="$Date$">
<title>Bibliography</title> <title>Bibliography</title>
<biblioentry id="thread.bib.AndrewsSchneider83"> <biblioentry id="threads.bib.AndrewsSchneider83">
<abbrev id="thread.bib.AndrewsSchneider83.abbrev">AndrewsSchnieder83</abbrev> <abbrev id="threads.bib.AndrewsSchneider83.abbrev">AndrewsSchnieder83</abbrev>
<biblioset relation="journal"> <biblioset relation="journal">
<title>ACM Computing Surveys</title> <title>ACM Computing Surveys</title>
<volumenum>Vol. 15</volumenum> <volumenum>Vol. 15</volumenum>
@@ -42,23 +38,23 @@ last-revision="$Date$">
Expressions, Message Passing, and Remote Procedure Call in addition to the Expressions, Message Passing, and Remote Procedure Call in addition to the
basics</para> basics</para>
</biblioentry> </biblioentry>
<biblioentry id="thread.bib.Boost"> <biblioentry id="threads.bib.Boost">
<abbrev id="thread.bib.Boost.abbrev">Boost</abbrev> <abbrev id="threads.bib.Boost.abbrev">Boost</abbrev>
<bibliomisc>The <emphasis>Boost</emphasis> world wide web site. <bibliomisc>The <emphasis>Boost</emphasis> world wide web site.
<ulink url="http:/www.boost.org">http://www.boost.org</ulink></bibliomisc> <ulink url="http:/www.boost.org">http://www.boost.org</ulink></bibliomisc>
<para>&Boost.Thread; is one of many Boost libraries. The Boost web <para>&Boost.Threads; is one of many Boost libraries. The Boost web
site includes a great deal of documentation and general information which site includes a great deal of documentation and general information which
applies to all Boost libraries. Current copies of the libraries including applies to all Boost libraries. Current copies of the libraries including
documentation and test programs may be downloaded from the web documentation and test programs may be downloaded from the web
site.</para> site.</para>
</biblioentry> </biblioentry>
<biblioentry id="thread.bib.Hansen73"> <biblioentry id="threads.bib.Hansen73">
<abbrev id="thread.bib.Hansen73.abbrev">Hansen73</abbrev> <abbrev id="threads.bib.Hansen73.abbrev">Hansen73</abbrev>
<biblioset relation="journal"> <biblioset relation="journal">
<title>ACM Computing Surveys</title> <title>ACM Computing Surveys</title>
<volumenum>Vol. 5</volumenum> <volumenum>Vol. 5</volumenum>
<issuenum>No. 4</issuenum> <issuenum>No. 4</issuenum>
<date>December, 1973</date> <date>December, 1983</date>
</biblioset> </biblioset>
<biblioset relation="article"> <biblioset relation="article">
<author>0-201-63392-2 <author>0-201-63392-2
@@ -78,8 +74,8 @@ last-revision="$Date$">
Brinch Hansen was years ahead of others in recognizing pattern concepts Brinch Hansen was years ahead of others in recognizing pattern concepts
applied to software, too.</para> applied to software, too.</para>
</biblioentry> </biblioentry>
<biblioentry id="thread.bib.Butenhof97"> <biblioentry id="threads.bib.Butenhof97">
<abbrev id="thread.bib.Butenhof97.abbrev">Butenhof97</abbrev> <abbrev id="threads.bib.Butenhof97.abbrev">Butenhof97</abbrev>
<title> <title>
<ulink url="http://cseng.aw.com/book/0,3828,0201633922,00.html" <ulink url="http://cseng.aw.com/book/0,3828,0201633922,00.html"
>Programming with POSIX Threads </ulink> >Programming with POSIX Threads </ulink>
@@ -96,8 +92,8 @@ last-revision="$Date$">
them. Many of the insights given apply to all multithreaded programming, not them. Many of the insights given apply to all multithreaded programming, not
just POSIX Threads</para> just POSIX Threads</para>
</biblioentry> </biblioentry>
<biblioentry id="thread.bib.Hoare74"> <biblioentry id="threads.bib.Hoare74">
<abbrev id="thread.bib.Hoare74.abbrev">Hoare74</abbrev> <abbrev id="threads.bib.Hoare74.abbrev">Hoare74</abbrev>
<biblioset relation="journal"> <biblioset relation="journal">
<title>Communications of the ACM</title> <title>Communications of the ACM</title>
<volumenum>Vol. 17</volumenum> <volumenum>Vol. 17</volumenum>
@@ -119,8 +115,8 @@ last-revision="$Date$">
multithreading patterns. This is one of the most often referenced papers in multithreading patterns. This is one of the most often referenced papers in
all of computer science, and with good reason.</para> all of computer science, and with good reason.</para>
</biblioentry> </biblioentry>
<biblioentry id="thread.bib.ISO98"> <biblioentry id="threads.bib.ISO98">
<abbrev id="thread.bib.ISO98.abbrev">ISO98</abbrev> <abbrev id="threads.bib.ISO98.abbrev">ISO98</abbrev>
<title> <title>
<ulink url="http://www.ansi.org">Programming Language C++</ulink> <ulink url="http://www.ansi.org">Programming Language C++</ulink>
</title> </title>
@@ -129,8 +125,8 @@ last-revision="$Date$">
<para>This is the official C++ Standards document. Available from the ANSI <para>This is the official C++ Standards document. Available from the ANSI
(American National Standards Institute) Electronic Standards Store.</para> (American National Standards Institute) Electronic Standards Store.</para>
</biblioentry> </biblioentry>
<biblioentry id="thread.bib.McDowellHelmbold89"> <biblioentry id="threads.bib.McDowellHelmbold89">
<abbrev id="thread.bib.McDowellHelmbold89.abbrev">McDowellHelmbold89</abbrev> <abbrev id="threads.bib.McDowellHelmbold89.abbrev">McDowellHelmbold89</abbrev>
<biblioset relation="journal"> <biblioset relation="journal">
<title>Communications of the ACM</title> <title>Communications of the ACM</title>
<volumenum>Vol. 21</volumenum> <volumenum>Vol. 21</volumenum>
@@ -157,8 +153,8 @@ last-revision="$Date$">
<para>Identifies many of the unique failure modes and debugging difficulties <para>Identifies many of the unique failure modes and debugging difficulties
associated with concurrent programs.</para> associated with concurrent programs.</para>
</biblioentry> </biblioentry>
<biblioentry id="thread.bib.SchmidtPyarali"> <biblioentry id="threads.bib.SchmidtPyarali">
<abbrev id="thread.bib.SchmidtPyarali.abbrev">SchmidtPyarali</abbrev> <abbrev id="threads.bib.SchmidtPyarali.abbrev">SchmidtPyarali</abbrev>
<title> <title>
<ulink url="http://www.cs.wustl.edu/~schmidt/win32-cv-1.html8" <ulink url="http://www.cs.wustl.edu/~schmidt/win32-cv-1.html8"
>Strategies for Implementing POSIX Condition Variables on Win32</ulink> >Strategies for Implementing POSIX Condition Variables on Win32</ulink>
@@ -176,14 +172,14 @@ last-revision="$Date$">
</authorgroup> </authorgroup>
<orgname>Department of Computer Science, Washington University, St. Louis, <orgname>Department of Computer Science, Washington University, St. Louis,
Missouri</orgname> Missouri</orgname>
<para>Rationale for understanding &Boost.Thread; condition <para>Rationale for understanding &Boost.Threads; condition
variables. Note that Alexander Terekhov found some bugs in the variables. Note that Alexander Terekhov found some bugs in the
implementation given in this article, so pthreads-win32 and &Boost.Thread; implementation given in this article, so pthreads-win32 and &Boost.Threads;
are even more complicated yet.</para> are even more complicated yet.</para>
</biblioentry> </biblioentry>
<biblioentry id="thread.bib.SchmidtStalRohnertBuschmann"> <biblioentry id="threads.bib.SchmidtStalRohnertBuschmann">
<abbrev <abbrev
id="thread.bib.SchmidtStalRohnertBuschmann.abbrev">SchmidtStalRohnertBuschmann</abbrev> id="threads.bib.SchmidtStalRohnertBuschmann.abbrev">SchmidtStalRohnertBuschmann</abbrev>
<title> <title>
<ulink <ulink
url="http://www.wiley.com/Corporate/Website/Objects/Products/0,9049,104671,00.html" url="http://www.wiley.com/Corporate/Website/Objects/Products/0,9049,104671,00.html"
@@ -214,11 +210,11 @@ last-revision="$Date$">
<copyright><year>2000</year></copyright> <copyright><year>2000</year></copyright>
<para>This is a very good explanation of how to apply several patterns <para>This is a very good explanation of how to apply several patterns
useful for concurrent programming. Among the patterns documented is the useful for concurrent programming. Among the patterns documented is the
Monitor Pattern mentioned frequently in the &Boost.Thread; Monitor Pattern mentioned frequently in the &Boost.Threads;
documentation.</para> documentation.</para>
</biblioentry> </biblioentry>
<biblioentry id="thread.bib.Stroustrup"> <biblioentry id="threads.bib.Stroustrup">
<abbrev id="thread.bib.Stroustrup.abbrev">Stroustrup</abbrev> <abbrev id="threads.bib.Stroustrup.abbrev">Stroustrup</abbrev>
<title> <title>
<ulink url="http://cseng.aw.com/book/0,3828,0201700735,00.html" <ulink url="http://cseng.aw.com/book/0,3828,0201700735,00.html"
>The C++ Programming Language</ulink> >The C++ Programming Language</ulink>

View File

@@ -1,49 +1,45 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<section id="thread.build" last-revision="$Date$"> <section id="thread.build" last-revision="$Date$">
<title>Build</title> <title>Build</title>
<para> <para>
How you build the &Boost.Thread; libraries, and how you build your own applications How you build the &Boost.Threads; libraries, and how you build your own applications
that use those libraries, are some of the most frequently asked questions. Build that use those libraries, are some of the most frequently asked questions. Build
processes are difficult to deal with in a portable manner. That's one reason processes are difficult to deal with in a portable manner. That's one reason
why &Boost.Thread; makes use of &Boost.Build;. why &Boost.Threads; makes use of &Boost.Build;.
In general you should refer to the documentation for &Boost.Build;. In general you should refer to the documentation for &Boost.Build;.
This document will only supply you with some simple usage examples for how to This document will only supply you with some simple usage examples for how to
use <emphasis>bjam</emphasis> to build and test &Boost.Thread;. In addition, this document use <emphasis>bjam</emphasis> to build and test &Boost.Threads;. In addition, this document
will try to explain the build requirements so that users may create their own will try to explain the build requirements so that users may create their own
build processes (for instance, create an IDE specific project), both for building build processes (for instance, create an IDE specific project), both for building
and testing &Boost.Thread;, as well as for building their own projects using and testing &Boost.Threads;, as well as for building their own projects using
&Boost.Thread;. &Boost.Threads;.
</para> </para>
<section id="thread.build.building"> <section id="thread.build.building">
<title>Building the &Boost.Thread; Libraries</title> <title>Building the &Boost.Threads; Libraries</title>
<para> <para>
To build the &Boost.Thread; libraries using &Boost.Build;, simply change to the To build the &Boost.Threads; libraries using &Boost.Build;, simply change to the
directory <emphasis>boost_root</emphasis>/libs/thread/build and execute the command: directory <emphasis>boost_root</emphasis>/libs/thread/build and execute the command:
<programlisting>bjam -sTOOLS=<emphasis>toolset</emphasis></programlisting> <programlisting>bjam -sTOOLS=<emphasis>toolset</emphasis></programlisting>
This will create the debug and the release builds of the &Boost.Thread; library. This will create the debug and the release builds of the &Boost.Threads; library.
<note>Invoking the above command in <emphasis>boost_root</emphasis> will build all of <note>Invoking the above command in <emphasis>boost_root</emphasis> will build all of
the Boost distribution, including &Boost.Thread;.</note> the Boost distribution, including &Boost.Threads;.</note>
</para> </para>
<para> <para>
The Jamfile supplied with &Boost.Thread; produces a dynamic link library named The Jamfile supplied with &Boost.Threads; produces a dynamic link library named
<emphasis>boost_thread{build-specific-tags}.{extension}</emphasis>, where the build-specific <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 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 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 a dynamic link library for the platform for which &Boost.Threads; is being built.
For instance, a debug library built for Win32 with VC++ 7.1 using Boost 1.31 would 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>. be named <emphasis>boost_thread-vc71-mt-gd-1_31.dll</emphasis>.
</para> </para>
<para> <para>
The source files that are used to create the &Boost.Thread; library The source files that are used to create the &Boost.Threads; library
are all of the *.cpp files found in <emphasis>boost_root</emphasis>/libs/thread/src. 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. 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 If you want to create your own build solution you'll have to follow these same
@@ -52,9 +48,9 @@
</para> </para>
</section> </section>
<section id="thread.build.testing"> <section id="thread.build.testing">
<title>Testing the &Boost.Thread; Libraries</title> <title>Testing the &Boost.Threads; Libraries</title>
<para> <para>
To test the &Boost.Thread; libraries using &Boost.Build;, simply change to the To test the &Boost.Threads; libraries using &Boost.Build;, simply change to the
directory <emphasis>boost_root</emphasis>/libs/thread/test and execute the command: directory <emphasis>boost_root</emphasis>/libs/thread/test and execute the command:
<programlisting>bjam -sTOOLS=<emphasis>toolset</emphasis> test</programlisting> <programlisting>bjam -sTOOLS=<emphasis>toolset</emphasis> test</programlisting>
</para> </para>

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<header name="boost/thread/condition.hpp" <header name="boost/thread/condition.hpp"
last-revision="$Date$"> last-revision="$Date$">
<namespace name="boost"> <namespace name="boost">
@@ -25,12 +21,12 @@
<description> <description>
<para>A <classname>condition</classname> object is always used in <para>A <classname>condition</classname> object is always used in
conjunction with a <link linkend="thread.concepts.mutexes">mutex</link> conjunction with a <link linkend="threads.concepts.mutexes">mutex</link>
object (an object whose type is a model of a <link object (an object whose type is a model of a <link
linkend="thread.concepts.Mutex">Mutex</link> or one of its linkend="threads.concepts.Mutex">Mutex</link> or one of its
refinements). The mutex object must be locked prior to waiting on the refinements). The mutex object must be locked prior to waiting on the
condition, which is verified by passing a lock object (an object whose condition, which is verified by passing a lock object (an object whose
type is a model of <link linkend="thread.concepts.Lock">Lock</link> or type is a model of <link linkend="threads.concepts.Lock">Lock</link> or
one of its refinements) to the <classname>condition</classname> object's one of its refinements) to the <classname>condition</classname> object's
wait functions. Upon blocking on the <classname>condition</classname> wait functions. Upon blocking on the <classname>condition</classname>
object, the thread unlocks the mutex object. When the thread returns object, the thread unlocks the mutex object. When the thread returns
@@ -43,8 +39,8 @@
&cite.SchmidtStalRohnertBuschmann; and &cite.Hoare74;). Monitors are one &cite.SchmidtStalRohnertBuschmann; and &cite.Hoare74;). Monitors are one
of the most important patterns for creating reliable multithreaded of the most important patterns for creating reliable multithreaded
programs.</para> programs.</para>
<para>See <xref linkend="thread.glossary"/> for definitions of <link <para>See <xref linkend="threads.glossary"/> for definitions of <link
linkend="thread.glossary.thread-state">thread states</link> linkend="threads.glossary.thread-state">thread states</link>
blocked and ready. Note that "waiting" is a synonym for blocked.</para> blocked and ready. Note that "waiting" is a synonym for blocked.</para>
</description> </description>
@@ -91,10 +87,10 @@
</parameter> </parameter>
<requires><simpara><code>ScopedLock</code> meets the <link <requires><simpara><code>ScopedLock</code> meets the <link
linkend="thread.concepts.ScopedLock">ScopedLock</link> linkend="threads.concepts.ScopedLock">ScopedLock</link>
requirements.</simpara></requires> requirements.</simpara></requires>
<effects><simpara>Releases the lock on the <link <effects><simpara>Releases the lock on the <link
linkend="thread.concepts.mutexes">mutex object</link> linkend="threads.concepts.mutexes">mutex object</link>
associated with <code>lock</code>, blocks the current thread of execution associated with <code>lock</code>, blocks the current thread of execution
until readied by a call to <code>this->notify_one()</code> until readied by a call to <code>this->notify_one()</code>
or<code> this->notify_all()</code>, and then reacquires the or<code> this->notify_all()</code>, and then reacquires the
@@ -120,7 +116,7 @@
</parameter> </parameter>
<requires><simpara><code>ScopedLock</code> meets the <link <requires><simpara><code>ScopedLock</code> meets the <link
linkend="thread.concepts.ScopedLock">ScopedLock</link> linkend="threads.concepts.ScopedLock">ScopedLock</link>
requirements and the return from <code>pred()</code> is requirements and the return from <code>pred()</code> is
convertible to <code>bool</code>.</simpara></requires> convertible to <code>bool</code>.</simpara></requires>
<effects><simpara>As if: <code>while (!pred()) <effects><simpara>As if: <code>while (!pred())
@@ -145,10 +141,10 @@
</parameter> </parameter>
<requires><simpara><code>ScopedLock</code> meets the <link <requires><simpara><code>ScopedLock</code> meets the <link
linkend="thread.concepts.ScopedLock">ScopedLock</link> linkend="threads.concepts.ScopedLock">ScopedLock</link>
requirements.</simpara></requires> requirements.</simpara></requires>
<effects><simpara>Releases the lock on the <link <effects><simpara>Releases the lock on the <link
linkend="thread.concepts.mutexes">mutex object</link> linkend="threads.concepts.mutexes">mutex object</link>
associated with <code>lock</code>, blocks the current thread of execution associated with <code>lock</code>, blocks the current thread of execution
until readied by a call to <code>this->notify_one()</code> until readied by a call to <code>this->notify_one()</code>
or<code> this->notify_all()</code>, or until time <code>xt</code> or<code> this->notify_all()</code>, or until time <code>xt</code>
@@ -171,16 +167,12 @@
<paramtype>ScopedLock&amp;</paramtype> <paramtype>ScopedLock&amp;</paramtype>
</parameter> </parameter>
<parameter name="xt">
<paramtype>const <classname>boost::xtime</classname>&amp;</paramtype>
</parameter>
<parameter name="pred"> <parameter name="pred">
<paramtype>Pred</paramtype> <paramtype>Pred</paramtype>
</parameter> </parameter>
<requires><simpara><code>ScopedLock</code> meets the <link <requires><simpara><code>ScopedLock</code> meets the <link
linkend="thread.concepts.ScopedLock">ScopedLock</link> linkend="threads.concepts.ScopedLock">ScopedLock</link>
requirements and the return from <code>pred()</code> is requirements and the return from <code>pred()</code> is
convertible to <code>bool</code>.</simpara></requires> convertible to <code>bool</code>.</simpara></requires>
<effects><simpara>As if: <code>while (!pred()) { if (!timed_wait(lock, <effects><simpara>As if: <code>while (!pred()) { if (!timed_wait(lock,

View File

@@ -1,23 +1,19 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<section id="thread.configuration" last-revision="$Date$"> <section id="thread.configuration" last-revision="$Date$">
<title>Configuration</title> <title>Configuration</title>
<para>&Boost.Thread; uses several configuration macros in &lt;boost/config.hpp&gt;, <para>&Boost.Threads; uses several configuration macros in &lt;boost/config.hpp&gt;,
as well as configuration macros meant to be supplied by the application. These as well as configuration macros meant to be supplied by the application. These
macros are documented here. macros are documented here.
</para> </para>
<section id="thread.configuration.public"> <section id="thread.configuration.public">
<title>Library Defined Public Macros</title> <title>Library Defined Public Macros</title>
<para> <para>
These macros are defined by &Boost.Thread; but are expected to be used These macros are defined by &Boost.Threads; but are expected to be used
by application code. by application code.
</para> </para>
<informaltable> <informaltable>
@@ -33,9 +29,9 @@
<entry>BOOST_HAS_THREADS</entry> <entry>BOOST_HAS_THREADS</entry>
<entry> <entry>
Indicates that threading support is available. This means both that there Indicates that threading support is available. This means both that there
is a platform specific implementation for &Boost.Thread; and that is a platform specific implementation for &Boost.Threads; and that
threading support has been enabled in a platform specific manner. For instance, threading support has been enabled in a platform specific manner. For instance,
on the Win32 platform there&#39;s an implementation for &Boost.Thread; on the Win32 platform there&#39;s an implementation for &Boost.Threads;
but unless the program is compiled against one of the multithreading runtimes but unless the program is compiled against one of the multithreading runtimes
(often determined by the compiler predefining the macro _MT) the BOOST_HAS_THREADS (often determined by the compiler predefining the macro _MT) the BOOST_HAS_THREADS
macro remains undefined. macro remains undefined.
@@ -48,7 +44,7 @@
<section id="thread.configuration.implementation"> <section id="thread.configuration.implementation">
<title>Library Defined Implementation Macros</title> <title>Library Defined Implementation Macros</title>
<para> <para>
These macros are defined by &Boost.Thread; and are implementation details These macros are defined by &Boost.Threads; and are implementation details
of interest only to implementors. of interest only to implementors.
</para> </para>
<informaltable> <informaltable>
@@ -64,14 +60,14 @@
<entry>BOOST_HAS_WINTHREADS</entry> <entry>BOOST_HAS_WINTHREADS</entry>
<entry> <entry>
Indicates that the platform has the Microsoft Win32 threading libraries, Indicates that the platform has the Microsoft Win32 threading libraries,
and that they should be used to implement &Boost.Thread;. and that they should be used to implement &Boost.Threads;.
</entry> </entry>
</row> </row>
<row> <row>
<entry>BOOST_HAS_PTHREADS</entry> <entry>BOOST_HAS_PTHREADS</entry>
<entry> <entry>
Indicates that the platform has the POSIX pthreads libraries, and that Indicates that the platform has the POSIX pthreads libraries, and that
they should be used to implement &Boost.Thread;. they should be used to implement &Boost.Threads;.
</entry> </entry>
</row> </row>
<row> <row>

View File

@@ -1,14 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford <section id="threads.design" last-revision="$Date$">
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<section id="thread.design" last-revision="$Date$">
<title>Design</title> <title>Design</title>
<para>With client/server and three-tier architectures becoming common place <para>With client/server and three-tier architectures becoming common place
in today's world, it's becoming increasingly important for programs to be in today's world, it's becoming increasingly important for programs to be
@@ -19,18 +15,18 @@
Further, these APIs are almost universally C APIs and fail to take Further, these APIs are almost universally C APIs and fail to take
advantage of C++'s strengths, or to address concepts unique to C++, such as advantage of C++'s strengths, or to address concepts unique to C++, such as
exceptions.</para> exceptions.</para>
<para>The &Boost.Thread; library is an attempt to define a portable interface <para>The &Boost.Threads; library is an attempt to define a portable interface
for writing parallel processes in C++.</para> for writing parallel processes in C++.</para>
<section id="thread.design.goals"> <section id="threads.design.goals">
<title>Goals</title> <title>Goals</title>
<para>The &Boost.Thread; library has several goals that should help to set <para>The &Boost.Threads; library has several goals that should help to set
it apart from other solutions. These goals are listed in order of precedence it apart from other solutions. These goals are listed in order of precedence
with full descriptions below. with full descriptions below.
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term>Portability</term> <term>Portability</term>
<listitem> <listitem>
<para>&Boost.Thread; was designed to be highly portable. The goal is <para>&Boost.Threads; was designed to be highly portable. The goal is
for the interface to be easily implemented on any platform that for the interface to be easily implemented on any platform that
supports threads, and possibly even on platforms without native thread supports threads, and possibly even on platforms without native thread
support.</para> support.</para>
@@ -39,8 +35,8 @@
<varlistentry> <varlistentry>
<term>Safety</term> <term>Safety</term>
<listitem> <listitem>
<para>&Boost.Thread; was designed to be as safe as possible. Writing <para>&Boost.Threads; was designed to be as safe as possible. Writing
<link linkend="thread.glossary.thread-safe">thread-safe</link> <link linkend="threads.glossary.thread-safe">thread-safe</link>
code is very difficult and successful libraries must strive to code is very difficult and successful libraries must strive to
insulate the programmer from dangerous constructs as much as insulate the programmer from dangerous constructs as much as
possible. This is accomplished in several ways: possible. This is accomplished in several ways:
@@ -49,14 +45,14 @@
<para>C++ language features are used to make correct usage easy <para>C++ language features are used to make correct usage easy
(if possible) and error-prone usage impossible or at least more (if possible) and error-prone usage impossible or at least more
difficult. For example, see the <link difficult. For example, see the <link
linkend="thread.concepts.Mutex">Mutex</link> and <link linkend="threads.concepts.Mutex">Mutex</link> and <link
linkend="thread.concepts.Lock">Lock</link> designs, and note linkend="threads.concepts.Lock">Lock</link> designs, and note
how they interact.</para> how they interact.</para>
</listitem> </listitem>
<listitem> <listitem>
<para>Certain traditional concurrent programming features are <para>Certain traditional concurrent programming features are
considered so error-prone that they are not provided at all. For considered so error-prone that they are not provided at all. For
example, see <xref linkend="thread.rationale.events" />.</para> example, see <xref linkend="threads.rationale.events" />.</para>
</listitem> </listitem>
<listitem> <listitem>
<para>Dangerous features, or features which may be misused, are <para>Dangerous features, or features which may be misused, are
@@ -69,9 +65,9 @@
<varlistentry> <varlistentry>
<term>Flexibility</term> <term>Flexibility</term>
<listitem> <listitem>
<para>&Boost.Thread; was designed to be flexible. This goal is often <para>&Boost.Threads; was designed to be flexible. This goal is often
at odds with <emphasis>safety</emphasis>. When functionality might be at odds with <emphasis>safety</emphasis>. When functionality might be
compromised by the desire to keep the interface safe, &Boost.Thread; compromised by the desire to keep the interface safe, &Boost.Threads;
has been designed to provide the functionality, but to make it's use has been designed to provide the functionality, but to make it's use
prohibitive for general use. In other words, the interfaces have been prohibitive for general use. In other words, the interfaces have been
designed such that it's usually obvious when something is unsafe, and designed such that it's usually obvious when something is unsafe, and
@@ -81,11 +77,11 @@
<varlistentry> <varlistentry>
<term>Efficiency</term> <term>Efficiency</term>
<listitem> <listitem>
<para>&Boost.Thread; was designed to be as efficient as <para>&Boost.Threads; was designed to be as efficient as
possible. When building a library on top of another library there is possible. When building a library on top of another library there is
always a danger that the result will be so much slower than the always a danger that the result will be so much slower than the
"native" API that programmers are inclined to ignore the higher level "native" API that programmers are inclined to ignore the higher level
API. &Boost.Thread; was designed to minimize the chances of this API. &Boost.Threads; was designed to minimize the chances of this
occurring. The interfaces have been crafted to allow an implementation occurring. The interfaces have been crafted to allow an implementation
the greatest chance of being as efficient as possible. This goal is the greatest chance of being as efficient as possible. This goal is
often at odds with the goal for <emphasis>safety</emphasis>. Every often at odds with the goal for <emphasis>safety</emphasis>. Every
@@ -98,18 +94,18 @@
</section> </section>
<section> <section>
<title>Iterative Phases</title> <title>Iterative Phases</title>
<para>Another goal of &Boost.Thread; was to take a dynamic, iterative <para>Another goal of &Boost.Threads; was to take a dynamic, iterative
approach in its development. The computing industry is still exploring the approach in its development. The computing industry is still exploring the
concepts of parallel programming. Most thread libraries supply only simple concepts of parallel programming. Most thread libraries supply only simple
primitive concepts for thread synchronization. These concepts are very primitive concepts for thread synchronization. These concepts are very
simple, but it is very difficult to use them safely or to provide formal simple, but it is very difficult to use them safely or to provide formal
proofs for constructs built on top of them. There has been a lot of research proofs for constructs built on top of them. There has been a lot of research
into other concepts, such as in "Communicating Sequential Processes." into other concepts, such as in "Communicating Sequential Processes."
&Boost.Thread; was designed in iterative steps, with each step providing &Boost.Threads; was designed in iterative steps, with each step providing
the building blocks necessary for the next step and giving the researcher the building blocks necessary for the next step and giving the researcher
the tools necessary to explore new concepts in a portable manner.</para> the tools necessary to explore new concepts in a portable manner.</para>
<para>Given the goal of following a dynamic, iterative approach <para>Given the goal of following a dynamic, iterative approach
&Boost.Thread; shall go through several growth cycles. Each phase in its &Boost.Threads; shall go through several growth cycles. Each phase in its
development shall be roughly documented here.</para> development shall be roughly documented here.</para>
</section> </section>
<section> <section>
@@ -123,10 +119,10 @@
much help to a programmer who wants to use the library in his multithreaded much help to a programmer who wants to use the library in his multithreaded
application. So there's a very great need for portable primitives that will application. So there's a very great need for portable primitives that will
allow the library developer to create <link allow the library developer to create <link
linkend="thread.glossary.thread-safe">thread-safe</link> linkend="threads.glossary.thread-safe">thread-safe</link>
implementations. This need far out weighs the need for portable methods to implementations. This need far out weighs the need for portable methods to
create and manage threads.</para> create and manage threads.</para>
<para>Because of this need, the first phase of &Boost.Thread; focuses <para>Because of this need, the first phase of &Boost.Threads; focuses
solely on providing portable primitive concepts for thread solely on providing portable primitive concepts for thread
synchronization. Types provided in this phase include the synchronization. Types provided in this phase include the
<classname>boost::mutex</classname>, <classname>boost::mutex</classname>,
@@ -139,16 +135,16 @@
synchronization primitives, though there are others that will be added in synchronization primitives, though there are others that will be added in
later phases.</para> later phases.</para>
</section> </section>
<section id="thread.design.phase2"> <section id="threads.design.phase2">
<title>Phase 2, Thread Management and Thread Specific Storage</title> <title>Phase 2, Thread Management and Thread Specific Storage</title>
<para>This phase addresses the creation and management of threads and <para>This phase addresses the creation and management of threads and
provides a mechanism for thread specific storage (data associated with a provides a mechanism for thread specific storage (data associated with a
thread instance). Thread management is a tricky issue in C++, so this thread instance). Thread management is a tricky issue in C++, so this
phase addresses only the basic needs of multithreaded program. Later phase addresses only the basic needs of multithreaded program. Later
phases are likely to add additional functionality in this area. This phases are likely to add additional functionality in this area. This
phase of &Boost.Thread; adds the <classname>boost::thread</classname> and phase of &Boost.Threads; adds the <classname>boost::thread</classname> and
<classname>boost::thread_specific_ptr</classname> types. With these <classname>boost::thread_specific_ptr</classname> types. With these
additions the &Boost.Thread; library can be considered minimal but additions the &Boost.Threads; library can be considered minimal but
complete.</para> complete.</para>
</section> </section>
<section> <section>

View File

@@ -1,30 +1,26 @@
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford <!ENTITY Boost.Threads "<emphasis role='bold'>Boost.Threads</emphasis>">
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.Thread "<emphasis role='bold'>Boost.Thread</emphasis>">
<!ENTITY Boost.Build "<emphasis role='bold'>Boost.Build</emphasis>"> <!ENTITY Boost.Build "<emphasis role='bold'>Boost.Build</emphasis>">
<!ENTITY cite.AndrewsSchneider83 "<citation><xref <!ENTITY cite.AndrewsSchneider83 "<citation><xref
linkend='thread.bib.AndrewsSchneider83' linkend='threads.bib.AndrewsSchneider83'
endterm='thread.bib.AndrewsSchneider83.abbrev'/></citation>"> endterm='threads.bib.AndrewsSchneider83.abbrev'/></citation>">
<!ENTITY cite.Boost "<citation><xref linkend='thread.bib.Boost' <!ENTITY cite.Boost "<citation><xref linkend='threads.bib.Boost'
endterm='thread.bib.Boost.abbrev'/></citation>"> endterm='threads.bib.Boost.abbrev'/></citation>">
<!ENTITY cite.Hansen73 "<citation><xref linkend='thread.bib.Hansen73' <!ENTITY cite.Hansen73 "<citation><xref linkend='threads.bib.Hansen73'
endterm='thread.bib.Hansen73.abbrev'/></citation>"> endterm='threads.bib.Hansen73.abbrev'/></citation>">
<!ENTITY cite.Butenhof97 "<citation><xref linkend='thread.bib.Butenhof97' <!ENTITY cite.Butenhof97 "<citation><xref linkend='threads.bib.Butenhof97'
endterm='thread.bib.Butenhof97.abbrev'/></citation>"> endterm='threads.bib.Butenhof97.abbrev'/></citation>">
<!ENTITY cite.Hoare74 "<citation><xref linkend='thread.bib.Hoare74' <!ENTITY cite.Hoare74 "<citation><xref linkend='threads.bib.Hoare74'
endterm='thread.bib.Hoare74.abbrev'/></citation>"> endterm='threads.bib.Hoare74.abbrev'/></citation>">
<!ENTITY cite.ISO98 "<citation><xref linkend='thread.bib.ISO98' <!ENTITY cite.ISO98 "<citation><xref linkend='threads.bib.ISO98'
endterm='thread.bib.ISO98.abbrev'/></citation>"> endterm='threads.bib.ISO98.abbrev'/></citation>">
<!ENTITY cite.McDowellHelmbold89 "<citation><xref <!ENTITY cite.McDowellHelmbold89 "<citation><xref
linkend='thread.bib.McDowellHelmbold89' linkend='threads.bib.McDowellHelmbold89'
endterm='thread.bib.McDowellHelmbold89.abbrev'/></citation>"> endterm='threads.bib.McDowellHelmbold89.abbrev'/></citation>">
<!ENTITY cite.SchmidtPyarali "<citation><xref <!ENTITY cite.SchmidtPyarali "<citation><xref
linkend='thread.bib.SchmidtPyarali' linkend='threads.bib.SchmidtPyarali'
endterm='thread.bib.SchmidtPyarali.abbrev'/></citation>"> endterm='threads.bib.SchmidtPyarali.abbrev'/></citation>">
<!ENTITY cite.SchmidtStalRohnertBuschmann "<citation><xref <!ENTITY cite.SchmidtStalRohnertBuschmann "<citation><xref
linkend='thread.bib.SchmidtStalRohnertBuschmann' linkend='threads.bib.SchmidtStalRohnertBuschmann'
endterm='thread.bib.SchmidtStalRohnertBuschmann.abbrev'/></citation>"> endterm='threads.bib.SchmidtStalRohnertBuschmann.abbrev'/></citation>">
<!ENTITY cite.Stroustrup "<citation><xref linkend='thread.bib.Stroustrup' <!ENTITY cite.Stroustrup "<citation><xref linkend='threads.bib.Stroustrup'
endterm='thread.bib.Stroustrup.abbrev'/></citation>"> endterm='threads.bib.Stroustrup.abbrev'/></citation>">

View File

@@ -1,13 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<header name="boost/thread/exceptions.hpp" <header name="boost/thread/exceptions.hpp"
last-revision="$Date$"> last-revision="$Date$">
<namespace name="boost"> <namespace name="boost">
@@ -38,7 +34,7 @@
<purpose> <purpose>
<simpara>The <classname>thread_resource_error</classname> class <simpara>The <classname>thread_resource_error</classname> class
defines an exception type that is thrown by constructors in the defines an exception type that is thrown by constructors in the
&Boost.Thread; library when thread-related resources can not be &Boost.Threads; library when thread-related resources can not be
acquired.</simpara> acquired.</simpara>
</purpose> </purpose>

View File

@@ -1,49 +1,45 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford <section id="threads.faq" last-revision="$Date$">
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<section id="thread.faq" last-revision="$Date$">
<title>Frequently Asked Questions</title> <title>Frequently Asked Questions</title>
<qandaset> <qandaset>
<qandaentry> <qandaentry>
<question> <question>
<para>Are lock objects <link <para>Are lock objects <link
linkend="thread.glossary.thread-safe">thread safe</link>?</para> linkend="threads.glossary.thread-safe">thread safe</link>?</para>
</question> </question>
<answer> <answer>
<para><emphasis role="bold">No!</emphasis> Lock objects are not meant to <para><emphasis role="bold">No!</emphasis> Lock objects are not meant to
be shared between threads. They are meant to be short-lived objects be shared between threads. They are meant to be short-lived objects
created on automatic storage within a code block. Any other usage is created on automatic storage within a code block. Any other usage is
just likely to lead to errors and won't really be of actual benefit anyway. just likely to lead to errors and won't really be of actual benefit anyway.
Share <link linkend="thread.concepts.mutexes">Mutexes</link>, not Share <link linkend="threads.concepts.mutexes">Mutexes</link>, not
Locks. For more information see the <link Locks. For more information see the <link
linkend="thread.rationale.locks">rationale</link> behind the linkend="threads.rationale.locks">rationale</link> behind the
design for lock objects.</para> design for lock objects.</para>
</answer> </answer>
</qandaentry> </qandaentry>
<qandaentry> <qandaentry>
<question> <question>
<para>Why was &Boost.Thread; modeled after (specific library <para>Why was &Boost.Threads; modeled after (specific library
name)?</para> name)?</para>
</question> </question>
<answer> <answer>
<para>It wasn't. &Boost.Thread; was designed from scratch. Extensive <para>It wasn't. &Boost.Threads; was designed from scratch. Extensive
design discussions involved numerous people representing a wide range of design discussions involved numerous people representing a wide range of
experience across many platforms. To ensure portability, the initial experience across many platforms. To ensure portability, the initial
implements were done in parallel using POSIX Threads and the Win32 implements were done in parallel using POSIX Threads and the Win32
threading API. But the &Boost.Thread; design is very much in the spirit threading API. But the &Boost.Threads; design is very much in the spirit
of C++, and thus doesn't model such C based APIs.</para> of C++, and thus doesn't model such C based APIs.</para>
</answer> </answer>
</qandaentry> </qandaentry>
<qandaentry> <qandaentry>
<question> <question>
<para>Why wasn't &Boost.Thread; modeled after (specific library <para>Why wasn't &Boost.Threads; modeled after (specific library
name)?</para> name)?</para>
</question> </question>
<answer> <answer>
@@ -58,12 +54,12 @@
</qandaentry> </qandaentry>
<qandaentry> <qandaentry>
<question> <question>
<para>Why do <link linkend="thread.concepts.mutexes">Mutexes</link> <para>Why do <link linkend="threads.concepts.mutexes">Mutexes</link>
have noncopyable semantics?</para> have noncopyable semantics?</para>
</question> </question>
<answer> <answer>
<para>To ensure that <link <para>To ensure that <link
linkend="thread.glossary.deadlock">deadlocks</link> don't occur. The linkend="threads.glossary.deadlock">deadlocks</link> don't occur. The
only logical form of copy would be to use some sort of shallow copy only logical form of copy would be to use some sort of shallow copy
semantics in which multiple mutex objects could refer to the same mutex semantics in which multiple mutex objects could refer to the same mutex
state. This means that if ObjA has a mutex object as part of its state state. This means that if ObjA has a mutex object as part of its state
@@ -77,20 +73,20 @@
<qandaentry> <qandaentry>
<question> <question>
<para>How can you prevent <link <para>How can you prevent <link
linkend="thread.glossary.deadlock">deadlock</link> from occurring when linkend="threads.glossary.deadlock">deadlock</link> from occurring when
a thread must lock multiple mutexes?</para> a thread must lock multiple mutexes?</para>
</question> </question>
<answer> <answer>
<para>Always lock them in the same order. One easy way of doing this is <para>Always lock them in the same order. One easy way of doing this is
to use each mutex's address to determine the order in which they are to use each mutex's address to determine the order in which they are
locked. A future &Boost.Thread; concept may wrap this pattern up in a locked. A future &Boost.Threads; concept may wrap this pattern up in a
reusable class.</para> reusable class.</para>
</answer> </answer>
</qandaentry> </qandaentry>
<qandaentry> <qandaentry>
<question> <question>
<para>Don't noncopyable <link <para>Don't noncopyable <link
linkend="thread.concepts.mutexes">Mutex</link> semantics mean that a linkend="threads.concepts.mutexes">Mutex</link> semantics mean that a
class with a mutex member will be noncopyable as well?</para> class with a mutex member will be noncopyable as well?</para>
</question> </question>
<answer> <answer>
@@ -98,7 +94,7 @@
copy constructor and assignment operator, so they will have to be coded copy constructor and assignment operator, so they will have to be coded
explicitly. This is a <emphasis role="bold">good thing</emphasis>, explicitly. This is a <emphasis role="bold">good thing</emphasis>,
however, since the compiler generated operations would not be <link however, since the compiler generated operations would not be <link
linkend="thread.glossary.thread-safe">thread-safe</link>. The following linkend="threads.glossary.thread-safe">thread-safe</link>. The following
is a simple example of a class with copyable semantics and internal is a simple example of a class with copyable semantics and internal
synchronization through a mutex member.</para> synchronization through a mutex member.</para>
<programlisting> <programlisting>
@@ -148,7 +144,7 @@ private:
<qandaentry> <qandaentry>
<question> <question>
<para>How can you lock a <link <para>How can you lock a <link
linkend="thread.concepts.mutexes">Mutex</link> member in a const member linkend="threads.concepts.mutexes">Mutex</link> member in a const member
function, in order to implement the Monitor Pattern?</para> function, in order to implement the Monitor Pattern?</para>
</question> </question>
<answer> <answer>
@@ -169,8 +165,8 @@ private:
</question> </question>
<answer> <answer>
<para>Condition variables result in user code much less prone to <link <para>Condition variables result in user code much less prone to <link
linkend="thread.glossary.race-condition">race conditions</link> than linkend="threads.glossary.race-condition">race conditions</link> than
event variables. See <xref linkend="thread.rationale.events" /> event variables. See <xref linkend="threads.rationale.events" />
for analysis. Also see &cite.Hoare74; and &cite.SchmidtStalRohnertBuschmann;. for analysis. Also see &cite.Hoare74; and &cite.SchmidtStalRohnertBuschmann;.
</para> </para>
</answer> </answer>
@@ -181,7 +177,7 @@ private:
</question> </question>
<answer> <answer>
<para>There's a valid need for thread termination, so at some point <para>There's a valid need for thread termination, so at some point
&Boost.Thread; probably will include it, but only after we can find a &Boost.Threads; probably will include it, but only after we can find a
truly safe (and portable) mechanism for this concept.</para> truly safe (and portable) mechanism for this concept.</para>
</answer> </answer>
</qandaentry> </qandaentry>
@@ -210,26 +206,5 @@ private:
condition variable.</para> condition variable.</para>
</answer> </answer>
</qandaentry> </qandaentry>
<qandaentry>
<question>
<para>Why doesn't the thread's ctor take at least a void* to pass any
information along with the function? All other threading libs support
that and it makes Boost.Threads inferiour. </para>
</question>
<answer>
<para>There is no need, because Boost.Threads are superiour! First
thing is that its ctor doesn't take a function but a functor. That
means that you can pass an object with an overloaded operator() and
include additional data as members in that object. Beware though that
this object is copied, use boost::ref to prevent that. Secondly, even
a boost::function&lt;void (void)&gt; can carry parameters, you only have to
use boost::bind() to create it from any function and bind its
parameters.</para>
<para>That is also why Boost.Threads are superiour, because they
don't require you to pass a type-unsafe void pointer. Rather, you can
use the flexible Boost.Functions to create a thread entry out of
anything that can be called.</para>
</answer>
</qandaentry>
</qandaset> </qandaset>
</section> </section>

View File

@@ -1,14 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford <glossary id="threads.glossary" last-revision="$Date$">
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<glossary id="thread.glossary" last-revision="$Date$">
<title>Glossary</title> <title>Glossary</title>
<para>Definitions are given in terms of the C++ Standard <para>Definitions are given in terms of the C++ Standard
&cite.ISO98;. References to the standard are in the form [1.2.3/4], which &cite.ISO98;. References to the standard are in the form [1.2.3/4], which
@@ -16,9 +12,9 @@
"/".</para> "/".</para>
<para>Because the definitions are written in something akin to "standardese", <para>Because the definitions are written in something akin to "standardese",
they can be difficult to understand. The intent isn't to confuse, but rather they can be difficult to understand. The intent isn't to confuse, but rather
to clarify the additional requirements &Boost.Thread; places on a C++ to clarify the additional requirements &Boost.Threads; places on a C++
implementation as defined by the C++ Standard.</para> implementation as defined by the C++ Standard.</para>
<glossentry id="thread.glossary.thread"> <glossentry id="threads.glossary.thread">
<glossterm>Thread</glossterm> <glossterm>Thread</glossterm>
<glossdef> <glossdef>
<para>Thread is short for "thread of execution". A thread of execution is <para>Thread is short for "thread of execution". A thread of execution is
@@ -54,13 +50,13 @@
</itemizedlist> </itemizedlist>
</glossdef> </glossdef>
</glossentry> </glossentry>
<glossentry id="thread.glossary.thread-safe"> <glossentry id="threads.glossary.thread-safe">
<glossterm>Thread-safe</glossterm> <glossterm>Thread-safe</glossterm>
<glossdef> <glossdef>
<para>A program is thread-safe if it has no <link <para>A program is thread-safe if it has no <link
linkend="thread.glossary.race-condition">race conditions</link>, does linkend="threads.glossary.race-condition">race conditions</link>, does
not <link linkend="thread.glossary.deadlock">deadlock</link>, and has not <link linkend="threads.glossary.deadlock">deadlock</link>, and has
no <link linkend="thread.glossary.priority-failure">priority no <link linkend="threads.glossary.priority-failure">priority
failures</link>.</para> failures</link>.</para>
<para>Note that thread-safety does not necessarily imply efficiency, and <para>Note that thread-safety does not necessarily imply efficiency, and
than while some thread-safety violations can be determined statically at than while some thread-safety violations can be determined statically at
@@ -68,7 +64,7 @@
runtime.</para> runtime.</para>
</glossdef> </glossdef>
</glossentry> </glossentry>
<glossentry id="thread.glossary.thread-state"> <glossentry id="threads.glossary.thread-state">
<glossterm>Thread State</glossterm> <glossterm>Thread State</glossterm>
<glossdef> <glossdef>
<para>During the lifetime of a thread, it shall be in one of the following <para>During the lifetime of a thread, it shall be in one of the following
@@ -170,7 +166,7 @@
above table.]</para> above table.]</para>
</glossdef> </glossdef>
</glossentry> </glossentry>
<glossentry id="thread.glossary.race-condition"> <glossentry id="threads.glossary.race-condition">
<glossterm>Race Condition</glossterm> <glossterm>Race Condition</glossterm>
<glossdef> <glossdef>
<para>A race condition is what occurs when multiple threads read from and write <para>A race condition is what occurs when multiple threads read from and write
@@ -179,10 +175,10 @@
pattern which isn't even a valid value for the data type. A race condition pattern which isn't even a valid value for the data type. A race condition
results in undefined behavior [1.3.12].</para> results in undefined behavior [1.3.12].</para>
<para>Race conditions can be prevented by serializing memory access using <para>Race conditions can be prevented by serializing memory access using
the tools provided by &Boost.Thread;.</para> the tools provided by &Boost.Threads;.</para>
</glossdef> </glossdef>
</glossentry> </glossentry>
<glossentry id="thread.glossary.deadlock"> <glossentry id="threads.glossary.deadlock">
<glossterm>Deadlock</glossterm> <glossterm>Deadlock</glossterm>
<glossdef> <glossdef>
<para>Deadlock is an execution state where for some set of threads, each <para>Deadlock is an execution state where for some set of threads, each
@@ -191,14 +187,14 @@
become ready again.</para> become ready again.</para>
</glossdef> </glossdef>
</glossentry> </glossentry>
<glossentry id="thread.glossary.starvation"> <glossentry id="threads.glossary.starvation">
<glossterm>Starvation</glossterm> <glossterm>Starvation</glossterm>
<glossdef> <glossdef>
<para>The condition in which a thread is not making sufficient progress in <para>The condition in which a thread is not making sufficient progress in
its work during a given time interval.</para> its work during a given time interval.</para>
</glossdef> </glossdef>
</glossentry> </glossentry>
<glossentry id="thread.glossary.priority-failure"> <glossentry id="threads.glossary.priority-failure">
<glossterm>Priority Failure</glossterm> <glossterm>Priority Failure</glossterm>
<glossdef> <glossdef>
<para>A priority failure (such as priority inversion or infinite overtaking) <para>A priority failure (such as priority inversion or infinite overtaking)
@@ -206,10 +202,10 @@
performed in time to be useful.</para> performed in time to be useful.</para>
</glossdef> </glossdef>
</glossentry> </glossentry>
<glossentry id="thread.glossary.undefined-behavior"> <glossentry id="threads.glossary.undefined-behavior">
<glossterm>Undefined Behavior</glossterm> <glossterm>Undefined Behavior</glossterm>
<glossdef> <glossdef>
<para>The result of certain operations in &Boost.Thread; is undefined; <para>The result of certain operations in &Boost.Threads; is undefined;
this means that those operations can invoke almost any behavior when this means that those operations can invoke almost any behavior when
they are executed.</para> they are executed.</para>
@@ -224,7 +220,7 @@
programming error.</para> programming error.</para>
</glossdef> </glossdef>
</glossentry> </glossentry>
<glossentry id="thread.glossary.memory-visibility"> <glossentry id="threads.glossary.memory-visibility">
<glossterm>Memory Visibility</glossterm> <glossterm>Memory Visibility</glossterm>
<glossdef> <glossdef>
<para>An address [1.7] shall always point to the same memory byte, <para>An address [1.7] shall always point to the same memory byte,

View File

@@ -1,16 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford <section id="threads.implementation_notes" last-revision="$Date$">
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<section id="thread.implementation_notes" last-revision="$Date$">
<title>Implementation Notes</title> <title>Implementation Notes</title>
<section id="thread.implementation_notes.win32"> <section id="threads.implementation_notes.win32">
<title>Win32</title> <title>Win32</title>
<para> <para>
In the current Win32 implementation, creating a boost::thread object In the current Win32 implementation, creating a boost::thread object

View File

@@ -1,12 +1,8 @@
<!-- Copyright (c) 2002-2003 Beman Dawes, William E. Kempf.
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<html> <html>
<head> <head>
<meta http-equiv="refresh" content="0; URL=../../../doc/html/thread.html"> <meta http-equiv="refresh" content="0; URL=../../../doc/html/threads.html">
</head> </head>
<body> <body>
Automatic redirection failed, please go to <a href="../../../doc/html/thread.html">../../../doc/html/thread.html</a> Automatic redirection failed, please go to <a href="../../../doc/html/threads.html">../../../doc/html/threads.html</a>
</body> </body>
</html> </html>

View File

@@ -1,39 +1,35 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<header name="boost/thread/mutex.hpp" <header name="boost/thread/mutex.hpp"
last-revision="$Date$"> last-revision="$Date$">
<namespace name="boost"> <namespace name="boost">
<class name="mutex"> <class name="mutex">
<purpose> <purpose>
<para>The <classname>mutex</classname> class is a model of the <para>The <classname>mutex</classname> class is a model of the
<link linkend="thread.concepts.Mutex">Mutex</link> concept.</para> <link linkend="threads.concepts.Mutex">Mutex</link> concept.</para>
</purpose> </purpose>
<description> <description>
<para>The <classname>mutex</classname> class is a model of the <para>The <classname>mutex</classname> class is a model of the
<link linkend="thread.concepts.Mutex">Mutex</link> concept. <link linkend="threads.concepts.Mutex">Mutex</link> concept.
It should be used to synchronize access to shared resources using It should be used to synchronize access to shared resources using
<link linkend="thread.concepts.unspecified-locking-strategy">Unspecified</link> <link linkend="threads.concepts.unspecified-locking-strategy">Unspecified</link>
locking mechanics.</para> locking mechanics.</para>
<para>For classes that model related mutex concepts, see <para>For classes that model related mutex concepts, see
<classname>try_mutex</classname> and <classname>timed_mutex</classname>.</para> <classname>try_mutex</classname> and <classname>timed_mutex</classname>.</para>
<para>For <link linkend="thread.concepts.recursive-locking-strategy">Recursive</link> <para>For <link linkend="threads.concepts.recursive-locking-strategy">Recursive</link>
locking mechanics, see <classname>recursive_mutex</classname>, locking mechanics, see <classname>recursive_mutex</classname>,
<classname>recursive_try_mutex</classname>, and <classname>recursive_timed_mutex</classname>. <classname>recursive_try_mutex</classname>, and <classname>recursive_timed_mutex</classname>.
</para> </para>
<para>The <classname>mutex</classname> class supplies the following typedef, <para>The <classname>mutex</classname> class supplies the following typedef,
which <link linkend="thread.concepts.lock-models">models</link> which <link linkend="threads.concepts.lock-models">models</link>
the specified locking strategy: the specified locking strategy:
<informaltable> <informaltable>
@@ -47,7 +43,7 @@
<tbody> <tbody>
<row> <row>
<entry>scoped_lock</entry> <entry>scoped_lock</entry>
<entry><link linkend="thread.concepts.ScopedLock">ScopedLock</link></entry> <entry><link linkend="threads.concepts.ScopedLock">ScopedLock</link></entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
@@ -55,7 +51,7 @@
</para> </para>
<para>The <classname>mutex</classname> class uses an <para>The <classname>mutex</classname> class uses an
<link linkend="thread.concepts.unspecified-locking-strategy">Unspecified</link> <link linkend="threads.concepts.unspecified-locking-strategy">Unspecified</link>
locking strategy, so attempts to recursively lock a <classname>mutex</classname> locking strategy, so attempts to recursively lock a <classname>mutex</classname>
object or attempts to unlock one by threads that don't own a lock on it result in object or attempts to unlock one by threads that don't own a lock on it result in
<emphasis role="bold">undefined behavior</emphasis>. <emphasis role="bold">undefined behavior</emphasis>.
@@ -65,10 +61,10 @@
<code>NDEBUG</code> is not defined.</para> <code>NDEBUG</code> is not defined.</para>
<para>Like all <para>Like all
<link linkend="thread.concepts.mutex-models">mutex models</link> <link linkend="threads.concepts.mutex-models">mutex models</link>
in &Boost.Thread;, <classname>mutex</classname> leaves the in &Boost.Threads;, <classname>mutex</classname> leaves the
<link linkend="thread.concepts.sheduling-policies">scheduling policy</link> <link linkend="threads.concepts.sheduling-policies">scheduling policy</link>
as <link linkend="thread.concepts.unspecified-scheduling-policy">Unspecified</link>. as <link linkend="threads.concepts.unspecified-scheduling-policy">Unspecified</link>.
Programmers should make no assumptions about the order in which Programmers should make no assumptions about the order in which
waiting threads acquire a lock.</para> waiting threads acquire a lock.</para>
</description> </description>
@@ -104,26 +100,26 @@
<class name="try_mutex"> <class name="try_mutex">
<purpose> <purpose>
<para>The <classname>try_mutex</classname> class is a model of the <para>The <classname>try_mutex</classname> class is a model of the
<link linkend="thread.concepts.TryMutex">TryMutex</link> concept.</para> <link linkend="threads.concepts.TryMutex">TryMutex</link> concept.</para>
</purpose> </purpose>
<description> <description>
<para>The <classname>try_mutex</classname> class is a model of the <para>The <classname>try_mutex</classname> class is a model of the
<link linkend="thread.concepts.TryMutex">TryMutex</link> concept. <link linkend="threads.concepts.TryMutex">TryMutex</link> concept.
It should be used to synchronize access to shared resources using It should be used to synchronize access to shared resources using
<link linkend="thread.concepts.unspecified-locking-strategy">Unspecified</link> <link linkend="threads.concepts.unspecified-locking-strategy">Unspecified</link>
locking mechanics.</para> locking mechanics.</para>
<para>For classes that model related mutex concepts, see <para>For classes that model related mutex concepts, see
<classname>mutex</classname> and <classname>timed_mutex</classname>.</para> <classname>mutex</classname> and <classname>timed_mutex</classname>.</para>
<para>For <link linkend="thread.concepts.recursive-locking-strategy">Recursive</link> <para>For <link linkend="threads.concepts.recursive-locking-strategy">Recursive</link>
locking mechanics, see <classname>recursive_mutex</classname>, locking mechanics, see <classname>recursive_mutex</classname>,
<classname>recursive_try_mutex</classname>, and <classname>recursive_timed_mutex</classname>. <classname>recursive_try_mutex</classname>, and <classname>recursive_timed_mutex</classname>.
</para> </para>
<para>The <classname>try_mutex</classname> class supplies the following typedefs, <para>The <classname>try_mutex</classname> class supplies the following typedefs,
which <link linkend="thread.concepts.lock-models">model</link> which <link linkend="threads.concepts.lock-models">model</link>
the specified locking strategies: the specified locking strategies:
<informaltable> <informaltable>
@@ -137,11 +133,11 @@
<tbody> <tbody>
<row> <row>
<entry>scoped_lock</entry> <entry>scoped_lock</entry>
<entry><link linkend="thread.concepts.ScopedLock">ScopedLock</link></entry> <entry><link linkend="threads.concepts.ScopedLock">ScopedLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_try_lock</entry> <entry>scoped_try_lock</entry>
<entry><link linkend="thread.concepts.ScopedTryLock">ScopedTryLock</link></entry> <entry><link linkend="threads.concepts.ScopedTryLock">ScopedTryLock</link></entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
@@ -149,7 +145,7 @@
</para> </para>
<para>The <classname>try_mutex</classname> class uses an <para>The <classname>try_mutex</classname> class uses an
<link linkend="thread.concepts.unspecified-locking-strategy">Unspecified</link> <link linkend="threads.concepts.unspecified-locking-strategy">Unspecified</link>
locking strategy, so attempts to recursively lock a <classname>try_mutex</classname> locking strategy, so attempts to recursively lock a <classname>try_mutex</classname>
object or attempts to unlock one by threads that don't own a lock on it result in object or attempts to unlock one by threads that don't own a lock on it result in
<emphasis role="bold">undefined behavior</emphasis>. <emphasis role="bold">undefined behavior</emphasis>.
@@ -159,10 +155,10 @@
<code>NDEBUG</code> is not defined.</para> <code>NDEBUG</code> is not defined.</para>
<para>Like all <para>Like all
<link linkend="thread.concepts.mutex-models">mutex models</link> <link linkend="threads.concepts.mutex-models">mutex models</link>
in &Boost.Thread;, <classname>try_mutex</classname> leaves the in &Boost.Threads;, <classname>try_mutex</classname> leaves the
<link linkend="thread.concepts.sheduling-policies">scheduling policy</link> <link linkend="threads.concepts.sheduling-policies">scheduling policy</link>
as <link linkend="thread.concepts.unspecified-scheduling-policy">Unspecified</link>. as <link linkend="threads.concepts.unspecified-scheduling-policy">Unspecified</link>.
Programmers should make no assumptions about the order in which Programmers should make no assumptions about the order in which
waiting threads acquire a lock.</para> waiting threads acquire a lock.</para>
</description> </description>
@@ -203,26 +199,26 @@
<class name="timed_mutex"> <class name="timed_mutex">
<purpose> <purpose>
<para>The <classname>timed_mutex</classname> class is a model of the <para>The <classname>timed_mutex</classname> class is a model of the
<link linkend="thread.concepts.TimedMutex">TimedMutex</link> concept.</para> <link linkend="threads.concepts.TimedMutex">TimedMutex</link> concept.</para>
</purpose> </purpose>
<description> <description>
<para>The <classname>timed_mutex</classname> class is a model of the <para>The <classname>timed_mutex</classname> class is a model of the
<link linkend="thread.concepts.TimedMutex">TimedMutex</link> concept. <link linkend="threads.concepts.TimedMutex">TimedMutex</link> concept.
It should be used to synchronize access to shared resources using It should be used to synchronize access to shared resources using
<link linkend="thread.concepts.unspecified-locking-strategy">Unspecified</link> <link linkend="threads.concepts.unspecified-locking-strategy">Unspecified</link>
locking mechanics.</para> locking mechanics.</para>
<para>For classes that model related mutex concepts, see <para>For classes that model related mutex concepts, see
<classname>mutex</classname> and <classname>try_mutex</classname>.</para> <classname>mutex</classname> and <classname>try_mutex</classname>.</para>
<para>For <link linkend="thread.concepts.recursive-locking-strategy">Recursive</link> <para>For <link linkend="threads.concepts.recursive-locking-strategy">Recursive</link>
locking mechanics, see <classname>recursive_mutex</classname>, locking mechanics, see <classname>recursive_mutex</classname>,
<classname>recursive_try_mutex</classname>, and <classname>recursive_timed_mutex</classname>. <classname>recursive_try_mutex</classname>, and <classname>recursive_timed_mutex</classname>.
</para> </para>
<para>The <classname>timed_mutex</classname> class supplies the following typedefs, <para>The <classname>timed_mutex</classname> class supplies the following typedefs,
which <link linkend="thread.concepts.lock-models">model</link> which <link linkend="threads.concepts.lock-models">model</link>
the specified locking strategies: the specified locking strategies:
<informaltable> <informaltable>
@@ -236,15 +232,15 @@
<tbody> <tbody>
<row> <row>
<entry>scoped_lock</entry> <entry>scoped_lock</entry>
<entry><link linkend="thread.concepts.ScopedLock">ScopedLock</link></entry> <entry><link linkend="threads.concepts.ScopedLock">ScopedLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_try_lock</entry> <entry>scoped_try_lock</entry>
<entry><link linkend="thread.concepts.ScopedTryLock">ScopedTryLock</link></entry> <entry><link linkend="threads.concepts.ScopedTryLock">ScopedTryLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_timed_lock</entry> <entry>scoped_timed_lock</entry>
<entry><link linkend="thread.concepts.ScopedTimedLock">ScopedTimedLock</link></entry> <entry><link linkend="threads.concepts.ScopedTimedLock">ScopedTimedLock</link></entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
@@ -252,7 +248,7 @@
</para> </para>
<para>The <classname>timed_mutex</classname> class uses an <para>The <classname>timed_mutex</classname> class uses an
<link linkend="thread.concepts.unspecified-locking-strategy">Unspecified</link> <link linkend="threads.concepts.unspecified-locking-strategy">Unspecified</link>
locking strategy, so attempts to recursively lock a <classname>timed_mutex</classname> locking strategy, so attempts to recursively lock a <classname>timed_mutex</classname>
object or attempts to unlock one by threads that don't own a lock on it result in object or attempts to unlock one by threads that don't own a lock on it result in
<emphasis role="bold">undefined behavior</emphasis>. <emphasis role="bold">undefined behavior</emphasis>.
@@ -262,10 +258,10 @@
<code>NDEBUG</code> is not defined.</para> <code>NDEBUG</code> is not defined.</para>
<para>Like all <para>Like all
<link linkend="thread.concepts.mutex-models">mutex models</link> <link linkend="threads.concepts.mutex-models">mutex models</link>
in &Boost.Thread;, <classname>timed_mutex</classname> leaves the in &Boost.Threads;, <classname>timed_mutex</classname> leaves the
<link linkend="thread.concepts.sheduling-policies">scheduling policy</link> <link linkend="threads.concepts.sheduling-policies">scheduling policy</link>
as <link linkend="thread.concepts.unspecified-scheduling-policy">Unspecified</link>. as <link linkend="threads.concepts.unspecified-scheduling-policy">Unspecified</link>.
Programmers should make no assumptions about the order in which Programmers should make no assumptions about the order in which
waiting threads acquire a lock.</para> waiting threads acquire a lock.</para>
</description> </description>

View File

@@ -1,13 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<header name="boost/thread/once.hpp" <header name="boost/thread/once.hpp"
last-revision="$Date$"> last-revision="$Date$">
<macro name="BOOST_ONCE_INIT"> <macro name="BOOST_ONCE_INIT">
@@ -15,7 +11,7 @@
<code>once_flag</code> type (statically initialized to <code>once_flag</code> type (statically initialized to
<macroname>BOOST_ONCE_INIT</macroname>) can be used to run a <macroname>BOOST_ONCE_INIT</macroname>) can be used to run a
routine exactly once. This can be used to initialize data in a routine exactly once. This can be used to initialize data in a
<link linkend="thread.glossary.thread-safe">thread-safe</link> <link linkend="threads.glossary.thread-safe">thread-safe</link>
manner.</purpose> manner.</purpose>
<description>The implementation-defined macro <description>The implementation-defined macro
@@ -31,7 +27,7 @@
<code>once_flag</code> type (statically initialized to <code>once_flag</code> type (statically initialized to
<macroname>BOOST_ONCE_INIT</macroname>) can be used to run a <macroname>BOOST_ONCE_INIT</macroname>) can be used to run a
routine exactly once. This can be used to initialize data in a routine exactly once. This can be used to initialize data in a
<link linkend="thread.glossary.thread-safe">thread-safe</link> <link linkend="threads.glossary.thread-safe">thread-safe</link>
manner.</purpose> manner.</purpose>
<description>The implementation-defined type <code>once_flag</code> <description>The implementation-defined type <code>once_flag</code>
@@ -49,7 +45,7 @@
<code>once_flag</code> type (statically initialized to <code>once_flag</code> type (statically initialized to
<macroname>BOOST_ONCE_INIT</macroname>) can be used to run a <macroname>BOOST_ONCE_INIT</macroname>) can be used to run a
routine exactly once. This can be used to initialize data in a routine exactly once. This can be used to initialize data in a
<link linkend="thread.glossary.thread-safe">thread-safe</link> <link linkend="threads.glossary.thread-safe">thread-safe</link>
manner.</purpose> manner.</purpose>
<description> <description>

View File

@@ -1,23 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford <section id="threads.overview" last-revision="$Date$">
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<section id="thread.overview" last-revision="$Date$">
<title>Overview</title> <title>Overview</title>
<section id="thread.introduction"> <section id="threads.introduction">
<title>Introduction</title> <title>Introduction</title>
<para>&Boost.Thread; allows C++ programs to execute as multiple, <para>&Boost.Threads; allows C++ programs to execute as multiple,
asynchronous, independent threads-of-execution. Each thread has its own asynchronous, independent threads-of-execution. Each thread has its own
machine state including program instruction counter and registers. Programs machine state including program instruction counter and registers. Programs
which execute as multiple threads are called multithreaded programs to which execute as multiple threads are called multithreaded programs to
distinguish them from traditional single-threaded programs. The <link distinguish them from traditional single-threaded programs. The <link
linkend="thread.glossary">glossary</link> gives a more complete description linkend="threads.glossary">glossary</link> gives a more complete description
of the multithreading execution environment.</para> of the multithreading execution environment.</para>
<para>Multithreading provides several advantages: <para>Multithreading provides several advantages:
<itemizedlist> <itemizedlist>
@@ -48,15 +44,15 @@
multithreaded programs are subject to additional errors: multithreaded programs are subject to additional errors:
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para><link linkend="thread.glossary.race-condition">Race <para><link linkend="threads.glossary.race-condition">Race
conditions</link></para> conditions</link></para>
</listitem> </listitem>
<listitem> <listitem>
<para><link linkend="thread.glossary.deadlock">Deadlock</link> <para><link linkend="threads.glossary.deadlock">Deadlock</link>
(sometimes called "deadly embrace")</para> (sometimes called "deadly embrace")</para>
</listitem> </listitem>
<listitem> <listitem>
<para><link linkend="thread.glossary.priority-failure">Priority <para><link linkend="threads.glossary.priority-failure">Priority
failures</link> (priority inversion, infinite overtaking, starvation, failures</link> (priority inversion, infinite overtaking, starvation,
etc.)</para> etc.)</para>
</listitem> </listitem>
@@ -65,10 +61,10 @@
errors. These aren't rare or exotic failures - they are virtually guaranteed errors. These aren't rare or exotic failures - they are virtually guaranteed
to occur unless multithreaded code is designed to avoid them. Priority to occur unless multithreaded code is designed to avoid them. Priority
failures are somewhat less common, but are nonetheless serious.</para> failures are somewhat less common, but are nonetheless serious.</para>
<para>The <link linkend="thread.design">&Boost.Thread; design</link> <para>The <link linkend="threads.design">&Boost.Threads; design</link>
attempts to minimize these errors, but they will still occur unless the attempts to minimize these errors, but they will still occur unless the
programmer proactively designs to avoid them.</para> programmer proactively designs to avoid them.</para>
<note>Please also see <xref linkend="thread.implementation_notes"/> <note>Please also see <xref linkend="threads.implementation_notes"/>
for additional, implementation-specific considerations.</note> for additional, implementation-specific considerations.</note>
</section> </section>
<section> <section>
@@ -123,11 +119,11 @@
<title>Runtime libraries</title> <title>Runtime libraries</title>
<para> <para>
<emphasis role="bold">Warning:</emphasis> Multithreaded programs such as <emphasis role="bold">Warning:</emphasis> Multithreaded programs such as
those using &Boost.Thread; must link to <link those using &Boost.Threads; must link to <link
linkend="thread.glossary.thread-safe">thread-safe</link> versions of linkend="threads.glossary.thread-safe">thread-safe</link> versions of
all runtime libraries used by the program, including the runtime library all runtime libraries used by the program, including the runtime library
for the C++ Standard Library. Failure to do so will cause <link for the C++ Standard Library. Failure to do so will cause <link
linkend="thread.glossary.race-condition">race conditions</link> to occur linkend="threads.glossary.race-condition">race conditions</link> to occur
when multiple threads simultaneously execute runtime library functions for when multiple threads simultaneously execute runtime library functions for
<code>new</code>, <code>delete</code>, or other language features which <code>new</code>, <code>delete</code>, or other language features which
imply shared state.</para> imply shared state.</para>
@@ -173,15 +169,15 @@
</section> </section>
</section> </section>
<section> <section>
<title>Common guarantees for all &Boost.Thread; components</title> <title>Common guarantees for all &Boost.Threads; components</title>
<section> <section>
<title>Exceptions</title> <title>Exceptions</title>
<para>&Boost.Thread; destructors never <para>&Boost.Threads; destructors never
throw exceptions. Unless otherwise specified, other throw exceptions. Unless otherwise specified, other
&Boost.Thread; functions that do not have &Boost.Threads; functions that do not have
an exception-specification may throw implementation-defined an exception-specification may throw implementation-defined
exceptions.</para> exceptions.</para>
<para>In particular, &Boost.Thread; <para>In particular, &Boost.Threads;
reports failure to allocate storage by throwing an exception of type reports failure to allocate storage by throwing an exception of type
<code>std::bad_alloc</code> or a class derived from <code>std::bad_alloc</code> or a class derived from
<code>std::bad_alloc</code>, failure to obtain thread resources other than <code>std::bad_alloc</code>, failure to obtain thread resources other than
@@ -195,7 +191,7 @@
</section> </section>
<section> <section>
<title>NonCopyable requirement</title> <title>NonCopyable requirement</title>
<para>&Boost.Thread; classes documented as <para>&Boost.Threads; classes documented as
meeting the NonCopyable requirement disallow copy construction and copy meeting the NonCopyable requirement disallow copy construction and copy
assignment. For the sake of exposition, the synopsis of such classes show assignment. For the sake of exposition, the synopsis of such classes show
private derivation from <classname>boost::noncopyable</classname>. Users private derivation from <classname>boost::noncopyable</classname>. Users

View File

@@ -1,23 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford <section id="threads.rationale" last-revision="$Date$">
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<section id="thread.rationale" last-revision="$Date$">
<title>Rationale</title> <title>Rationale</title>
<para>This page explains the rationale behind various design decisions in the <para>This page explains the rationale behind various design decisions in the
&Boost.Thread; library. Having the rationale documented here should explain &Boost.Threads; library. Having the rationale documented here should explain
how we arrived at the current design as well as prevent future rehashing of how we arrived at the current design as well as prevent future rehashing of
discussions and thought processes that have already occurred. It can also give discussions and thought processes that have already occurred. It can also give
users a lot of insight into the design process required for this users a lot of insight into the design process required for this
library.</para> library.</para>
<section id="thread.rationale.Boost.Thread"> <section id="threads.rationale.Boost.Threads">
<title>Rationale for the Creation of &Boost.Thread;</title> <title>Rationale for the Creation of &Boost.Threads;</title>
<para>Processes often have a degree of "potential parallelism" and it can <para>Processes often have a degree of "potential parallelism" and it can
often be more intuitive to design systems with this in mind. Further, these often be more intuitive to design systems with this in mind. Further, these
parallel processes can result in more responsive programs. The benefits for parallel processes can result in more responsive programs. The benefits for
@@ -37,24 +33,24 @@
<para>What's truly needed is C++ language support for threads. However, the <para>What's truly needed is C++ language support for threads. However, the
C++ standards committee needs existing practice or a good proposal as a C++ standards committee needs existing practice or a good proposal as a
starting point for adding this to the standard.</para> starting point for adding this to the standard.</para>
<para>The &Boost.Thread; library was developed to provide a C++ developer <para>The &Boost.Threads; library was developed to provide a C++ developer
with a portable interface for writing multithreaded programs on numerous with a portable interface for writing multithreaded programs on numerous
platforms. There's a hope that the library can be the basis for a more platforms. There's a hope that the library can be the basis for a more
detailed proposal for the C++ standards committee to consider for inclusion detailed proposal for the C++ standards committee to consider for inclusion
in the next C++ standard.</para> in the next C++ standard.</para>
</section> </section>
<section id="thread.rationale.primitives"> <section id="threads.rationale.primitives">
<title>Rationale for the Low Level Primitives Supported in &Boost.Thread;</title> <title>Rationale for the Low Level Primitives Supported in &Boost.Threads;</title>
<para>The &Boost.Thread; library supplies a set of low level primitives for <para>The &Boost.Threads; library supplies a set of low level primitives for
writing multithreaded programs, such as mutexes and condition variables. In writing multithreaded programs, such as mutexes and condition variables. In
fact, the first release of &Boost.Thread; supports only these low level fact, the first release of &Boost.Threads; supports only these low level
primitives. However, computer science research has shown that use of these primitives. However, computer science research has shown that use of these
primitives is difficult since it's difficult to mathematically prove that a primitives is difficult since it's difficult to mathematically prove that a
usage pattern is correct, meaning it doesn't result in race conditions or usage pattern is correct, meaning it doesn't result in race conditions or
deadlocks. There are several algebras (such as CSP, CCS and Join calculus) deadlocks. There are several algebras (such as CSP, CCS and Join calculus)
that have been developed to help write provably correct parallel that have been developed to help write provably correct parallel
processes. In order to prove the correctness these processes must be coded processes. In order to prove the correctness these processes must be coded
using higher level abstractions. So why does &Boost.Thread; support the using higher level abstractions. So why does &Boost.Threads; support the
lower level concepts?</para> lower level concepts?</para>
<para>The reason is simple: the higher level concepts need to be implemented <para>The reason is simple: the higher level concepts need to be implemented
using at least some of the lower level concepts. So having portable lower using at least some of the lower level concepts. So having portable lower
@@ -68,11 +64,11 @@
level concepts, supporting the lower level concepts provides level concepts, supporting the lower level concepts provides
greater accessibility.</para> greater accessibility.</para>
</section> </section>
<section id="thread.rationale.locks"> <section id="threads.rationale.locks">
<title>Rationale for the Lock Design</title> <title>Rationale for the Lock Design</title>
<para>Programmers who are used to multithreaded programming issues will <para>Programmers who are used to multithreaded programming issues will
quickly note that the &Boost.Thread; design for mutex lock concepts is not quickly note that the &Boost.Threads; design for mutex lock concepts is not
<link linkend="thread.glossary.thread-safe">thread-safe</link> (this is <link linkend="threads.glossary.thread-safe">thread-safe</link> (this is
clearly documented as well). At first this may seem like a serious design clearly documented as well). At first this may seem like a serious design
flaw. Why have a multithreading primitive that's not thread-safe flaw. Why have a multithreading primitive that's not thread-safe
itself?</para> itself?</para>
@@ -95,17 +91,17 @@
since checking the state can occur only by a call after construction, we'd since checking the state can occur only by a call after construction, we'd
have a race condition if the lock object were shared between threads.</para> have a race condition if the lock object were shared between threads.</para>
<para>So, to avoid the overhead of synchronizing access to the state <para>So, to avoid the overhead of synchronizing access to the state
information and to avoid the race condition, the &Boost.Thread; library information and to avoid the race condition, the &Boost.Threads; library
simply does nothing to make lock objects thread-safe. Instead, sharing a simply does nothing to make lock objects thread-safe. Instead, sharing a
lock object between threads results in undefined behavior. Since the only lock object between threads results in undefined behavior. Since the only
proper usage of lock objects is within block scope this isn't a problem, and proper usage of lock objects is within block scope this isn't a problem, and
so long as the lock object is properly used there's no danger of any so long as the lock object is properly used there's no danger of any
multithreading issues.</para> multithreading issues.</para>
</section> </section>
<section id="thread.rationale.non-copyable"> <section id="threads.rationale.non-copyable">
<title>Rationale for NonCopyable Thread Type</title> <title>Rationale for NonCopyable Thread Type</title>
<para>Programmers who are used to C libraries for multithreaded programming <para>Programmers who are used to C libraries for multithreaded programming
are likely to wonder why &Boost.Thread; uses a noncopyable design for are likely to wonder why &Boost.Threads; uses a noncopyable design for
<classname>boost::thread</classname>. After all, the C thread types are <classname>boost::thread</classname>. After all, the C thread types are
copyable, and you often have a need for copying them within user copyable, and you often have a need for copying them within user
code. However, careful comparison of C designs to C++ designs shows a flaw code. However, careful comparison of C designs to C++ designs shows a flaw
@@ -141,7 +137,7 @@
appear to bear them out. To illustrate the analysis we'll first provide appear to bear them out. To illustrate the analysis we'll first provide
pseudo-code illustrating the six typical usage patterns of a thread pseudo-code illustrating the six typical usage patterns of a thread
object.</para> object.</para>
<section id="thread.rationale.non-copyable.simple"> <section id="threads.rationale.non-copyable.simple">
<title>1. Use case: Simple creation of a thread.</title> <title>1. Use case: Simple creation of a thread.</title>
<programlisting> <programlisting>
void foo() void foo()
@@ -150,7 +146,7 @@
} }
</programlisting> </programlisting>
</section> </section>
<section id="thread.rationale.non-copyable.joined"> <section id="threads.rationale.non-copyable.joined">
<title>2. Use case: Creation of a thread that's later joined.</title> <title>2. Use case: Creation of a thread that's later joined.</title>
<programlisting> <programlisting>
void foo() void foo()
@@ -160,7 +156,7 @@
} }
</programlisting> </programlisting>
</section> </section>
<section id="thread.rationale.non-copyable.loop"> <section id="threads.rationale.non-copyable.loop">
<title>3. Use case: Simple creation of several threads in a loop.</title> <title>3. Use case: Simple creation of several threads in a loop.</title>
<programlisting> <programlisting>
void foo() void foo()
@@ -170,7 +166,7 @@
} }
</programlisting> </programlisting>
</section> </section>
<section id="thread.rationale.non-copyable.loop-join"> <section id="threads.rationale.non-copyable.loop-join">
<title>4. Use case: Creation of several threads in a loop which are later joined.</title> <title>4. Use case: Creation of several threads in a loop which are later joined.</title>
<programlisting> <programlisting>
void foo() void foo()
@@ -182,7 +178,7 @@
} }
</programlisting> </programlisting>
</section> </section>
<section id="thread.rationale.non-copyable.pass"> <section id="threads.rationale.non-copyable.pass">
<title>5. Use case: Creation of a thread whose ownership is passed to another object/method.</title> <title>5. Use case: Creation of a thread whose ownership is passed to another object/method.</title>
<programlisting> <programlisting>
void foo() void foo()
@@ -192,7 +188,7 @@
} }
</programlisting> </programlisting>
</section> </section>
<section id="thread.rationale.non-copyable.shared"> <section id="threads.rationale.non-copyable.shared">
<title>6. Use case: Creation of a thread whose ownership is shared between multiple <title>6. Use case: Creation of a thread whose ownership is shared between multiple
objects.</title> objects.</title>
<programlisting> <programlisting>
@@ -225,7 +221,7 @@
use a concept for any of the usage patterns there would be a good argument use a concept for any of the usage patterns there would be a good argument
for choosing the other design. So we'll code all six usage patterns using for choosing the other design. So we'll code all six usage patterns using
both designs.</para> both designs.</para>
<section id="thread.rationale_comparison.non-copyable.simple"> <section id="threads.rationale_comparison.non-copyable.simple">
<title>1. Comparison: simple creation of a thread.</title> <title>1. Comparison: simple creation of a thread.</title>
<programlisting> <programlisting>
void foo() void foo()
@@ -238,7 +234,7 @@
} }
</programlisting> </programlisting>
</section> </section>
<section id="thread.rationale_comparison.non-copyable.joined"> <section id="threads.rationale_comparison.non-copyable.joined">
<title>2. Comparison: creation of a thread that's later joined.</title> <title>2. Comparison: creation of a thread that's later joined.</title>
<programlisting> <programlisting>
void foo() void foo()
@@ -253,7 +249,7 @@
} }
</programlisting> </programlisting>
</section> </section>
<section id="thread.rationale_comparison.non-copyable.loop"> <section id="threads.rationale_comparison.non-copyable.loop">
<title>3. Comparison: simple creation of several threads in a loop.</title> <title>3. Comparison: simple creation of several threads in a loop.</title>
<programlisting> <programlisting>
void foo() void foo()
@@ -268,7 +264,7 @@
} }
</programlisting> </programlisting>
</section> </section>
<section id="thread.rationale_comparison.non-copyable.loop-join"> <section id="threads.rationale_comparison.non-copyable.loop-join">
<title>4. Comparison: creation of several threads in a loop which are later joined.</title> <title>4. Comparison: creation of several threads in a loop which are later joined.</title>
<programlisting> <programlisting>
void foo() void foo()
@@ -289,7 +285,7 @@
} }
</programlisting> </programlisting>
</section> </section>
<section id="thread.rationale_comparison.non-copyable.pass"> <section id="threads.rationale_comparison.non-copyable.pass">
<title>5. Comparison: creation of a thread whose ownership is passed to another object/method.</title> <title>5. Comparison: creation of a thread whose ownership is passed to another object/method.</title>
<programlisting> <programlisting>
void foo() void foo()
@@ -304,7 +300,7 @@
} }
</programlisting> </programlisting>
</section> </section>
<section id="thread.rationale_comparison.non-copyable.shared"> <section id="threads.rationale_comparison.non-copyable.shared">
<title>6. Comparison: creation of a thread whose ownership is shared <title>6. Comparison: creation of a thread whose ownership is shared
between multiple objects.</title> between multiple objects.</title>
<programlisting> <programlisting>
@@ -325,18 +321,18 @@
<para>This shows the usage patterns being nearly identical in complexity for <para>This shows the usage patterns being nearly identical in complexity for
both designs. The only actual added complexity occurs because of the use of both designs. The only actual added complexity occurs because of the use of
operator new in operator new in
<link linkend="thread.rationale_comparison.non-copyable.loop-join">(4)</link>, <link linkend="threads.rationale_comparison.non-copyable.loop-join">(4)</link>,
<link linkend="thread.rationale_comparison.non-copyable.pass">(5)</link>, and <link linkend="threads.rationale_comparison.non-copyable.pass">(5)</link>, and
<link linkend="thread.rationale_comparison.non-copyable.shared">(6)</link>; <link linkend="threads.rationale_comparison.non-copyable.shared">(6)</link>;
and the use of std::auto_ptr and boost::shared_ptr in and the use of std::auto_ptr and boost::shared_ptr in
<link linkend="thread.rationale_comparison.non-copyable.loop-join">(4)</link> and <link linkend="threads.rationale_comparison.non-copyable.loop-join">(4)</link> and
<link linkend="thread.rationale_comparison.non-copyable.shared">(6)</link> <link linkend="threads.rationale_comparison.non-copyable.shared">(6)</link>
respectively. However, that's not really respectively. However, that's not really
much added complexity, and C++ programmers are used to using these idioms much added complexity, and C++ programmers are used to using these idioms
anyway. Some may dislike the presence of operator new in user code, but anyway. Some may dislike the presence of operator new in user code, but
this can be eliminated by proper design of higher level concepts, such as this can be eliminated by proper design of higher level concepts, such as
the boost::thread_group class that simplifies example the boost::thread_group class that simplifies example
<link linkend="thread.rationale_comparison.non-copyable.loop-join">(4)</link> <link linkend="threads.rationale_comparison.non-copyable.loop-join">(4)</link>
down to:</para> down to:</para>
<programlisting> <programlisting>
void foo() void foo()
@@ -351,49 +347,49 @@
design.</para> design.</para>
<para>So what about performance? Looking at the above code examples, <para>So what about performance? Looking at the above code examples,
we can analyze the theoretical impact to performance that both designs we can analyze the theoretical impact to performance that both designs
have. For <link linkend="thread.rationale_comparison.non-copyable.simple">(1)</link> have. For <link linkend="threads.rationale_comparison.non-copyable.simple">(1)</link>
we can see that platforms that don't have a ref-counted native we can see that platforms that don't have a ref-counted native
thread type (POSIX, for instance) will be impacted by a thread_ref thread type (POSIX, for instance) will be impacted by a thread_ref
design. Even if the native thread type is ref-counted there may be an impact design. Even if the native thread type is ref-counted there may be an impact
if more state information has to be maintained for concepts foreign to the if more state information has to be maintained for concepts foreign to the
native API, such as clean up stacks for Win32 implementations. native API, such as clean up stacks for Win32 implementations.
For <link linkend="thread.rationale_comparison.non-copyable.joined">(2)</link> For <link linkend="threads.rationale_comparison.non-copyable.joined">(2)</link>
and <link linkend="thread.rationale_comparison.non-copyable.loop">(3)</link> and <link linkend="threads.rationale_comparison.non-copyable.loop">(3)</link>
the performance impact will be identical to the performance impact will be identical to
<link linkend="thread.rationale_comparison.non-copyable.simple">(1)</link>. <link linkend="threads.rationale_comparison.non-copyable.simple">(1)</link>.
For <link linkend="thread.rationale_comparison.non-copyable.loop-join">(4)</link> For <link linkend="threads.rationale_comparison.non-copyable.loop-join">(4)</link>
things get a little more interesting and we find that theoretically at least things get a little more interesting and we find that theoretically at least
the thread_ref may perform faster since the thread design requires dynamic the thread_ref may perform faster since the thread design requires dynamic
memory allocation/deallocation. However, in practice there may be dynamic memory allocation/deallocation. However, in practice there may be dynamic
allocation for the thread_ref design as well, it will just be hidden from allocation for the thread_ref design as well, it will just be hidden from
the user. As long as the implementation has to do dynamic allocations the the user. As long as the implementation has to do dynamic allocations the
thread_ref loses again because of the reference management. For thread_ref loses again because of the reference management. For
<link linkend="thread.rationale_comparison.non-copyable.pass">(5)</link> we see <link linkend="threads.rationale_comparison.non-copyable.pass">(5)</link> we see
the same impact as we do for the same impact as we do for
<link linkend="thread.rationale_comparison.non-copyable.loop-join">(4)</link>. <link linkend="threads.rationale_comparison.non-copyable.loop-join">(4)</link>.
For <link linkend="thread.rationale_comparison.non-copyable.shared">(6)</link> For <link linkend="threads.rationale_comparison.non-copyable.shared">(6)</link>
we still have a possible impact to we still have a possible impact to
the thread design because of dynamic allocation but thread_ref no longer the thread design because of dynamic allocation but thread_ref no longer
suffers because of its reference management, and in fact, theoretically at suffers because of its reference management, and in fact, theoretically at
least, the thread_ref may do a better job of managing the references. All of least, the thread_ref may do a better job of managing the references. All of
this indicates that thread wins for this indicates that thread wins for
<link linkend="thread.rationale_comparison.non-copyable.simple">(1)</link>, <link linkend="threads.rationale_comparison.non-copyable.simple">(1)</link>,
<link linkend="thread.rationale_comparison.non-copyable.joined">(2)</link> and <link linkend="threads.rationale_comparison.non-copyable.joined">(2)</link> and
<link linkend="thread.rationale_comparison.non-copyable.loop">(3)</link>; with <link linkend="threads.rationale_comparison.non-copyable.loop">(3)</link>; with
<link linkend="thread.rationale_comparison.non-copyable.loop-join">(4)</link> <link linkend="threads.rationale_comparison.non-copyable.loop-join">(4)</link>
and <link linkend="thread.rationale_comparison.non-copyable.pass">(5)</link> the and <link linkend="threads.rationale_comparison.non-copyable.pass">(5)</link> the
winner depending on the implementation and the platform but with the thread design winner depending on the implementation and the platform but with the thread design
probably having a better chance; and with probably having a better chance; and with
<link linkend="thread.rationale_comparison.non-copyable.shared">(6)</link> <link linkend="threads.rationale_comparison.non-copyable.shared">(6)</link>
it will again depend on the it will again depend on the
implementation and platform but this time we favor thread_ref implementation and platform but this time we favor thread_ref
slightly. Given all of this it's a narrow margin, but the thread design slightly. Given all of this it's a narrow margin, but the thread design
prevails.</para> prevails.</para>
<para>Given this analysis, and the fact that noncopyable objects for system <para>Given this analysis, and the fact that noncopyable objects for system
resources are the normal designs that C++ programmers are used to dealing resources are the normal designs that C++ programmers are used to dealing
with, the &Boost.Thread; library has gone with a noncopyable design.</para> with, the &Boost.Threads; library has gone with a noncopyable design.</para>
</section> </section>
<section id="thread.rationale.events"> <section id="threads.rationale.events">
<title>Rationale for not providing <emphasis>Event Variables</emphasis></title> <title>Rationale for not providing <emphasis>Event Variables</emphasis></title>
<para><emphasis>Event variables</emphasis> are simply far too <para><emphasis>Event variables</emphasis> are simply far too
error-prone. <classname>boost::condition</classname> variables are a much safer error-prone. <classname>boost::condition</classname> variables are a much safer
@@ -420,13 +416,13 @@
experiences caused them to be very careful in their use of event experiences caused them to be very careful in their use of event
variables. Overt problems can be avoided, for example, by teaming the event variables. Overt problems can be avoided, for example, by teaming the event
variable with a mutex, but that may just convert a <link variable with a mutex, but that may just convert a <link
linkend="thread.glossary.race-condition">race condition</link> into another linkend="threads.glossary.race-condition">race condition</link> into another
problem, such as excessive resource use. One of the most distressing aspects problem, such as excessive resource use. One of the most distressing aspects
of the experience reports is the claim that many defects are latent. That of the experience reports is the claim that many defects are latent. That
is, the programs appear to work correctly, but contain hidden timing is, the programs appear to work correctly, but contain hidden timing
dependencies which will cause them to fail when environmental factors or dependencies which will cause them to fail when environmental factors or
usage patterns change, altering relative thread timings.</para> usage patterns change, altering relative thread timings.</para>
<para>The decision to exclude event variables from &Boost.Thread; has been <para>The decision to exclude event variables from &Boost.Threads; has been
surprising to some Windows programmers. They have written programs which surprising to some Windows programmers. They have written programs which
work using event variables, and wonder what the problem is. It seems similar work using event variables, and wonder what the problem is. It seems similar
to the "goto considered harmful" controversy of 30 years ago. It isn't that to the "goto considered harmful" controversy of 30 years ago. It isn't that

View File

@@ -1,13 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<header name="boost/thread/read_write_mutex.hpp" <header name="boost/thread/read_write_mutex.hpp"
last-revision="$Date$"> last-revision="$Date$">
<namespace name="boost"> <namespace name="boost">
@@ -20,13 +16,13 @@
<purpose> <purpose>
<para>Specifies the <para>Specifies the
<link linkend="thread.concepts.read-write-scheduling-policies.inter-class">inter-class sheduling policy</link> <link linkend="threads.concepts.read-write-scheduling-policies.inter-class">inter-class sheduling policy</link>
to use when a set of threads try to obtain different types of to use when a set of threads try to obtain different types of
locks simultaneously.</para> locks simultaneously.</para>
</purpose> </purpose>
<description> <description>
<para>The only clock type supported by &Boost.Thread; is <para>The only clock type supported by &Boost.Threads; is
<code>TIME_UTC</code>. The epoch for <code>TIME_UTC</code> <code>TIME_UTC</code>. The epoch for <code>TIME_UTC</code>
is 1970-01-01 00:00:00.</para> is 1970-01-01 00:00:00.</para>
</description> </description>
@@ -36,21 +32,21 @@
<class name="read_write_mutex"> <class name="read_write_mutex">
<purpose> <purpose>
<para>The <classname>read_write_mutex</classname> class is a model of the <para>The <classname>read_write_mutex</classname> class is a model of the
<link linkend="thread.concepts.ReadWriteMutex">ReadWriteMutex</link> concept.</para> <link linkend="threads.concepts.ReadWriteMutex">ReadWriteMutex</link> concept.</para>
</purpose> </purpose>
<description> <description>
<para>The <classname>read_write_mutex</classname> class is a model of the <para>The <classname>read_write_mutex</classname> class is a model of the
<link linkend="thread.concepts.ReadWriteMutex">ReadWriteMutex</link> concept. <link linkend="threads.concepts.ReadWriteMutex">ReadWriteMutex</link> concept.
It should be used to synchronize access to shared resources using It should be used to synchronize access to shared resources using
<link linkend="thread.concepts.read-write-locking-strategies.unspecified">Unspecified</link> <link linkend="threads.concepts.read-write-locking-strategies.unspecified">Unspecified</link>
locking mechanics.</para> locking mechanics.</para>
<para>For classes that model related mutex concepts, see <para>For classes that model related mutex concepts, see
<classname>try_read_write_mutex</classname> and <classname>timed_read_write_mutex</classname>.</para> <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, <para>The <classname>read_write_mutex</classname> class supplies the following typedefs,
which <link linkend="thread.concepts.read-write-lock-models">model</link> which <link linkend="threads.concepts.read-write-lock-models">model</link>
the specified locking strategies: the specified locking strategies:
<informaltable> <informaltable>
@@ -64,15 +60,15 @@
<tbody> <tbody>
<row> <row>
<entry>scoped_read_write_lock</entry> <entry>scoped_read_write_lock</entry>
<entry><link linkend="thread.concepts.ScopedReadWriteLock">ScopedReadWriteLock</link></entry> <entry><link linkend="threads.concepts.ScopedReadWriteLock">ScopedReadWriteLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_read_lock</entry> <entry>scoped_read_lock</entry>
<entry><link linkend="thread.concepts.ScopedLock">ScopedLock</link></entry> <entry><link linkend="threads.concepts.ScopedLock">ScopedLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_write_lock</entry> <entry>scoped_write_lock</entry>
<entry><link linkend="thread.concepts.ScopedLock">ScopedLock</link></entry> <entry><link linkend="threads.concepts.ScopedLock">ScopedLock</link></entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
@@ -80,7 +76,7 @@
</para> </para>
<para>The <classname>read_write_mutex</classname> class uses an <para>The <classname>read_write_mutex</classname> class uses an
<link linkend="thread.concepts.read-write-locking-strategies.unspecified">Unspecified</link> <link linkend="threads.concepts.read-write-locking-strategies.unspecified">Unspecified</link>
locking strategy, so attempts to recursively lock a <classname>read_write_mutex</classname> locking strategy, so attempts to recursively lock a <classname>read_write_mutex</classname>
object or attempts to unlock one by threads that don't own a lock on it result in object or attempts to unlock one by threads that don't own a lock on it result in
<emphasis role="bold">undefined behavior</emphasis>. <emphasis role="bold">undefined behavior</emphasis>.
@@ -90,20 +86,20 @@
<code>NDEBUG</code> is not defined.</para> <code>NDEBUG</code> is not defined.</para>
<para>Like all <para>Like all
<link linkend="thread.concepts.read-write-mutex-models">read/write mutex models</link> <link linkend="threads.concepts.read-write-mutex-models">read/write mutex models</link>
in &Boost.Thread;, <classname>read_write_mutex</classname> has two types of in &Boost.Threads;, <classname>read_write_mutex</classname> has two types of
<link linkend="thread.concepts.read-write-scheduling-policies">scheduling policies</link>, an <link linkend="threads.concepts.read-write-scheduling-policies">scheduling policies</link>, an
<link linkend="thread.concepts.read-write-scheduling-policies.inter-class">inter-class sheduling policy</link> <link linkend="threads.concepts.read-write-scheduling-policies.inter-class">inter-class sheduling policy</link>
between threads trying to obtain different types of locks and an between threads trying to obtain different types of locks and an
<link linkend="thread.concepts.read-write-scheduling-policies.intra-class">intra-class sheduling policy</link> <link linkend="threads.concepts.read-write-scheduling-policies.intra-class">intra-class sheduling policy</link>
between threads trying to obtain the same type of lock. between threads trying to obtain the same type of lock.
The <classname>read_write_mutex</classname> class allows the The <classname>read_write_mutex</classname> class allows the
programmer to choose what programmer to choose what
<link linkend="thread.concepts.read-write-scheduling-policies.inter-class">inter-class sheduling policy</link> <link linkend="threads.concepts.read-write-scheduling-policies.inter-class">inter-class sheduling policy</link>
will be used; however, like all read/write mutex models, will be used; however, like all read/write mutex models,
<classname>read_write_mutex</classname> leaves the <classname>read_write_mutex</classname> leaves the
<link linkend="thread.concepts.read-write-scheduling-policies.intra-class">intra-class sheduling policy</link> as <link linkend="threads.concepts.read-write-scheduling-policies.intra-class">intra-class sheduling policy</link> as
<link linkend="thread.concepts.read-write-locking-strategies.unspecified">Unspecified</link>. <link linkend="threads.concepts.read-write-locking-strategies.unspecified">Unspecified</link>.
</para> </para>
<note>Self-deadlock is virtually guaranteed if a thread tries to <note>Self-deadlock is virtually guaranteed if a thread tries to
@@ -159,21 +155,21 @@
<class name="try_read_write_mutex"> <class name="try_read_write_mutex">
<purpose> <purpose>
<para>The <classname>try_read_write_mutex</classname> class is a model of the <para>The <classname>try_read_write_mutex</classname> class is a model of the
<link linkend="thread.concepts.TryReadWriteMutex">TryReadWriteMutex</link> concept.</para> <link linkend="threads.concepts.TryReadWriteMutex">TryReadWriteMutex</link> concept.</para>
</purpose> </purpose>
<description> <description>
<para>The <classname>try_read_write_mutex</classname> class is a model of the <para>The <classname>try_read_write_mutex</classname> class is a model of the
<link linkend="thread.concepts.TryReadWriteMutex">TryReadWriteMutex</link> concept. <link linkend="threads.concepts.TryReadWriteMutex">TryReadWriteMutex</link> concept.
It should be used to synchronize access to shared resources using It should be used to synchronize access to shared resources using
<link linkend="thread.concepts.read-write-locking-strategies.unspecified">Unspecified</link> <link linkend="threads.concepts.read-write-locking-strategies.unspecified">Unspecified</link>
locking mechanics.</para> locking mechanics.</para>
<para>For classes that model related mutex concepts, see <para>For classes that model related mutex concepts, see
<classname>read_write_mutex</classname> and <classname>timed_read_write_mutex</classname>.</para> <classname>read_write_mutex</classname> and <classname>timed_read_write_mutex</classname>.</para>
<para>The <classname>try_read_write_mutex</classname> class supplies the following typedefs, <para>The <classname>try_read_write_mutex</classname> class supplies the following typedefs,
which <link linkend="thread.concepts.read-write-lock-models">model</link> which <link linkend="threads.concepts.read-write-lock-models">model</link>
the specified locking strategies: the specified locking strategies:
<informaltable> <informaltable>
@@ -187,27 +183,27 @@
<tbody> <tbody>
<row> <row>
<entry>scoped_read_write_lock</entry> <entry>scoped_read_write_lock</entry>
<entry><link linkend="thread.concepts.ScopedReadWriteLock">ScopedReadWriteLock</link></entry> <entry><link linkend="threads.concepts.ScopedReadWriteLock">ScopedReadWriteLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_try_read_write_lock</entry> <entry>scoped_try_read_write_lock</entry>
<entry><link linkend="thread.concepts.ScopedTryReadWriteLock">ScopedTryReadWriteLock</link></entry> <entry><link linkend="threads.concepts.ScopedTryReadWriteLock">ScopedTryReadWriteLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_read_lock</entry> <entry>scoped_read_lock</entry>
<entry><link linkend="thread.concepts.ScopedLock">ScopedLock</link></entry> <entry><link linkend="threads.concepts.ScopedLock">ScopedLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_try_read_lock</entry> <entry>scoped_try_read_lock</entry>
<entry><link linkend="thread.concepts.ScopedTryLock">ScopedTryLock</link></entry> <entry><link linkend="threads.concepts.ScopedTryLock">ScopedTryLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_write_lock</entry> <entry>scoped_write_lock</entry>
<entry><link linkend="thread.concepts.ScopedLock">ScopedLock</link></entry> <entry><link linkend="threads.concepts.ScopedLock">ScopedLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_try_write_lock</entry> <entry>scoped_try_write_lock</entry>
<entry><link linkend="thread.concepts.ScopedTryLock">ScopedTryLock</link></entry> <entry><link linkend="threads.concepts.ScopedTryLock">ScopedTryLock</link></entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
@@ -215,7 +211,7 @@
</para> </para>
<para>The <classname>try_read_write_mutex</classname> class uses an <para>The <classname>try_read_write_mutex</classname> class uses an
<link linkend="thread.concepts.read-write-locking-strategies.unspecified">Unspecified</link> <link linkend="threads.concepts.read-write-locking-strategies.unspecified">Unspecified</link>
locking strategy, so attempts to recursively lock a <classname>try_read_write_mutex</classname> locking strategy, so attempts to recursively lock a <classname>try_read_write_mutex</classname>
object or attempts to unlock one by threads that don't own a lock on it result in object or attempts to unlock one by threads that don't own a lock on it result in
<emphasis role="bold">undefined behavior</emphasis>. <emphasis role="bold">undefined behavior</emphasis>.
@@ -225,20 +221,20 @@
<code>NDEBUG</code> is not defined.</para> <code>NDEBUG</code> is not defined.</para>
<para>Like all <para>Like all
<link linkend="thread.concepts.read-write-mutex-models">read/write mutex models</link> <link linkend="threads.concepts.read-write-mutex-models">read/write mutex models</link>
in &Boost.Thread;, <classname>try_read_write_mutex</classname> has two types of in &Boost.Threads;, <classname>try_read_write_mutex</classname> has two types of
<link linkend="thread.concepts.read-write-scheduling-policies">scheduling policies</link>, an <link linkend="threads.concepts.read-write-scheduling-policies">scheduling policies</link>, an
<link linkend="thread.concepts.read-write-scheduling-policies.inter-class">inter-class sheduling policy</link> <link linkend="threads.concepts.read-write-scheduling-policies.inter-class">inter-class sheduling policy</link>
between threads trying to obtain different types of locks and an between threads trying to obtain different types of locks and an
<link linkend="thread.concepts.read-write-scheduling-policies.intra-class">intra-class sheduling policy</link> <link linkend="threads.concepts.read-write-scheduling-policies.intra-class">intra-class sheduling policy</link>
between threads trying to obtain the same type of lock. between threads trying to obtain the same type of lock.
The <classname>try_read_write_mutex</classname> class allows the The <classname>try_read_write_mutex</classname> class allows the
programmer to choose what programmer to choose what
<link linkend="thread.concepts.read-write-scheduling-policies.inter-class">inter-class sheduling policy</link> <link linkend="threads.concepts.read-write-scheduling-policies.inter-class">inter-class sheduling policy</link>
will be used; however, like all read/write mutex models, will be used; however, like all read/write mutex models,
<classname>try_read_write_mutex</classname> leaves the <classname>try_read_write_mutex</classname> leaves the
<link linkend="thread.concepts.read-write-scheduling-policies.intra-class">intra-class sheduling policy</link> as <link linkend="threads.concepts.read-write-scheduling-policies.intra-class">intra-class sheduling policy</link> as
<link linkend="thread.concepts.unspecified-scheduling-policy">Unspecified</link>. <link linkend="threads.concepts.unspecified-scheduling-policy">Unspecified</link>.
</para> </para>
<note>Self-deadlock is virtually guaranteed if a thread tries to <note>Self-deadlock is virtually guaranteed if a thread tries to
@@ -301,21 +297,21 @@
<class name="timed_read_write_mutex"> <class name="timed_read_write_mutex">
<purpose> <purpose>
<para>The <classname>timed_read_write_mutex</classname> class is a model of the <para>The <classname>timed_read_write_mutex</classname> class is a model of the
<link linkend="thread.concepts.TimedReadWriteMutex">TimedReadWriteMutex</link> concept.</para> <link linkend="threads.concepts.TimedReadWriteMutex">TimedReadWriteMutex</link> concept.</para>
</purpose> </purpose>
<description> <description>
<para>The <classname>timed_read_write_mutex</classname> class is a model of the <para>The <classname>timed_read_write_mutex</classname> class is a model of the
<link linkend="thread.concepts.TimedReadWriteMutex">TimedReadWriteMutex</link> concept. <link linkend="threads.concepts.TimedReadWriteMutex">TimedReadWriteMutex</link> concept.
It should be used to synchronize access to shared resources using It should be used to synchronize access to shared resources using
<link linkend="thread.concepts.read-write-locking-strategies.unspecified">Unspecified</link> <link linkend="threads.concepts.read-write-locking-strategies.unspecified">Unspecified</link>
locking mechanics.</para> locking mechanics.</para>
<para>For classes that model related mutex concepts, see <para>For classes that model related mutex concepts, see
<classname>read_write_mutex</classname> and <classname>try_read_write_mutex</classname>.</para> <classname>read_write_mutex</classname> and <classname>try_read_write_mutex</classname>.</para>
<para>The <classname>timed_read_write_mutex</classname> class supplies the following typedefs, <para>The <classname>timed_read_write_mutex</classname> class supplies the following typedefs,
which <link linkend="thread.concepts.read-write-lock-models">model</link> which <link linkend="threads.concepts.read-write-lock-models">model</link>
the specified locking strategies: the specified locking strategies:
<informaltable> <informaltable>
@@ -329,39 +325,39 @@
<tbody> <tbody>
<row> <row>
<entry>scoped_read_write_lock</entry> <entry>scoped_read_write_lock</entry>
<entry><link linkend="thread.concepts.ScopedReadWriteLock">ScopedReadWriteLock</link></entry> <entry><link linkend="threads.concepts.ScopedReadWriteLock">ScopedReadWriteLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_try_read_write_lock</entry> <entry>scoped_try_read_write_lock</entry>
<entry><link linkend="thread.concepts.ScopedTryReadWriteLock">ScopedTryReadWriteLock</link></entry> <entry><link linkend="threads.concepts.ScopedTryReadWriteLock">ScopedTryReadWriteLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_timed_read_write_lock</entry> <entry>scoped_timed_read_write_lock</entry>
<entry><link linkend="thread.concepts.ScopedTimedReadWriteLock">ScopedTimedReadWriteLock</link></entry> <entry><link linkend="threads.concepts.ScopedTimedReadWriteLock">ScopedTimedReadWriteLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_read_lock</entry> <entry>scoped_read_lock</entry>
<entry><link linkend="thread.concepts.ScopedLock">ScopedLock</link></entry> <entry><link linkend="threads.concepts.ScopedLock">ScopedLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_try_read_lock</entry> <entry>scoped_try_read_lock</entry>
<entry><link linkend="thread.concepts.ScopedTryLock">ScopedTryLock</link></entry> <entry><link linkend="threads.concepts.ScopedTryLock">ScopedTryLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_timed_read_lock</entry> <entry>scoped_timed_read_lock</entry>
<entry><link linkend="thread.concepts.ScopedTimedLock">ScopedTimedLock</link></entry> <entry><link linkend="threads.concepts.ScopedTimedLock">ScopedTimedLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_write_lock</entry> <entry>scoped_write_lock</entry>
<entry><link linkend="thread.concepts.ScopedLock">ScopedLock</link></entry> <entry><link linkend="threads.concepts.ScopedLock">ScopedLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_try_write_lock</entry> <entry>scoped_try_write_lock</entry>
<entry><link linkend="thread.concepts.ScopedTryLock">ScopedTryLock</link></entry> <entry><link linkend="threads.concepts.ScopedTryLock">ScopedTryLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_timed_write_lock</entry> <entry>scoped_timed_write_lock</entry>
<entry><link linkend="thread.concepts.ScopedTimedLock">ScopedTimedLock</link></entry> <entry><link linkend="threads.concepts.ScopedTimedLock">ScopedTimedLock</link></entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
@@ -369,7 +365,7 @@
</para> </para>
<para>The <classname>timed_read_write_mutex</classname> class uses an <para>The <classname>timed_read_write_mutex</classname> class uses an
<link linkend="thread.concepts.read-write-locking-strategies.unspecified">Unspecified</link> <link linkend="threads.concepts.read-write-locking-strategies.unspecified">Unspecified</link>
locking strategy, so attempts to recursively lock a <classname>timed_read_write_mutex</classname> locking strategy, so attempts to recursively lock a <classname>timed_read_write_mutex</classname>
object or attempts to unlock one by threads that don't own a lock on it result in object or attempts to unlock one by threads that don't own a lock on it result in
<emphasis role="bold">undefined behavior</emphasis>. <emphasis role="bold">undefined behavior</emphasis>.
@@ -379,20 +375,20 @@
<code>NDEBUG</code> is not defined.</para> <code>NDEBUG</code> is not defined.</para>
<para>Like all <para>Like all
<link linkend="thread.concepts.read-write-mutex-models">read/write mutex models</link> <link linkend="threads.concepts.read-write-mutex-models">read/write mutex models</link>
in &Boost.Thread;, <classname>timed_read_write_mutex</classname> has two types of in &Boost.Threads;, <classname>timed_read_write_mutex</classname> has two types of
<link linkend="thread.concepts.read-write-scheduling-policies">scheduling policies</link>, an <link linkend="threads.concepts.read-write-scheduling-policies">scheduling policies</link>, an
<link linkend="thread.concepts.read-write-scheduling-policies.inter-class">inter-class sheduling policy</link> <link linkend="threads.concepts.read-write-scheduling-policies.inter-class">inter-class sheduling policy</link>
between threads trying to obtain different types of locks and an between threads trying to obtain different types of locks and an
<link linkend="thread.concepts.read-write-scheduling-policies.intra-class">intra-class sheduling policy</link> <link linkend="threads.concepts.read-write-scheduling-policies.intra-class">intra-class sheduling policy</link>
between threads trying to obtain the same type of lock. between threads trying to obtain the same type of lock.
The <classname>timed_read_write_mutex</classname> class allows the The <classname>timed_read_write_mutex</classname> class allows the
programmer to choose what programmer to choose what
<link linkend="thread.concepts.read-write-scheduling-policies.inter-class">inter-class sheduling policy</link> <link linkend="threads.concepts.read-write-scheduling-policies.inter-class">inter-class sheduling policy</link>
will be used; however, like all read/write mutex models, will be used; however, like all read/write mutex models,
<classname>timed_read_write_mutex</classname> leaves the <classname>timed_read_write_mutex</classname> leaves the
<link linkend="thread.concepts.read-write-scheduling-policies.intra-class">intra-class sheduling policy</link> as <link linkend="threads.concepts.read-write-scheduling-policies.intra-class">intra-class sheduling policy</link> as
<link linkend="thread.concepts.unspecified-scheduling-policy">Unspecified</link>. <link linkend="threads.concepts.unspecified-scheduling-policy">Unspecified</link>.
</para> </para>
<note>Self-deadlock is virtually guaranteed if a thread tries to <note>Self-deadlock is virtually guaranteed if a thread tries to

View File

@@ -1,33 +1,29 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<header name="boost/thread/recursive_mutex.hpp" <header name="boost/thread/recursive_mutex.hpp"
last-revision="$Date$"> last-revision="$Date$">
<namespace name="boost"> <namespace name="boost">
<class name="recursive_mutex"> <class name="recursive_mutex">
<purpose> <purpose>
<para>The <classname>recursive_mutex</classname> class is a model of the <para>The <classname>recursive_mutex</classname> class is a model of the
<link linkend="thread.concepts.Mutex">Mutex</link> concept.</para> <link linkend="threads.concepts.Mutex">Mutex</link> concept.</para>
</purpose> </purpose>
<description> <description>
<para>The <classname>recursive_mutex</classname> class is a model of the <para>The <classname>recursive_mutex</classname> class is a model of the
<link linkend="thread.concepts.Mutex">Mutex</link> concept. <link linkend="threads.concepts.Mutex">Mutex</link> concept.
It should be used to synchronize access to shared resources using It should be used to synchronize access to shared resources using
<link linkend="thread.concepts.recursive-locking-strategy">Recursive</link> <link linkend="threads.concepts.recursive-locking-strategy">Recursive</link>
locking mechanics.</para> locking mechanics.</para>
<para>For classes that model related mutex concepts, see <para>For classes that model related mutex concepts, see
<classname>recursive_try_mutex</classname> and <classname>recursive_timed_mutex</classname>.</para> <classname>recursive_try_mutex</classname> and <classname>recursive_timed_mutex</classname>.</para>
<para>For <link linkend="thread.concepts.unspecified-locking-strategy">Unspecified</link> <para>For <link linkend="threads.concepts.unspecified-locking-strategy">Unspecified</link>
locking mechanics, see <classname>mutex</classname>, locking mechanics, see <classname>mutex</classname>,
<classname>try_mutex</classname>, and <classname>timed_mutex</classname>. <classname>try_mutex</classname>, and <classname>timed_mutex</classname>.
</para> </para>
@@ -47,7 +43,7 @@
<tbody> <tbody>
<row> <row>
<entry>scoped_lock</entry> <entry>scoped_lock</entry>
<entry><link linkend="thread.concepts.ScopedLock">ScopedLock</link></entry> <entry><link linkend="threads.concepts.ScopedLock">ScopedLock</link></entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
@@ -55,7 +51,7 @@
</para> </para>
<para>The <classname>recursive_mutex</classname> class uses a <para>The <classname>recursive_mutex</classname> class uses a
<link linkend="thread.concepts.recursive-locking-strategy">Recursive</link> <link linkend="threads.concepts.recursive-locking-strategy">Recursive</link>
locking strategy, so attempts to recursively lock a locking strategy, so attempts to recursively lock a
<classname>recursive_mutex</classname> object <classname>recursive_mutex</classname> object
succeed and an internal "lock count" is maintained. succeed and an internal "lock count" is maintained.
@@ -64,10 +60,10 @@
<emphasis role="bold">undefined behavior</emphasis>.</para> <emphasis role="bold">undefined behavior</emphasis>.</para>
<para>Like all <para>Like all
<link linkend="thread.concepts.mutex-models">mutex models</link> <link linkend="threads.concepts.mutex-models">mutex models</link>
in &Boost.Thread;, <classname>recursive_mutex</classname> leaves the in &Boost.Threads;, <classname>recursive_mutex</classname> leaves the
<link linkend="thread.concepts.sheduling-policies">scheduling policy</link> <link linkend="threads.concepts.sheduling-policies">scheduling policy</link>
as <link linkend="thread.concepts.unspecified-scheduling-policy">Unspecified</link>. as <link linkend="threads.concepts.unspecified-scheduling-policy">Unspecified</link>.
Programmers should make no assumptions about the order in which Programmers should make no assumptions about the order in which
waiting threads acquire a lock.</para> waiting threads acquire a lock.</para>
</description> </description>
@@ -103,20 +99,20 @@
<class name="recursive_try_mutex"> <class name="recursive_try_mutex">
<purpose> <purpose>
<para>The <classname>recursive_try_mutex</classname> class is a model of the <para>The <classname>recursive_try_mutex</classname> class is a model of the
<link linkend="thread.concepts.TryMutex">TryMutex</link> concept.</para> <link linkend="threads.concepts.TryMutex">TryMutex</link> concept.</para>
</purpose> </purpose>
<description> <description>
<para>The <classname>recursive_try_mutex</classname> class is a model of the <para>The <classname>recursive_try_mutex</classname> class is a model of the
<link linkend="thread.concepts.TryMutex">TryMutex</link> concept. <link linkend="threads.concepts.TryMutex">TryMutex</link> concept.
It should be used to synchronize access to shared resources using It should be used to synchronize access to shared resources using
<link linkend="thread.concepts.recursive-locking-strategy">Recursive</link> <link linkend="threads.concepts.recursive-locking-strategy">Recursive</link>
locking mechanics.</para> locking mechanics.</para>
<para>For classes that model related mutex concepts, see <para>For classes that model related mutex concepts, see
<classname>recursive_mutex</classname> and <classname>recursive_timed_mutex</classname>.</para> <classname>recursive_mutex</classname> and <classname>recursive_timed_mutex</classname>.</para>
<para>For <link linkend="thread.concepts.unspecified-locking-strategy">Unspecified</link> <para>For <link linkend="threads.concepts.unspecified-locking-strategy">Unspecified</link>
locking mechanics, see <classname>mutex</classname>, locking mechanics, see <classname>mutex</classname>,
<classname>try_mutex</classname>, and <classname>timed_mutex</classname>. <classname>try_mutex</classname>, and <classname>timed_mutex</classname>.
</para> </para>
@@ -136,11 +132,11 @@
<tbody> <tbody>
<row> <row>
<entry>scoped_lock</entry> <entry>scoped_lock</entry>
<entry><link linkend="thread.concepts.ScopedLock">ScopedLock</link></entry> <entry><link linkend="threads.concepts.ScopedLock">ScopedLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_try_lock</entry> <entry>scoped_try_lock</entry>
<entry><link linkend="thread.concepts.ScopedTryLock">ScopedTryLock</link></entry> <entry><link linkend="threads.concepts.ScopedTryLock">ScopedTryLock</link></entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
@@ -148,7 +144,7 @@
</para> </para>
<para>The <classname>recursive_try_mutex</classname> class uses a <para>The <classname>recursive_try_mutex</classname> class uses a
<link linkend="thread.concepts.recursive-locking-strategy">Recursive</link> <link linkend="threads.concepts.recursive-locking-strategy">Recursive</link>
locking strategy, so attempts to recursively lock a locking strategy, so attempts to recursively lock a
<classname>recursive_try_mutex</classname> object <classname>recursive_try_mutex</classname> object
succeed and an internal "lock count" is maintained. succeed and an internal "lock count" is maintained.
@@ -157,10 +153,10 @@
<emphasis role="bold">undefined behavior</emphasis>.</para> <emphasis role="bold">undefined behavior</emphasis>.</para>
<para>Like all <para>Like all
<link linkend="thread.concepts.mutex-models">mutex models</link> <link linkend="threads.concepts.mutex-models">mutex models</link>
in &Boost.Thread;, <classname>recursive_try_mutex</classname> leaves the in &Boost.Threads;, <classname>recursive_try_mutex</classname> leaves the
<link linkend="thread.concepts.sheduling-policies">scheduling policy</link> <link linkend="threads.concepts.sheduling-policies">scheduling policy</link>
as <link linkend="thread.concepts.unspecified-scheduling-policy">Unspecified</link>. as <link linkend="threads.concepts.unspecified-scheduling-policy">Unspecified</link>.
Programmers should make no assumptions about the order in which Programmers should make no assumptions about the order in which
waiting threads acquire a lock.</para> waiting threads acquire a lock.</para>
</description> </description>
@@ -201,20 +197,20 @@
<class name="recursive_timed_mutex"> <class name="recursive_timed_mutex">
<purpose> <purpose>
<para>The <classname>recursive_timed_mutex</classname> class is a model of the <para>The <classname>recursive_timed_mutex</classname> class is a model of the
<link linkend="thread.concepts.TimedMutex">TimedMutex</link> concept.</para> <link linkend="threads.concepts.TimedMutex">TimedMutex</link> concept.</para>
</purpose> </purpose>
<description> <description>
<para>The <classname>recursive_timed_mutex</classname> class is a model of the <para>The <classname>recursive_timed_mutex</classname> class is a model of the
<link linkend="thread.concepts.TimedMutex">TimedMutex</link> concept. <link linkend="threads.concepts.TimedMutex">TimedMutex</link> concept.
It should be used to synchronize access to shared resources using It should be used to synchronize access to shared resources using
<link linkend="thread.concepts.recursive-locking-strategy">Recursive</link> <link linkend="threads.concepts.recursive-locking-strategy">Recursive</link>
locking mechanics.</para> locking mechanics.</para>
<para>For classes that model related mutex concepts, see <para>For classes that model related mutex concepts, see
<classname>recursive_mutex</classname> and <classname>recursive_try_mutex</classname>.</para> <classname>recursive_mutex</classname> and <classname>recursive_try_mutex</classname>.</para>
<para>For <link linkend="thread.concepts.unspecified-locking-strategy">Unspecified</link> <para>For <link linkend="threads.concepts.unspecified-locking-strategy">Unspecified</link>
locking mechanics, see <classname>mutex</classname>, locking mechanics, see <classname>mutex</classname>,
<classname>try_mutex</classname>, and <classname>timed_mutex</classname>. <classname>try_mutex</classname>, and <classname>timed_mutex</classname>.
</para> </para>
@@ -234,15 +230,15 @@
<tbody> <tbody>
<row> <row>
<entry>scoped_lock</entry> <entry>scoped_lock</entry>
<entry><link linkend="thread.concepts.ScopedLock">ScopedLock</link></entry> <entry><link linkend="threads.concepts.ScopedLock">ScopedLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_try_lock</entry> <entry>scoped_try_lock</entry>
<entry><link linkend="thread.concepts.ScopedTryLock">ScopedTryLock</link></entry> <entry><link linkend="threads.concepts.ScopedTryLock">ScopedTryLock</link></entry>
</row> </row>
<row> <row>
<entry>scoped_timed_lock</entry> <entry>scoped_timed_lock</entry>
<entry><link linkend="thread.concepts.ScopedTimedLock">ScopedTimedLock</link></entry> <entry><link linkend="threads.concepts.ScopedTimedLock">ScopedTimedLock</link></entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
@@ -250,7 +246,7 @@
</para> </para>
<para>The <classname>recursive_timed_mutex</classname> class uses a <para>The <classname>recursive_timed_mutex</classname> class uses a
<link linkend="thread.concepts.recursive-locking-strategy">Recursive</link> <link linkend="threads.concepts.recursive-locking-strategy">Recursive</link>
locking strategy, so attempts to recursively lock a locking strategy, so attempts to recursively lock a
<classname>recursive_timed_mutex</classname> object <classname>recursive_timed_mutex</classname> object
succeed and an internal "lock count" is maintained. succeed and an internal "lock count" is maintained.
@@ -259,10 +255,10 @@
<emphasis role="bold">undefined behavior</emphasis>.</para> <emphasis role="bold">undefined behavior</emphasis>.</para>
<para>Like all <para>Like all
<link linkend="thread.concepts.mutex-models">mutex models</link> <link linkend="threads.concepts.mutex-models">mutex models</link>
in &Boost.Thread;, <classname>recursive_timed_mutex</classname> leaves the in &Boost.Threads;, <classname>recursive_timed_mutex</classname> leaves the
<link linkend="thread.concepts.sheduling-policies">scheduling policy</link> <link linkend="threads.concepts.sheduling-policies">scheduling policy</link>
as <link linkend="thread.concepts.unspecified-scheduling-policy">Unspecified</link>. as <link linkend="threads.concepts.unspecified-scheduling-policy">Unspecified</link>.
Programmers should make no assumptions about the order in which Programmers should make no assumptions about the order in which
waiting threads acquire a lock.</para> waiting threads acquire a lock.</para>
</description> </description>

View File

@@ -1,14 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford <library-reference id="threads.reference"
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<library-reference id="thread.reference"
last-revision="$Date$" last-revision="$Date$"
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="barrier-ref.xml"/> <xi:include href="barrier-ref.xml"/>

View File

@@ -1,19 +1,15 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford <section id="threads.release_notes" last-revision="$Date$">
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<section id="thread.release_notes" last-revision="$Date$">
<title>Release Notes</title> <title>Release Notes</title>
<section id="thread.release_notes.boost_1_32_0"> <section id="threads.release_notes.boost_1_32_0">
<title>Boost 1.32.0</title> <title>Boost 1.32.0</title>
<section id="thread.release_notes.boost_1_32_0.change_log.documentation"> <section id="threads.release_notes.boost_1_32_0.change_log.documentation">
<title>Documentation converted to BoostBook</title> <title>Documentation converted to BoostBook</title>
<para>The documentation was converted to BoostBook format, <para>The documentation was converted to BoostBook format,
@@ -24,24 +20,24 @@
please report them!</para> please report them!</para>
</section> </section>
<section id="thread.release_notes.boost_1_32_0.change_log.static_link"> <section id="threads.release_notes.boost_1_32_0.change_log.static_link">
<title>Statically-link build option added</title> <title>Statically-link build option added</title>
<para>The option to link &Boost.Thread; as a static <para>The option to link &Boost.Threads; as a static
library has been added (with some limitations on Win32 platforms). library has been added (with some limitations on Win32 platforms).
This feature was originally removed from an earlier version This feature was originally removed from an earlier version
of Boost because <classname>boost::thread_specific_ptr</classname> of Boost because <classname>boost::thread_specific_ptr</classname>
required that &Boost.Thread; be dynamically linked in order required that &Boost.Threads; be dynamically linked in order
for its cleanup functionality to work on Win32 platforms. for its cleanup functionality to work on Win32 platforms.
Because this limitation never applied to non-Win32 platforms, Because this limitation never applied to non-Win32 platforms,
because significant progress has been made in removing because significant progress has been made in removing
the limitation on Win32 platforms (many thanks to the limitation on Win32 platforms (many thanks to
Aaron LaFramboise and Roland Scwarz!), and because the lack Aaron LaFramboise and Roland Scwarz!), and because the lack
of static linking is one of the most common complaints of of static linking is one of the most common complaints of
&Boost.Thread; users, this decision was reversed.</para> &Boost.Threads; users, this decision was reversed.</para>
<para>On non-Win32 platforms: <para>On non-Win32 platforms:
To choose the dynamically linked version of &Boost.Thread; To choose the dynamically linked version of &Boost.Threads;
using Boost's auto-linking feature, #define BOOST_THREAD_USE_DLL; using Boost's auto-linking feature, #define BOOST_THREAD_USE_DLL;
to choose the statically linked version, to choose the statically linked version,
#define BOOST_THREAD_USE_LIB. #define BOOST_THREAD_USE_LIB.
@@ -67,9 +63,9 @@
because it has not yet been possible to implement automatic because it has not yet been possible to implement automatic
tss cleanup in the statically linked version for compilers tss cleanup in the statically linked version for compilers
other than VC++, although it is hoped that this will be other than VC++, although it is hoped that this will be
possible in a future version of &Boost.Thread;. possible in a future version of &Boost.Threads;.
Note for advanced users: &Boost.Thread; provides several "hook" Note for advanced users: &Boost.Threads; provides several "hook"
functions to allow users to experiment with the statically functions to allow users to experiment with the statically
linked version on Win32 with compilers other than VC++. linked version on Win32 with compilers other than VC++.
These functions are on_process_enter(), on_process_exit(), These functions are on_process_enter(), on_process_exit(),
@@ -78,13 +74,13 @@
information.</para> information.</para>
</section> </section>
<section id="thread.release_notes.boost_1_32_0.change_log.barrier"> <section id="threads.release_notes.boost_1_32_0.change_log.barrier">
<title>Barrier functionality added</title> <title>Barrier functionality added</title>
<para>A new class, <classname>boost::barrier</classname>, was added.</para> <para>A new class, <classname>boost::barrier</classname>, was added.</para>
</section> </section>
<section id="thread.release_notes.boost_1_32_0.change_log.read_write_mutex"> <section id="threads.release_notes.boost_1_32_0.change_log.read_write_mutex">
<title>Read/write mutex functionality added</title> <title>Read/write mutex functionality added</title>
<para>New classes, <para>New classes,
@@ -95,13 +91,13 @@
<note>Since the read/write mutex and related classes are new, <note>Since the read/write mutex and related classes are new,
both interface and implementation are liable to change both interface and implementation are liable to change
in future releases of &Boost.Thread;. in future releases of &Boost.Threads;.
The lock concepts and lock promotion in particular are The lock concepts and lock promotion in particular are
still under discussion and very likely to change.</note> still under discussion and very likely to change.</note>
</para> </para>
</section> </section>
<section id="thread.release_notes.boost_1_32_0.change_log.thread_specific_ptr"> <section id="threads.release_notes.boost_1_32_0.change_log.thread_specific_ptr">
<title>Thread-specific pointer functionality changed</title> <title>Thread-specific pointer functionality changed</title>
<para>The <classname>boost::thread_specific_ptr</classname> <para>The <classname>boost::thread_specific_ptr</classname>
@@ -128,7 +124,7 @@
is called.</para> is called.</para>
</section> </section>
<section id="thread.release_notes.boost_1_32_0.change_log.mutex"> <section id="threads.release_notes.boost_1_32_0.change_log.mutex">
<title>Mutex implementation changed for Win32</title> <title>Mutex implementation changed for Win32</title>
<para>On Win32, <classname>boost::mutex</classname>, <para>On Win32, <classname>boost::mutex</classname>,
@@ -139,10 +135,10 @@
<classname>boost::recursive_timed_mutex</classname> use a Win32 mutex.</para> <classname>boost::recursive_timed_mutex</classname> use a Win32 mutex.</para>
</section> </section>
<section id="thread.release_notes.boost_1_32_0.change_log.wince"> <section id="threads.release_notes.boost_1_32_0.change_log.wince">
<title>Windows CE support improved</title> <title>Windows CE support improved</title>
<para>Minor changes were made to make Boost.Thread work on Windows CE.</para> <para>Minor changes were made to make Boost.Threads work on Windows CE.</para>
</section> </section>
</section> </section>
</section> </section>

View File

@@ -1,13 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<header name="boost/thread/thread.hpp" <header name="boost/thread/thread.hpp"
last-revision="$Date$"> last-revision="$Date$">
<namespace name="boost"> <namespace name="boost">
@@ -15,15 +11,15 @@
<purpose> <purpose>
<para>The <classname>thread</classname> class represents threads of <para>The <classname>thread</classname> class represents threads of
execution, and provides the functionality to create and manage execution, and provides the functionality to create and manage
threads within the &Boost.Thread; library. See threads within the &Boost.Threads; library. See
<xref linkend="thread.glossary"/> for a precise description of <xref linkend="threads.glossary"/> for a precise description of
<link linkend="thread.glossary.thread">thread of execution</link>, <link linkend="threads.glossary.thread">thread of execution</link>,
and for definitions of threading-related terms and of thread states such as and for definitions of threading-related terms and of thread states such as
<link linkend="thread.glossary.thread-state">blocked</link>.</para> <link linkend="threads.glossary.thread-state">blocked</link>.</para>
</purpose> </purpose>
<description> <description>
<para>A <link linkend="thread.glossary.thread">thread of execution</link> <para>A <link linkend="threads.glossary.thread">thread of execution</link>
has an initial function. For the program's initial thread, the initial has an initial function. For the program's initial thread, the initial
function is <code>main()</code>. For other threads, the initial function is <code>main()</code>. For other threads, the initial
function is <code>operator()</code> of the function object passed to function is <code>operator()</code> of the function object passed to
@@ -40,7 +36,7 @@
&quot;joinable&quot; or &quot;non-joinable&quot;.</para> &quot;joinable&quot; or &quot;non-joinable&quot;.</para>
<para>Except as described below, the policy used by an implementation <para>Except as described below, the policy used by an implementation
of &Boost.Thread; to schedule transitions between thread states is of &Boost.Threads; to schedule transitions between thread states is
unspecified.</para> unspecified.</para>
<para><note>Just as the lifetime of a file may be different from the <para><note>Just as the lifetime of a file may be different from the
@@ -153,7 +149,7 @@
<notes>If <code>*this == thread()</code> the result is <notes>If <code>*this == thread()</code> the result is
implementation-defined. If the implementation doesn't implementation-defined. If the implementation doesn't
detect this the result will be detect this the result will be
<link linkend="thread.glossary.deadlock">deadlock</link>. <link linkend="threads.glossary.deadlock">deadlock</link>.
</notes> </notes>
</method> </method>
</method-group> </method-group>
@@ -174,7 +170,7 @@
<type>void</type> <type>void</type>
<effects>The current thread of execution is placed in the <effects>The current thread of execution is placed in the
<link linkend="thread.glossary.thread-state">ready</link> <link linkend="threads.glossary.thread-state">ready</link>
state.</effects> state.</effects>
<notes> <notes>
@@ -233,7 +229,7 @@
<type>void</type> <type>void</type>
<parameter name="thrd"> <parameter name="thrd">
<paramtype><classname>thread</classname>*</paramtype> <paramtype><classname>thread</classname>* thrd</paramtype>
</parameter> </parameter>
<effects>Adds <code>thrd</code> to the <effects>Adds <code>thrd</code> to the
@@ -247,7 +243,7 @@
<type>void</type> <type>void</type>
<parameter name="thrd"> <parameter name="thrd">
<paramtype><classname>thread</classname>*</paramtype> <paramtype><classname>thread</classname>* thrd</paramtype>
</parameter> </parameter>
<effects>Removes <code>thread</code> from <code>*this</code>'s <effects>Removes <code>thread</code> from <code>*this</code>'s
@@ -264,20 +260,7 @@
<effects>Calls <code>join()</code> on each of the managed <effects>Calls <code>join()</code> on each of the managed
<classname>thread</classname> objects.</effects> <classname>thread</classname> objects.</effects>
</method> </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> </class>
</namespace> </namespace>
</header> </header>

View File

@@ -1,14 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford <library name="Threads" dirname="thread" id="threads"
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<library name="Thread" dirname="thread" id="thread"
last-revision="$Date$" last-revision="$Date$"
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<libraryinfo> <libraryinfo>
@@ -24,14 +20,19 @@ xmlns:xi="http://www.w3.org/2001/XInclude">
<holder>William E. Kempf</holder> <holder>William E. Kempf</holder>
</copyright> </copyright>
<legalnotice> <legalnotice>
<para>Subject to the Boost Software License, Version 1.0. <para>Permission to use, copy, modify, distribute and sell this
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)</para> 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.</para>
</legalnotice> </legalnotice>
<librarypurpose>Portable C++ multi-threading</librarypurpose> <librarypurpose>Portable C++ multi-threading</librarypurpose>
<librarycategory name="category:concurrent" /> <librarycategory name="category:concurrent" />
<title>Boost.Thread</title> <title>Boost.Threads</title>
</libraryinfo> </libraryinfo>
<title>Boost.Thread</title> <title>&Boost.Threads;</title>
<xi:include href="overview.xml"/> <xi:include href="overview.xml"/>
<xi:include href="design.xml"/> <xi:include href="design.xml"/>
<xi:include href="concepts.xml"/> <xi:include href="concepts.xml"/>

View File

@@ -1,13 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<header name="boost/thread/tss.hpp" <header name="boost/thread/tss.hpp"
last-revision="$Date$"> last-revision="$Date$">
<namespace name="boost"> <namespace name="boost">
@@ -21,7 +17,7 @@
<para>Thread specific storage is data associated with <para>Thread specific storage is data associated with
individual threads and is often used to make operations individual threads and is often used to make operations
that rely on global data that rely on global data
<link linkend="thread.glossary.thread-safe">thread-safe</link>. <link linkend="threads.glossary.thread-safe">thread-safe</link>.
</para> </para>
<para>Template <classname>thread_specific_ptr</classname> <para>Template <classname>thread_specific_ptr</classname>

View File

@@ -1,13 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
<!ENTITY % thread.entities SYSTEM "entities.xml"> <!ENTITY % threads.entities SYSTEM "entities.xml">
%thread.entities; %threads.entities;
]> ]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<header name="boost/thread/xtime.hpp" <header name="boost/thread/xtime.hpp"
last-revision="$Date$"> last-revision="$Date$">
<namespace name="boost"> <namespace name="boost">
@@ -20,7 +16,7 @@
</purpose> </purpose>
<description> <description>
<para>The only clock type supported by &Boost.Thread; is <para>The only clock type supported by &Boost.Threads; is
<code>TIME_UTC</code>. The epoch for <code>TIME_UTC</code> <code>TIME_UTC</code>. The epoch for <code>TIME_UTC</code>
is 1970-01-01 00:00:00.</para> is 1970-01-01 00:00:00.</para>
</description> </description>
@@ -37,9 +33,9 @@
<description> <description>
<simpara>The <classname>xtime</classname> type is used to represent a point on <simpara>The <classname>xtime</classname> type is used to represent a point on
some time scale or a duration in time. This type may be proposed for the C standard by some time scale or a duration in time. This type may be proposed for the C standard by
Markus Kuhn. &Boost.Thread; provides only a very minimal implementation of this Markus Kuhn. &Boost.Threads; provides only a very minimal implementation of this
proposal; it is expected that a full implementation (or some other time proposal; it is expected that a full implementation (or some other time
library) will be provided in Boost as a separate library, at which time &Boost.Thread; library) will be provided in Boost as a separate library, at which time &Boost.Threads;
will deprecate its own implementation.</simpara> will deprecate its own implementation.</simpara>
<simpara><emphasis role="bold">Note</emphasis> that the resolution is <simpara><emphasis role="bold">Note</emphasis> that the resolution is

54
example/Jamfile Normal file
View File

@@ -0,0 +1,54 @@
# 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.
#
# Boost.Threads example Jamfile
#
# Additional configuration variables used:
# 1. PTW32 may be used on Win32 platforms to specify that the pthreads-win32
# library should be used instead of "native" threads. This feature is
# mostly used for testing and it's generally recommended you use the
# native threading libraries instead. PTW32 should be set to be a list
# of two strings, the first specifying the installation path of the
# pthreads-win32 library and the second specifying which library
# variant to link against (see the pthreads-win32 documentation).
# Example: jam -sPTW32="c:\pthreads-win32 pthreadVCE.lib"
# Declare the location of this subproject relative to the root.
subproject libs/thread/example ;
# Include threads.jam for Boost.Threads global build information.
# This greatly simplifies the Jam code needed to configure the build
# for the various Win32 build types.
import ../build/threads ;
{
template example
## sources ##
: <template>thread_base
<dll>../build/boost_thread
## requirements ##
:
## default build ##
:
;
exe monitor : <template>example monitor.cpp ;
exe starvephil : <template>example starvephil.cpp ;
exe tennis : <template>example tennis.cpp ;
exe condition : <template>example condition.cpp ;
exe mutex : <template>example mutex.cpp ;
exe once : <template>example once.cpp ;
exe recursive_mutex : <template>example recursive_mutex.cpp ;
exe thread : <template>example thread.cpp ;
exe thread_group : <template>example thread_group.cpp ;
exe tss : <template>example tss.cpp ;
exe xtime : <template>example xtime.cpp ;
}

View File

@@ -1,23 +1,5 @@
# 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)
project boost/thread/example exe starvephil
: requirements <library>../build//boost_thread <threading>multi : starvephil.cpp ../build/boost_thread ../../test/build/unit_test_framework
; ;
exe monitor : monitor.cpp ;
exe starvephil : starvephil.cpp ;
exe tennis : tennis.cpp ;
exe condition : condition.cpp ;
exe mutex : mutex.cpp ;
exe once : once.cpp ;
exe recursive_mutex : recursive_mutex.cpp ;
exe thread : thread.cpp ;
exe thread_group : thread_group.cpp ;
exe tss : tss.cpp ;
exe xtime : xtime.cpp ;

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <iostream> #include <iostream>
#include <vector> #include <vector>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <vector> #include <vector>
#include <iostream> #include <iostream>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>
#include <boost/thread/once.hpp> #include <boost/thread/once.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/recursive_mutex.hpp> #include <boost/thread/recursive_mutex.hpp>
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp> #include <boost/thread/condition.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp> #include <boost/thread/condition.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp> #include <boost/thread/xtime.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>
#include <iostream> #include <iostream>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>
#include <boost/thread/tss.hpp> #include <boost/thread/tss.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp> #include <boost/thread/xtime.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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.
#if !defined(BOOST_THREAD_WEK01082003_HPP) #if !defined(BOOST_THREAD_WEK01082003_HPP)
#define BOOST_THREAD_WEK01082003_HPP #define BOOST_THREAD_WEK01082003_HPP

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2002-2003 // Copyright (C) 2002-2003
// David Moore, William E. Kempf // David Moore, William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_BARRIER_JDM030602_HPP #ifndef BOOST_BARRIER_JDM030602_HPP
#define BOOST_BARRIER_JDM030602_HPP #define BOOST_BARRIER_JDM030602_HPP
@@ -24,16 +29,7 @@ public:
private: private:
mutex m_mutex; mutex m_mutex;
// disable warnings about non dll import
// see: http://www.boost.org/more/separate_compilation.html#dlls
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4251 4231 4660 4275)
#endif
condition m_cond; condition m_cond;
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
unsigned int m_threshold; unsigned int m_threshold;
unsigned int m_count; unsigned int m_count;
unsigned int m_generation; unsigned int m_generation;

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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_CONDITION_WEK070601_HPP #ifndef BOOST_CONDITION_WEK070601_HPP
#define BOOST_CONDITION_WEK070601_HPP #define BOOST_CONDITION_WEK070601_HPP
@@ -22,12 +27,7 @@
namespace boost { namespace boost {
struct xtime; struct xtime;
// disable warnings about non dll import
// see: http://www.boost.org/more/separate_compilation.html#dlls
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4251 4231 4660 4275)
#endif
namespace detail { namespace detail {
class BOOST_THREAD_DECL condition_impl : private noncopyable class BOOST_THREAD_DECL condition_impl : private noncopyable
@@ -185,9 +185,7 @@ private:
return ret; return ret;
} }
}; };
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
} // namespace boost } // namespace boost
// Change Log: // Change Log:

View File

@@ -1,75 +1,70 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_THREAD_CONFIG_WEK01032003_HPP #ifndef BOOST_THREAD_CONFIG_WEK01032003_HPP
#define BOOST_THREAD_CONFIG_WEK01032003_HPP #define BOOST_THREAD_CONFIG_WEK01032003_HPP
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#if BOOST_WORKAROUND(__BORLANDC__, < 0x600)
# pragma warn -8008 // Condition always true/false
# pragma warn -8080 // Identifier declared but never used
# pragma warn -8057 // Parameter never used
# pragma warn -8066 // Unreachable code
#endif
// insist on threading support being available: // insist on threading support being available:
#include <boost/config/requires_threads.hpp> #include <boost/config/requires_threads.hpp>
// compatibility with the rest of Boost's auto-linking code: #if defined(BOOST_HAS_WINTHREADS)
#if defined(BOOST_THREAD_DYN_DLL) || defined(BOOST_ALL_DYN_LINK) # if defined(BOOST_THREAD_BUILD_DLL) //Build dll
# undef BOOST_THREAD_USE_LIB # define BOOST_THREAD_DECL __declspec(dllexport)
# define BOOST_THREAD_USE_DLL # elif defined(BOOST_THREAD_BUILD_LIB) //Build lib
#endif # define BOOST_THREAD_DECL
# elif defined(BOOST_THREAD_USE_DLL) //Use dll
#if defined(BOOST_THREAD_BUILD_DLL) //Build dll # define BOOST_THREAD_DECL __declspec(dllimport)
#elif defined(BOOST_THREAD_BUILD_LIB) //Build lib # define BOOST_DYN_LINK
#elif defined(BOOST_THREAD_USE_DLL) //Use dll # elif defined(BOOST_THREAD_USE_LIB) //Use lib
#elif defined(BOOST_THREAD_USE_LIB) //Use lib # define BOOST_THREAD_DECL
#else //Use default # else //Use default
# if defined(BOOST_HAS_WINTHREADS)
# if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN) # if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)
//For compilers supporting auto-tss cleanup //For VC++, choose according to threading library setting
//with Boost.Threads lib, use Boost.Threads lib # if defined(_DLL)
# define BOOST_THREAD_USE_LIB //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 # else
//For compilers not yet supporting auto-tss cleanup //For compilers not yet supporting auto-tss cleanup
//with Boost.Threads lib, use Boost.Threads dll //with Boost.Threads lib, use Boost.Threads dll
# define BOOST_THREAD_USE_DLL # define BOOST_THREAD_USE_DLL
# define BOOST_THREAD_DECL __declspec(dllimport)
# define BOOST_DYN_LINK
# endif # endif
# else
# define BOOST_THREAD_USE_LIB
# endif
#endif
#if defined(BOOST_HAS_DECLSPEC)
# if defined(BOOST_THREAD_BUILD_DLL) //Build dll
# define BOOST_THREAD_DECL __declspec(dllexport)
# elif defined(BOOST_THREAD_USE_DLL) //Use dll
# define BOOST_THREAD_DECL __declspec(dllimport)
# else
# define BOOST_THREAD_DECL
# endif # endif
#else #else
# define BOOST_THREAD_DECL # define BOOST_THREAD_DECL
#endif // BOOST_HAS_DECLSPEC # if defined(BOOST_THREAD_USE_LIB) //Use dll
# define BOOST_THREAD_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) #if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_THREAD_NO_LIB) && !defined(BOOST_THREAD_BUILD_DLL) && !defined(BOOST_THREAD_BUILD_LIB)
// //
// Tell the autolink to link dynamically, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#if defined(BOOST_THREAD_USE_DLL)
# define BOOST_DYN_LINK
#endif
//
// Set the name of our library, this will get undef'ed by auto_link.hpp // Set the name of our library, this will get undef'ed by auto_link.hpp
// once it's done with it: // once it's done with it:
// //
@@ -87,9 +82,3 @@
#endif // auto-linking disabled #endif // auto-linking disabled
#endif // BOOST_THREAD_CONFIG_WEK1032003_HPP #endif // BOOST_THREAD_CONFIG_WEK1032003_HPP
// Change Log:
// 22 Jan 05 Roland Schwarz (speedsnail)
// Usage of BOOST_HAS_DECLSPEC macro.
// Default again is static lib usage.
// BOOST_DYN_LINK only defined when autolink included.

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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_XLOCK_WEK070601_HPP #ifndef BOOST_XLOCK_WEK070601_HPP
#define BOOST_XLOCK_WEK070601_HPP #define BOOST_XLOCK_WEK070601_HPP

View File

@@ -1,12 +1,17 @@
// Copyright (C) 2002-2003 // Copyright (C) 2002-2003
// David Moore, Michael Glassford // David Moore
// //
// Original scoped_lock implementation // Original scoped_lock implementation
// Copyright (C) 2001 // Copyright (C) 2001
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. David Moore makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_READ_WRITE_LOCK_JDM031002_HPP #ifndef BOOST_READ_WRITE_LOCK_JDM031002_HPP
#define BOOST_READ_WRITE_LOCK_JDM031002_HPP #define BOOST_READ_WRITE_LOCK_JDM031002_HPP
@@ -169,7 +174,7 @@ public:
m_state = read_write_lock_state::write_locked; m_state = read_write_lock_state::write_locked;
} }
//If allow_unlock = true, set_lock always succeeds and //If allow_unlock = true, set_lock always succeedes and
//the function result indicates whether an unlock was required. //the function result indicates whether an unlock was required.
//If allow_unlock = false, set_lock may fail; //If allow_unlock = false, set_lock may fail;
//the function result indicates whether it succeeded. //the function result indicates whether it succeeded.
@@ -443,7 +448,7 @@ public:
return read_write_lock_ops<TryReadWriteMutex>::try_promote(m_mutex) ? (m_state = read_write_lock_state::write_locked, true) : false; return read_write_lock_ops<TryReadWriteMutex>::try_promote(m_mutex) ? (m_state = read_write_lock_state::write_locked, true) : false;
} }
//If allow_unlock = true, set_lock always succeeds and //If allow_unlock = true, set_lock always succeedes and
//the function result indicates whether an unlock was required. //the function result indicates whether an unlock was required.
//If allow_unlock = false, set_lock may fail; //If allow_unlock = false, set_lock may fail;
//the function result indicates whether it succeeded. //the function result indicates whether it succeeded.
@@ -801,7 +806,7 @@ public:
return read_write_lock_ops<TimedReadWriteMutex>::timed_promote(m_mutex, xt) ? (m_state = read_write_lock_state::write_locked, true) : false; return read_write_lock_ops<TimedReadWriteMutex>::timed_promote(m_mutex, xt) ? (m_state = read_write_lock_state::write_locked, true) : false;
} }
//If allow_unlock = true, set_lock always succeeds and //If allow_unlock = true, set_lock always succeedes and
//the function result indicates whether an unlock was required. //the function result indicates whether an unlock was required.
//If allow_unlock = false, set_lock may fail; //If allow_unlock = false, set_lock may fail;
//the function result indicates whether it succeeded. //the function result indicates whether it succeeded.

View File

@@ -20,7 +20,7 @@
//Currently only implemented for Win32, but should //Currently only implemented for Win32, but should
//later be implemented for all platforms. //later be implemented for all platforms.
//Used by Win32 implementation of Boost.Threads //Used by Win32 implementation of Boost.Threads
//tss to perform cleanup. //tss to peform cleanup.
//Like the C runtime library atexit() function, //Like the C runtime library atexit() function,
//which it mimics, at_thread_exit() returns //which it mimics, at_thread_exit() returns
//zero if successful and a nonzero //zero if successful and a nonzero

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_THREAD_EXCEPTIONS_PDM070801_H #ifndef BOOST_THREAD_EXCEPTIONS_PDM070801_H
#define BOOST_THREAD_EXCEPTIONS_PDM070801_H #define BOOST_THREAD_EXCEPTIONS_PDM070801_H
@@ -31,6 +36,8 @@ public:
int native_error() const; int native_error() const;
const char* message() const;
private: private:
int m_sys_err; int m_sys_err;
}; };

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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_WEK070601_HPP #ifndef BOOST_MUTEX_WEK070601_HPP
#define BOOST_MUTEX_WEK070601_HPP #define BOOST_MUTEX_WEK070601_HPP
@@ -23,12 +28,7 @@
namespace boost { namespace boost {
struct xtime; struct xtime;
// disable warnings about non dll import
// see: http://www.boost.org/more/separate_compilation.html#dlls
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4251 4231 4660 4275)
#endif
class BOOST_THREAD_DECL mutex class BOOST_THREAD_DECL mutex
: private noncopyable : private noncopyable
{ {
@@ -155,9 +155,7 @@ private:
threads::mac::detail::scoped_critical_region m_mutex_mutex; threads::mac::detail::scoped_critical_region m_mutex_mutex;
#endif #endif
}; };
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
} // namespace boost } // namespace boost
// Change Log: // Change Log:

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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_ONCE_WEK080101_HPP #ifndef BOOST_ONCE_WEK080101_HPP
#define BOOST_ONCE_WEK080101_HPP #define BOOST_ONCE_WEK080101_HPP

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2002-2003 // Copyright (C) 2002-2003
// David Moore, William E. Kempf, Michael Glassford // David Moore, William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. David Moore makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
// A Boost::threads implementation of a synchronization // A Boost::threads implementation of a synchronization
// primitive which can allow multiple readers or a single // primitive which can allow multiple readers or a single
@@ -14,7 +19,6 @@
#include <boost/thread/detail/config.hpp> #include <boost/thread/detail/config.hpp>
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#include <boost/thread/detail/lock.hpp> #include <boost/thread/detail/lock.hpp>
@@ -22,19 +26,14 @@
#include <boost/thread/condition.hpp> #include <boost/thread/condition.hpp>
namespace boost { namespace boost {
// disable warnings about non dll import
// see: http://www.boost.org/more/separate_compilation.html#dlls
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4251 4231 4660 4275)
#endif
namespace read_write_scheduling_policy { namespace read_write_scheduling_policy {
enum read_write_scheduling_policy_enum enum read_write_scheduling_policy_enum
{ {
writer_priority, //Prefer writers; can starve readers writer_priority, //Prefer writers; can starve readers
reader_priority, //Prefer readers; can starve writers reader_priority, //Prefer readers; can starve writers
alternating_many_reads, //Alternate readers and writers; before a writer, release all queued readers alternating_many_reads, //Alternate readers and writers; before a writer, release all queued readers
alternating_single_read //Alternate readers and writers; before a writer, release only one queued reader alternating_single_read //Alternate readers and writers; before a writer, release only on queued reader
}; };
} // namespace read_write_scheduling_policy } // namespace read_write_scheduling_policy
@@ -52,28 +51,27 @@ struct read_write_mutex_impl
typedef detail::thread::scoped_try_lock<Mutex> scoped_try_lock; typedef detail::thread::scoped_try_lock<Mutex> scoped_try_lock;
typedef detail::thread::scoped_timed_lock<Mutex> scoped_timed_lock; typedef detail::thread::scoped_timed_lock<Mutex> scoped_timed_lock;
read_write_mutex_impl(read_write_scheduling_policy::read_write_scheduling_policy_enum sp); read_write_mutex_impl(read_write_scheduling_policy::read_write_scheduling_policy_enum sp)
#if !BOOST_WORKAROUND(__BORLANDC__,<= 0x564) : m_num_waiting_writers(0),
~read_write_mutex_impl(); m_num_waiting_readers(0),
#endif m_num_readers_to_wake(0),
m_state_waiting_promotion(false),
m_state(0),
m_sp(sp),
m_readers_next(true) { }
Mutex m_prot; Mutex m_prot;
const read_write_scheduling_policy::read_write_scheduling_policy_enum m_sp;
int m_state; //-1 = write lock; 0 = unlocked; >0 = read locked
boost::condition m_waiting_writers; boost::condition m_waiting_writers;
boost::condition m_waiting_readers; boost::condition m_waiting_readers;
boost::condition m_waiting_promotion;
int m_num_waiting_writers; int m_num_waiting_writers;
int m_num_waiting_readers; int m_num_waiting_readers;
int m_num_readers_to_wake;
boost::condition m_waiting_promotion;
bool m_state_waiting_promotion; bool m_state_waiting_promotion;
int m_state; // -1 = excl locked
int m_num_waking_writers; // 0 = unlocked
int m_num_waking_readers; // 1-> INT_MAX - shared locked
int m_num_max_waking_writers; //Debug only const read_write_scheduling_policy::read_write_scheduling_policy_enum m_sp;
int m_num_max_waking_readers; //Debug only
bool m_readers_next; bool m_readers_next;
void do_read_lock(); void do_read_lock();
@@ -98,20 +96,12 @@ struct read_write_mutex_impl
private: 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(); bool do_demote_to_read_lock_impl();
enum scheduling_reason
{
scheduling_reason_unlock,
scheduling_reason_timeout,
scheduling_reason_demote
};
void do_scheduling_impl(const scheduling_reason reason);
bool do_wake_one_reader(void);
bool do_wake_all_readers(void);
bool do_wake_writer(void);
bool waker_exists(void);
}; };
} // namespace detail } // namespace detail
@@ -122,8 +112,8 @@ class BOOST_THREAD_DECL read_write_mutex : private noncopyable
{ {
public: public:
read_write_mutex(read_write_scheduling_policy::read_write_scheduling_policy_enum sp); read_write_mutex(read_write_scheduling_policy::read_write_scheduling_policy_enum sp) : m_impl(sp) { }
~read_write_mutex(); ~read_write_mutex() { }
read_write_scheduling_policy::read_write_scheduling_policy_enum policy() const { return m_impl.m_sp; } read_write_scheduling_policy::read_write_scheduling_policy_enum policy() const { return m_impl.m_sp; }
@@ -161,8 +151,8 @@ class BOOST_THREAD_DECL try_read_write_mutex : private noncopyable
{ {
public: public:
try_read_write_mutex(read_write_scheduling_policy::read_write_scheduling_policy_enum sp); try_read_write_mutex(read_write_scheduling_policy::read_write_scheduling_policy_enum sp) : m_impl(sp) { }
~try_read_write_mutex(); ~try_read_write_mutex() { }
read_write_scheduling_policy::read_write_scheduling_policy_enum policy() const { return m_impl.m_sp; } read_write_scheduling_policy::read_write_scheduling_policy_enum policy() const { return m_impl.m_sp; }
@@ -211,8 +201,8 @@ class BOOST_THREAD_DECL timed_read_write_mutex : private noncopyable
{ {
public: public:
timed_read_write_mutex(read_write_scheduling_policy::read_write_scheduling_policy_enum sp); timed_read_write_mutex(read_write_scheduling_policy::read_write_scheduling_policy_enum sp) : m_impl(sp) { }
~timed_read_write_mutex(); ~timed_read_write_mutex() { }
read_write_scheduling_policy::read_write_scheduling_policy_enum policy() const { return m_impl.m_sp; } read_write_scheduling_policy::read_write_scheduling_policy_enum policy() const { return m_impl.m_sp; }
@@ -265,9 +255,7 @@ private:
detail::thread::read_write_mutex_impl<timed_mutex> m_impl; detail::thread::read_write_mutex_impl<timed_mutex> m_impl;
}; };
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
} // namespace boost } // namespace boost
#endif #endif

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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_RECURSIVE_MUTEX_WEK070601_HPP #ifndef BOOST_RECURSIVE_MUTEX_WEK070601_HPP
#define BOOST_RECURSIVE_MUTEX_WEK070601_HPP #define BOOST_RECURSIVE_MUTEX_WEK070601_HPP
@@ -23,12 +28,7 @@
namespace boost { namespace boost {
struct xtime; struct xtime;
// disable warnings about non dll import
// see: http://www.boost.org/more/separate_compilation.html#dlls
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4251 4231 4660 4275)
#endif
class BOOST_THREAD_DECL recursive_mutex class BOOST_THREAD_DECL recursive_mutex
: private noncopyable : private noncopyable
{ {
@@ -169,9 +169,7 @@ private:
std::size_t m_count; std::size_t m_count;
#endif #endif
}; };
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
} // namespace boost } // namespace boost
#endif // BOOST_RECURSIVE_MUTEX_WEK070601_HPP #endif // BOOST_RECURSIVE_MUTEX_WEK070601_HPP

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_THREAD_WEK070601_HPP #ifndef BOOST_THREAD_WEK070601_HPP
#define BOOST_THREAD_WEK070601_HPP #define BOOST_THREAD_WEK070601_HPP
@@ -25,12 +30,7 @@
namespace boost { namespace boost {
struct xtime; struct xtime;
// disable warnings about non dll import
// see: http://www.boost.org/more/separate_compilation.html#dlls
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4251 4231 4660 4275)
#endif
class BOOST_THREAD_DECL thread : private noncopyable class BOOST_THREAD_DECL thread : private noncopyable
{ {
public: public:
@@ -70,15 +70,12 @@ public:
void add_thread(thread* thrd); void add_thread(thread* thrd);
void remove_thread(thread* thrd); void remove_thread(thread* thrd);
void join_all(); void join_all();
int size() const;
private: private:
std::list<thread*> m_threads; std::list<thread*> m_threads;
mutex m_mutex; mutex m_mutex;
}; };
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
} // namespace boost } // namespace boost
// Change Log: // Change Log:

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 William E. Kempf // Copyright (C) 2001-2003
// Copyright (C) 2006 Roland Schwarz // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_TSS_WEK070601_HPP #ifndef BOOST_TSS_WEK070601_HPP
#define BOOST_TSS_WEK070601_HPP #define BOOST_TSS_WEK070601_HPP
@@ -21,13 +26,6 @@
namespace boost { namespace boost {
// disable warnings about non dll import
// see: http://www.boost.org/more/separate_compilation.html#dlls
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4251 4231 4660 4275)
#endif
namespace detail { namespace detail {
class BOOST_THREAD_DECL tss : private noncopyable class BOOST_THREAD_DECL tss : private noncopyable
@@ -45,7 +43,7 @@ public:
throw boost::thread_resource_error(); throw boost::thread_resource_error();
} }
} }
~tss();
void* get() const; void* get() const;
void set(void* value); void set(void* value);
void cleanup(void* p); void cleanup(void* p);
@@ -105,10 +103,6 @@ private:
detail::tss m_tss; detail::tss m_tss;
}; };
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
} // namespace boost } // namespace boost
#endif //BOOST_TSS_WEK070601_HPP #endif //BOOST_TSS_WEK070601_HPP

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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_XTIME_WEK070601_HPP #ifndef BOOST_XTIME_WEK070601_HPP
#define BOOST_XTIME_WEK070601_HPP #define BOOST_XTIME_WEK070601_HPP

View File

@@ -1,13 +1,8 @@
<!-- Copyright (c) 2002-2003 William E. Kempf.
Subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
-->
<html> <html>
<head> <head>
<meta http-equiv="refresh" content="0; URL=doc/index.html"> <meta http-equiv="refresh" content="0; URL=../../doc/html/threads.html">
</head> </head>
<body> <body>
Automatic redirection failed, please go to <a href="doc/index.html">doc/index.html</a> Automatic redirection failed, please go to <a href="../../doc/html/threads.html">../../doc/html/threads.html</a>
</body> </body>
</html> </html>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2002-2003 // Copyright (C) 2002-2003
// David Moore, William E. Kempf // David Moore, William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/config.hpp>
#include <boost/thread/barrier.hpp> #include <boost/thread/barrier.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/config.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/config.hpp>
@@ -10,6 +15,57 @@
#include <cstring> #include <cstring>
#include <string> #include <string>
# ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::strerror; }
# endif
// BOOST_POSIX or BOOST_WINDOWS specify which API to use.
# if !defined( BOOST_WINDOWS ) && !defined( BOOST_POSIX )
# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)
# define BOOST_WINDOWS
# else
# define BOOST_POSIX
# endif
# endif
# if defined( BOOST_WINDOWS )
# include "windows.h"
# else
# include <errno.h> // for POSIX error codes
# endif
namespace
{
std::string system_message(int sys_err_code)
{
std::string str;
# ifdef BOOST_WINDOWS
LPVOID lpMsgBuf;
::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
sys_err_code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPSTR)&lpMsgBuf,
0,
NULL);
str += static_cast<LPCSTR>(lpMsgBuf);
::LocalFree(lpMsgBuf); // free the buffer
while (str.size() && (str[str.size()-1] == '\n' ||
str[str.size()-1] == '\r'))
{
str.erase(str.size()-1);
}
# else
str += std::strerror(errno);
# endif
return str;
}
} // unnamed namespace
namespace boost { namespace boost {
thread_exception::thread_exception() thread_exception::thread_exception()
@@ -31,6 +87,13 @@ int thread_exception::native_error() const
return m_sys_err; return m_sys_err;
} }
const char* thread_exception::message() const
{
if (m_sys_err != 0)
return system_message(m_sys_err).c_str();
return what();
}
lock_error::lock_error() lock_error::lock_error()
{ {
} }

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/config.hpp>

View File

@@ -1,9 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// boostinspect:nounnamed // 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 { namespace {
@@ -24,7 +28,7 @@ void init_TryEnterCriticalSection()
version_info.dwMajorVersion >= 4) version_info.dwMajorVersion >= 4)
{ {
if (HMODULE kernel_module = GetModuleHandle(TEXT("KERNEL32.DLL"))) if (HMODULE kernel_module = GetModuleHandle(TEXT("KERNEL32.DLL")))
g_TryEnterCriticalSection = reinterpret_cast<TryEnterCriticalSection_type>(GetProcAddress(kernel_module, TEXT("TryEnterCriticalSection"))); g_TryEnterCriticalSection = reinterpret_cast<TryEnterCriticalSection_type>(GetProcAddress(kernel_module, "TryEnterCriticalSection"));
} }
} }
@@ -62,10 +66,8 @@ inline void* new_critical_section()
inline void* new_mutex(const char* name) inline void* new_mutex(const char* name)
{ {
#if defined(BOOST_NO_ANSI_APIS) #if defined(BOOST_NO_ANSI_APIS)
int num_wide_chars = (strlen(name) + 1); USES_CONVERSION;
LPWSTR wide_name = (LPWSTR)_alloca( num_wide_chars * 2 ); HANDLE mutex = CreateMutexW(0, 0, A2CW(name));
::MultiByteToWideChar(CP_ACP, 0, name, -1, wide_name, num_wide_chars);
HANDLE mutex = CreateMutexW(0, 0, wide_name);
#else #else
HANDLE mutex = CreateMutexA(0, 0, name); HANDLE mutex = CreateMutexA(0, 0, name);
#endif #endif

View File

@@ -1,25 +1,22 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/thread/once.hpp> #include <boost/thread/once.hpp>
#include <boost/thread/exceptions.hpp>
#include <cstdio> #include <cstdio>
#include <cassert> #include <cassert>
#if defined(BOOST_HAS_WINTHREADS) #if defined(BOOST_HAS_WINTHREADS)
# if BOOST_WORKAROUND(__BORLANDC__,<= 0x551)
using std::size_t;
# endif
# include <windows.h> # include <windows.h>
# include "mutex.inl"
# if defined(BOOST_NO_STRINGSTREAM) # if defined(BOOST_NO_STRINGSTREAM)
# include <strstream> # include <strstream>
@@ -115,11 +112,7 @@ inline LONG ice_wrapper(LPVOID (__stdcall *ice)(LPVOID*, LPVOID, LPVOID),
// according to the above function type wrappers. // according to the above function type wrappers.
inline LONG compare_exchange(volatile LPLONG dest, LONG exch, LONG cmp) inline LONG compare_exchange(volatile LPLONG dest, LONG exch, LONG cmp)
{ {
#ifdef _WIN64
return InterlockedCompareExchange(dest, exch, cmp);
#else
return ice_wrapper(&InterlockedCompareExchange, dest, exch, cmp); return ice_wrapper(&InterlockedCompareExchange, dest, exch, cmp);
#endif
} }
} }
#endif #endif
@@ -139,7 +132,12 @@ void call_once(void (*func)(), once_flag& flag)
<< &flag << &flag
<< std::ends; << std::ends;
unfreezer unfreeze(strm); unfreezer unfreeze(strm);
HANDLE mutex=new_mutex(strm.str()); # 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
#else #else
# if defined (BOOST_NO_ANSI_APIS) # if defined (BOOST_NO_ANSI_APIS)
std::wostringstream strm; std::wostringstream strm;

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/config.hpp>
@@ -514,7 +519,7 @@ bool recursive_try_mutex::do_trylock()
# if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE) # if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
int res = 0; int res = 0;
res = pthread_mutex_trylock(&m_mutex); res = pthread_mutex_trylock(&m_mutex);
assert(res == 0 || res == EBUSY); assert(res == 0);
if (res == 0) if (res == 0)
{ {

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/config.hpp>
@@ -89,18 +94,6 @@ public:
bool m_started; bool m_started;
}; };
#if defined(BOOST_HAS_WINTHREADS)
struct on_thread_exit_guard
{
~on_thread_exit_guard()
{
on_thread_exit();
}
};
#endif
} // unnamed namespace } // unnamed namespace
extern "C" { extern "C" {
@@ -112,25 +105,22 @@ extern "C" {
static OSStatus thread_proxy(void* param) static OSStatus thread_proxy(void* param)
#endif #endif
{ {
// try try
{ {
#if defined(BOOST_HAS_WINTHREADS)
on_thread_exit_guard guard;
#endif
thread_param* p = static_cast<thread_param*>(param); thread_param* p = static_cast<thread_param*>(param);
boost::function0<void> threadfunc = p->m_threadfunc; boost::function0<void> threadfunc = p->m_threadfunc;
p->started(); p->started();
threadfunc(); 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) #if defined(BOOST_HAS_MPTASKS)
::boost::detail::thread_cleanup(); ::boost::detail::thread_cleanup();
#endif #endif
@@ -230,7 +220,6 @@ bool thread::operator!=(const thread& other) const
void thread::join() void thread::join()
{ {
assert(m_joinable); //See race condition comment below
int res = 0; int res = 0;
#if defined(BOOST_HAS_WINTHREADS) #if defined(BOOST_HAS_WINTHREADS)
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_thread), INFINITE); res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_thread), INFINITE);
@@ -378,9 +367,4 @@ void thread_group::join_all()
} }
} }
int thread_group::size() const
{
return m_threads.size();
}
} // namespace boost } // namespace boost

View File

@@ -1,9 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// boostinspect:nounnamed // 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 { namespace {
const int MILLISECONDS_PER_SECOND = 1000; const int MILLISECONDS_PER_SECOND = 1000;
@@ -23,7 +27,7 @@ inline void to_time(int milliseconds, boost::xtime& xt)
xt.nsec += ((milliseconds % MILLISECONDS_PER_SECOND) * xt.nsec += ((milliseconds % MILLISECONDS_PER_SECOND) *
NANOSECONDS_PER_MILLISECOND); NANOSECONDS_PER_MILLISECOND);
if (xt.nsec >= NANOSECONDS_PER_SECOND) if (xt.nsec > NANOSECONDS_PER_SECOND)
{ {
++xt.sec; ++xt.sec;
xt.nsec -= NANOSECONDS_PER_SECOND; xt.nsec -= NANOSECONDS_PER_SECOND;
@@ -35,7 +39,7 @@ inline void to_timespec(const boost::xtime& xt, timespec& ts)
{ {
ts.tv_sec = static_cast<int>(xt.sec); ts.tv_sec = static_cast<int>(xt.sec);
ts.tv_nsec = static_cast<int>(xt.nsec); ts.tv_nsec = static_cast<int>(xt.nsec);
if(ts.tv_nsec >= NANOSECONDS_PER_SECOND) if(ts.tv_nsec > NANOSECONDS_PER_SECOND)
{ {
ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND; ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
ts.tv_nsec %= NANOSECONDS_PER_SECOND; ts.tv_nsec %= NANOSECONDS_PER_SECOND;
@@ -71,7 +75,7 @@ inline void to_timespec_duration(const boost::xtime& xt, timespec& ts)
ts.tv_sec -= 1; ts.tv_sec -= 1;
ts.tv_nsec += NANOSECONDS_PER_SECOND; ts.tv_nsec += NANOSECONDS_PER_SECOND;
} }
if(ts.tv_nsec >= NANOSECONDS_PER_SECOND) if(ts.tv_nsec > NANOSECONDS_PER_SECOND)
{ {
ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND; ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
ts.tv_nsec %= NANOSECONDS_PER_SECOND; ts.tv_nsec %= NANOSECONDS_PER_SECOND;
@@ -102,22 +106,17 @@ inline void to_duration(boost::xtime xt, int& milliseconds)
} }
} }
inline void to_microduration(boost::xtime xt, int& microseconds) inline void to_microduration(const boost::xtime& xt, int& microseconds)
{ {
boost::xtime cur; boost::xtime cur;
int res = 0; int res = 0;
res = boost::xtime_get(&cur, boost::TIME_UTC); res = boost::xtime_get(&cur, boost::TIME_UTC);
assert(res == boost::TIME_UTC); assert(res == boost::TIME_UTC);
if (boost::xtime_cmp(xt, cur) <= 0) if (boost::xtime_get(&cur, boost::TIME_UTC) <= 0)
microseconds = 0; microseconds = 0;
else else
{ {
if (cur.nsec > xt.nsec)
{
xt.nsec += NANOSECONDS_PER_SECOND;
--xt.sec;
}
microseconds = (int)((xt.sec - cur.sec) * MICROSECONDS_PER_SECOND) + microseconds = (int)((xt.sec - cur.sec) * MICROSECONDS_PER_SECOND) +
(((xt.nsec - cur.nsec) + (NANOSECONDS_PER_MICROSECOND/2)) / (((xt.nsec - cur.nsec) + (NANOSECONDS_PER_MICROSECOND/2)) /
NANOSECONDS_PER_MICROSECOND); NANOSECONDS_PER_MICROSECOND);

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 William E. Kempf // Copyright (C) 2001-2003
// Copyright (C) 2006 Roland Schwarz // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/config.hpp>
@@ -25,98 +30,62 @@
namespace { namespace {
typedef std::vector<void*> tss_slots; typedef std::vector<void*> tss_slots;
typedef std::vector<boost::function1<void, void*>*> tss_data_cleanup_handlers_type;
struct tss_data_t
{
boost::mutex mutex;
std::vector<boost::function1<void, void*>*> cleanup_handlers;
#if defined(BOOST_HAS_WINTHREADS)
DWORD native_key;
#elif defined(BOOST_HAS_PTHREADS)
pthread_key_t native_key;
#elif defined(BOOST_HAS_MPTASKS)
TaskStorageIndex native_key;
#endif
};
tss_data_t* tss_data = 0;
boost::once_flag tss_data_once = BOOST_ONCE_INIT; boost::once_flag tss_data_once = BOOST_ONCE_INIT;
boost::mutex* tss_data_mutex = 0;
tss_data_cleanup_handlers_type* tss_data_cleanup_handlers = 0;
#if defined(BOOST_HAS_WINTHREADS)
DWORD tss_data_native_key;
#elif defined(BOOST_HAS_PTHREADS)
pthread_key_t tss_data_native_key;
#elif defined(BOOST_HAS_MPTASKS)
TaskStorageIndex tss_data_native_key;
#endif
int tss_data_use = 0;
void tss_data_inc_use(boost::mutex::scoped_lock& lk)
{
++tss_data_use;
}
void tss_data_dec_use(boost::mutex::scoped_lock& lk)
{
if (0 == --tss_data_use)
{
tss_data_cleanup_handlers_type::size_type i;
for (i = 0; i < tss_data_cleanup_handlers->size(); ++i)
{
delete (*tss_data_cleanup_handlers)[i];
}
delete tss_data_cleanup_handlers;
tss_data_cleanup_handlers = 0;
lk.unlock();
delete tss_data_mutex;
tss_data_mutex = 0;
#if defined(BOOST_HAS_WINTHREADS)
TlsFree(tss_data_native_key);
#elif defined(BOOST_HAS_PTHREADS)
pthread_key_delete(tss_data_native_key);
#elif defined(BOOST_HAS_MPTASKS)
// Don't know what to put here.
// But MPTASKS isn't currently maintained anyways...
#endif
}
}
extern "C" void cleanup_slots(void* p) extern "C" void cleanup_slots(void* p)
{ {
tss_slots* slots = static_cast<tss_slots*>(p); tss_slots* slots = static_cast<tss_slots*>(p);
boost::mutex::scoped_lock lock(*tss_data_mutex);
for (tss_slots::size_type i = 0; i < slots->size(); ++i) for (tss_slots::size_type i = 0; i < slots->size(); ++i)
{ {
(*(*tss_data_cleanup_handlers)[i])((*slots)[i]); boost::mutex::scoped_lock lock(tss_data->mutex);
(*tss_data->cleanup_handlers[i])((*slots)[i]);
(*slots)[i] = 0; (*slots)[i] = 0;
} }
tss_data_dec_use(lock);
delete slots;
} }
void init_tss_data() void init_tss_data()
{ {
std::auto_ptr<tss_data_cleanup_handlers_type> temp(new tss_data_cleanup_handlers_type); std::auto_ptr<tss_data_t> temp(new tss_data_t);
std::auto_ptr<boost::mutex> temp_mutex(new boost::mutex);
if (temp_mutex.get() == 0)
throw boost::thread_resource_error();
#if defined(BOOST_HAS_WINTHREADS) #if defined(BOOST_HAS_WINTHREADS)
//Force the cleanup implementation library to be linked in //Force the cleanup implementation library to be linked in
tss_cleanup_implemented(); tss_cleanup_implemented();
//Allocate tls slot //Allocate tls slot
tss_data_native_key = TlsAlloc(); temp->native_key = TlsAlloc();
if (tss_data_native_key == 0xFFFFFFFF) if (temp->native_key == 0xFFFFFFFF)
return; return;
#elif defined(BOOST_HAS_PTHREADS) #elif defined(BOOST_HAS_PTHREADS)
int res = pthread_key_create(&tss_data_native_key, &cleanup_slots); int res = pthread_key_create(&temp->native_key, &cleanup_slots);
if (res != 0) if (res != 0)
return; return;
#elif defined(BOOST_HAS_MPTASKS) #elif defined(BOOST_HAS_MPTASKS)
OSStatus status = MPAllocateTaskStorageIndex(&tss_data_native_key); OSStatus status = MPAllocateTaskStorageIndex(&temp->native_key);
if (status != noErr) if (status != noErr)
return; return;
#endif #endif
// The life time of cleanup handlers and mutex is beeing // Intentional memory "leak"
// managed by a reference counting technique. // This is the only way to ensure the mutex in the global data
// This avoids a memory leak by releasing the global data // structure is available when cleanup handlers are run, since the
// after last use only, since the execution order of cleanup // execution order of cleanup handlers is unspecified on any platform
// handlers is unspecified on any platform with regards to // with regards to C++ destructor ordering rules.
// C++ destructor ordering rules. tss_data = temp.release();
tss_data_cleanup_handlers = temp.release();
tss_data_mutex = temp_mutex.release();
} }
#if defined(BOOST_HAS_WINTHREADS) #if defined(BOOST_HAS_WINTHREADS)
@@ -136,13 +105,13 @@ tss_slots* get_slots(bool alloc)
#if defined(BOOST_HAS_WINTHREADS) #if defined(BOOST_HAS_WINTHREADS)
slots = static_cast<tss_slots*>( slots = static_cast<tss_slots*>(
TlsGetValue(tss_data_native_key)); TlsGetValue(tss_data->native_key));
#elif defined(BOOST_HAS_PTHREADS) #elif defined(BOOST_HAS_PTHREADS)
slots = static_cast<tss_slots*>( slots = static_cast<tss_slots*>(
pthread_getspecific(tss_data_native_key)); pthread_getspecific(tss_data->native_key));
#elif defined(BOOST_HAS_MPTASKS) #elif defined(BOOST_HAS_MPTASKS)
slots = static_cast<tss_slots*>( slots = static_cast<tss_slots*>(
MPGetTaskStorageValue(tss_data_native_key)); MPGetTaskStorageValue(tss_data->native_key));
#endif #endif
if (slots == 0 && alloc) if (slots == 0 && alloc)
@@ -152,19 +121,16 @@ tss_slots* get_slots(bool alloc)
#if defined(BOOST_HAS_WINTHREADS) #if defined(BOOST_HAS_WINTHREADS)
if (at_thread_exit(&tss_thread_exit) == -1) if (at_thread_exit(&tss_thread_exit) == -1)
return 0; return 0;
if (!TlsSetValue(tss_data_native_key, temp.get())) if (!TlsSetValue(tss_data->native_key, temp.get()))
return 0; return 0;
#elif defined(BOOST_HAS_PTHREADS) #elif defined(BOOST_HAS_PTHREADS)
if (pthread_setspecific(tss_data_native_key, temp.get()) != 0) if (pthread_setspecific(tss_data->native_key, temp.get()) != 0)
return 0; return 0;
#elif defined(BOOST_HAS_MPTASKS) #elif defined(BOOST_HAS_MPTASKS)
if (MPSetTaskStorageValue(tss_data_native_key, temp.get()) != noErr) if (MPSetTaskStorageValue(tss_data->native_key, temp.get()) != noErr)
return 0; return 0;
#endif #endif
{
boost::mutex::scoped_lock lock(*tss_data_mutex);
tss_data_inc_use(lock);
}
slots = temp.release(); slots = temp.release();
} }
@@ -179,14 +145,13 @@ namespace detail {
void tss::init(boost::function1<void, void*>* pcleanup) void tss::init(boost::function1<void, void*>* pcleanup)
{ {
boost::call_once(&init_tss_data, tss_data_once); boost::call_once(&init_tss_data, tss_data_once);
if (tss_data_cleanup_handlers == 0) if (tss_data == 0)
throw thread_resource_error(); throw thread_resource_error();
boost::mutex::scoped_lock lock(*tss_data_mutex); boost::mutex::scoped_lock lock(tss_data->mutex);
try try
{ {
tss_data_cleanup_handlers->push_back(pcleanup); tss_data->cleanup_handlers.push_back(pcleanup);
m_slot = tss_data_cleanup_handlers->size() - 1; m_slot = tss_data->cleanup_handlers.size() - 1;
tss_data_inc_use(lock);
} }
catch (...) catch (...)
{ {
@@ -194,12 +159,6 @@ void tss::init(boost::function1<void, void*>* pcleanup)
} }
} }
tss::~tss()
{
boost::mutex::scoped_lock lock(*tss_data_mutex);
tss_data_dec_use(lock);
}
void* tss::get() const void* tss::get() const
{ {
tss_slots* slots = get_slots(false); tss_slots* slots = get_slots(false);
@@ -237,8 +196,8 @@ void tss::set(void* value)
void tss::cleanup(void* value) void tss::cleanup(void* value)
{ {
boost::mutex::scoped_lock lock(*tss_data_mutex); boost::mutex::scoped_lock lock(tss_data->mutex);
(*(*tss_data_cleanup_handlers)[m_slot])(value); (*tss_data->cleanup_handlers[m_slot])(value);
} }
} // namespace detail } // namespace detail

View File

@@ -14,8 +14,6 @@
#if defined(__BORLANDC__) #if defined(__BORLANDC__)
extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE /*hInstance*/, DWORD dwReason, LPVOID /*lpReserved*/) extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE /*hInstance*/, DWORD dwReason, LPVOID /*lpReserved*/)
#elif defined(_WIN32_WCE)
extern "C" BOOL WINAPI DllMain(HANDLE /*hInstance*/, DWORD dwReason, LPVOID /*lpReserved*/)
#else #else
extern "C" BOOL WINAPI DllMain(HINSTANCE /*hInstance*/, DWORD dwReason, LPVOID /*lpReserved*/) extern "C" BOOL WINAPI DllMain(HINSTANCE /*hInstance*/, DWORD dwReason, LPVOID /*lpReserved*/)
#endif #endif

View File

@@ -1,7 +1,4 @@
// (C) Copyright Michael Glassford 2004. // (C) Copyright Michael Glassford 2004.
// Copyright (c) 2006 Peter Dimov
// Copyright (c) 2006 Anthony Williams
//
// Use, modification and distribution are subject to the // Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file // Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,152 +7,178 @@
#if defined(BOOST_HAS_WINTHREADS) #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/assert.hpp>
#include <boost/thread/once.hpp> #include <boost/thread/mutex.hpp>
#include <boost/thread/once.hpp>
#include <list> #include <list>
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <windows.h> #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 )
{ {
return -1; 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;
} }
// Get the exit handlers list for the current thread from tls. /*
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.
*/
thread_exit_handlers* exit_handlers = extern "C" BOOST_THREAD_DECL int at_thread_exit(
static_cast< thread_exit_handlers* >( TlsGetValue( tls_key ) ); thread_exit_handler exit_handler
)
if( exit_handlers == 0 )
{ {
// No exit handlers list was created yet. 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 try
{ {
// Attempt to create a new exit handlers list. exit_handlers->push_front(exit_handler);
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; return -1;
} }
//Like the atexit() function, a result of zero
//indicates success.
return 0;
} }
// Like the C runtime library atexit() function, extern "C" BOOST_THREAD_DECL void on_process_enter(void)
// functions should be called in the reverse of {
// the order they are added, so push them on the boost::call_once(init_threadmon_mutex, once_init_threadmon_mutex);
// front of the list. boost::mutex::scoped_lock lock(*threadmon_mutex);
try BOOST_ASSERT(attached_thread_count == 0);
{
exit_handlers->push_front( exit_handler );
}
catch( ... )
{
return -1;
} }
// Like the atexit() function, a result of zero extern "C" BOOST_THREAD_DECL void on_process_exit(void)
// 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 )
{ {
TlsFree(tls_key); 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_enter() BOOST_ASSERT(attached_thread_count == 0);
{
}
extern "C" BOOST_THREAD_DECL void on_thread_exit() //Free the tls slot if one was allocated.
{
// Initializing tls_key here ensures its proper visibility
boost::call_once( init_tls_key, once_init_tls_key );
// Get the exit handlers list for the current thread from tls. if (tls_key != invalid_tls_key)
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() )
{ {
if( thread_exit_handler exit_handler = *exit_handlers->begin() ) 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())
{ {
(*exit_handler)(); if (thread_exit_handler exit_handler = *exit_handlers->begin())
(*exit_handler)();
exit_handlers->pop_front();
} }
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; delete exit_handlers;
exit_handlers = 0;
} }
} }
}
#endif //defined(BOOST_HAS_WINTHREADS) #endif //defined(BOOST_HAS_WINTHREADS)

View File

@@ -16,7 +16,7 @@
//Definitions required by implementation //Definitions required by implementation
#if (_MSC_VER < 1300) // 1300 == VC++ 7.0 #if (_MSC_VER < 1310) // 1310 == VC++ 7.1
typedef void (__cdecl *_PVFV)(void); typedef void (__cdecl *_PVFV)(void);
#define INIRETSUCCESS #define INIRETSUCCESS
#define PVAPI void #define PVAPI void
@@ -48,7 +48,7 @@
//The .CRT$Xxx information is taken from Codeguru: //The .CRT$Xxx information is taken from Codeguru:
//http://www.codeguru.com/Cpp/misc/misc/threadsprocesses/article.php/c6945__2/ //http://www.codeguru.com/Cpp/misc/misc/threadsprocesses/article.php/c6945__2/
#if (_MSC_VER >= 1300) // 1300 == VC++ 7.0 #if (_MSC_VER >= 1310) // 1310 == VC++ 7.1
# pragma data_seg(push, old_seg) # pragma data_seg(push, old_seg)
#endif #endif
//Callback to run tls glue code first. //Callback to run tls glue code first.
@@ -78,7 +78,7 @@
#pragma data_seg(".CRT$XTU") #pragma data_seg(".CRT$XTU")
static _PVFV p_process_term = on_process_term; static _PVFV p_process_term = on_process_term;
#pragma data_seg() #pragma data_seg()
#if (_MSC_VER >= 1300) // 1300 == VC++ 7.0 #if (_MSC_VER >= 1310) // 1310 == VC++ 7.1
# pragma data_seg(pop, old_seg) # pragma data_seg(pop, old_seg)
#endif #endif
@@ -94,7 +94,7 @@
DWORD volatile dw = _tls_used; DWORD volatile dw = _tls_used;
#if (_MSC_VER < 1300) // 1300 == VC++ 7.0 #if (_MSC_VER < 1310) // 1310 == VC++ 7.1
_TLSCB* pfbegin = __xl_a; _TLSCB* pfbegin = __xl_a;
_TLSCB* pfend = __xl_z; _TLSCB* pfend = __xl_z;
_TLSCB* pfdst = pfbegin; _TLSCB* pfdst = pfbegin;

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/config.hpp>
@@ -22,8 +27,6 @@
# include <boost/thread/detail/force_cast.hpp> # include <boost/thread/detail/force_cast.hpp>
#endif #endif
#include <cassert>
namespace boost { namespace boost {
#ifdef BOOST_HAS_MPTASKS #ifdef BOOST_HAS_MPTASKS
@@ -108,23 +111,13 @@ int xtime_get(struct xtime* xtp, int clock_type)
return clock_type; return clock_type;
#elif defined(BOOST_HAS_GETTIMEOFDAY) #elif defined(BOOST_HAS_GETTIMEOFDAY)
struct timeval tv; struct timeval tv;
# ifndef NDEBUG
int res =
#endif
gettimeofday(&tv, 0); gettimeofday(&tv, 0);
assert(0 == res);
assert(tv.tv_sec >= 0);
assert(tv.tv_usec >= 0);
xtp->sec = tv.tv_sec; xtp->sec = tv.tv_sec;
xtp->nsec = tv.tv_usec * 1000; xtp->nsec = tv.tv_usec * 1000;
return clock_type; return clock_type;
#elif defined(BOOST_HAS_CLOCK_GETTIME) #elif defined(BOOST_HAS_CLOCK_GETTIME)
timespec ts; timespec ts;
# ifndef NDEBUG
int res =
# endif
clock_gettime(CLOCK_REALTIME, &ts); clock_gettime(CLOCK_REALTIME, &ts);
assert(0 == res);
xtp->sec = ts.tv_sec; xtp->sec = ts.tv_sec;
xtp->nsec = ts.tv_nsec; xtp->nsec = ts.tv_nsec;
return clock_type; return clock_type;

83
test/Jamfile Normal file
View File

@@ -0,0 +1,83 @@
# 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.
#
# Boost.Threads test Jamfile
#
# Additional configuration variables used:
# See threads.jam.
# Declare the location of this subproject relative to the root.
subproject libs/thread/test ;
# Include threads.jam for Boost.Threads global build information.
# This greatly simplifies the Jam code needed to configure the build
# for the various Win32 build types.
import ../build/threads ;
# bring in rules for testing
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 ##
;
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 ]
;
}

View File

@@ -1,6 +1,7 @@
# (C) Copyright William E. Kempf 2001. # (C) Copyright William E. Kempf 2001. Permission to copy, use, modify, sell
# Distributed under the Boost Software License, Version 1.0. (See accompanying # and distribute this software is granted provided this copyright notice
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # 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 # Boost.Threads test Jamfile
# #
@@ -18,28 +19,18 @@
import testing ; import testing ;
project project
: requirements <library>/boost/test//boost_unit_test_framework/<link>static : requirements <library>../build//boost_thread
<library>../../test/build//boost_unit_test_framework
<threading>multi <threading>multi
; ;
rule thread-run ( sources )
{
return
[ run $(sources) ../build//boost_thread ]
[ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
: : : : $(sources[1]:B)_lib ]
;
}
{ {
test-suite "threads" test-suite "threads"
: [ thread-run test_thread.cpp ] : [ run test_thread.cpp ]
[ thread-run test_mutex.cpp ] [ run test_mutex.cpp ]
[ thread-run test_condition.cpp ] [ run test_condition.cpp ]
[ thread-run test_tss.cpp ] [ run test_tss.cpp ]
[ thread-run test_once.cpp ] [ run test_once.cpp ]
[ thread-run test_xtime.cpp ] [ run test_xtime.cpp ]
[ thread-run test_barrier.cpp ] [ run test_barrier.cpp ]
[ thread-run test_read_write_mutex.cpp ]
; ;
} }

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/config.hpp>
@@ -43,7 +48,7 @@ void test_barrier()
g.join_all(); g.join_all();
BOOST_CHECK(global_parameter == 5); BOOST_TEST(global_parameter == 5);
} }
boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[]) boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/config.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/config.hpp>
@@ -12,6 +17,7 @@
#include <boost/thread/condition.hpp> #include <boost/thread/condition.hpp>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <boost/test/unit_test_suite_ex.hpp>
#define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_sleep_only #define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_sleep_only
#include <libs/thread/test/util.inl> #include <libs/thread/test/util.inl>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/config.hpp>

View File

@@ -1,10 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
#include <boost/thread/detail/config.hpp> // that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp> #include <boost/thread/xtime.hpp>
@@ -14,767 +17,314 @@
#include <iostream> #include <iostream>
#define TS_CHECK(pred) \
do { if (!(pred)) BOOST_ERROR (#pred); } while (0)
#define TS_CHECK_MSG(pred, msg) \
do { if (!(pred)) BOOST_ERROR (msg); } while (0)
namespace { namespace {
int shared_val = 0; int shared_val = 0;
boost::xtime xsecs(int secs) boost::xtime xsecs(int secs)
{ {
//Create an xtime that is secs seconds from now
boost::xtime ret; boost::xtime ret;
TS_CHECK (boost::TIME_UTC == boost::xtime_get(&ret, boost::TIME_UTC)); BOOST_TEST(boost::TIME_UTC == boost::xtime_get(&ret, boost::TIME_UTC));
ret.sec += secs; ret.sec += secs;
return ret; return ret;
} }
#define MESSAGE "w1=" << w1.value_ << ", w2=" << w2.value_ << ", r1=" << r1.value_ << ", r2=" << r2.value_
template <typename RW> template <typename RW>
class thread_adapter class thread_adapter
{ {
public: public:
thread_adapter(void (*func)(void*,RW &), void* param1,RW &param2)
thread_adapter( : _func(func), _param1(param1) ,_param2(param2){ }
void (*func)(void*, RW&), void operator()() const { _func(_param1, _param2); }
void* param1,
RW &param2
)
: func_(func)
, param1_(param1)
, param2_(param2)
{}
void operator()() const
{
func_(param1_, param2_);
}
private: private:
void (*_func)(void*, RW &);
void (*func_)(void*, RW&); void* _param1;
void* param1_; RW& _param2;
RW& param2_;
}; };
const int k_data_init = -1;
template <typename RW> template <typename RW>
struct data struct data
{ {
data( data(int id, RW &m, int secs=0)
int id, : m_id(id), m_value(-1), m_secs(secs), m_rw(m)
RW& m, {
int wait_for_lock_secs, }
int sleep_with_lock_secs, int m_id;
bool demote_after_write = false int m_value;
) int m_secs;
: id_(id)
, wait_for_lock_secs_(wait_for_lock_secs)
, sleep_with_lock_secs_(sleep_with_lock_secs)
, test_promotion_and_demotion_(demote_after_write)
, value_(k_data_init)
, rw_(m)
{}
int id_; RW& m_rw; // Reader/Writer mutex
int wait_for_lock_secs_;
int sleep_with_lock_secs_;
bool test_promotion_and_demotion_;
int value_;
RW& rw_;
}; };
// plain_writer excercises the "infinite" lock for each
// read_write_mutex type.
template<typename RW> template<typename RW>
void plain_writer(void* arg, RW& rw) void plain_writer(void *arg,RW &rw)
{ {
try data<RW> *pdata = (data<RW> *) arg;
// std::cout << "-->W" << pdata->m_id << "\n";
typename RW::scoped_read_write_lock l(rw, boost::read_write_lock_state::write_locked);
boost::thread::sleep(xsecs(3));
shared_val += 10;
pdata->m_value = shared_val;
}
template<typename RW>
void plain_reader(void *arg,RW &rw)
{
data<RW> *pdata = (data<RW> *) arg;
typename RW::scoped_read_write_lock l(rw, boost::read_write_lock_state::read_locked);
pdata->m_value = shared_val;
}
template<typename RW>
void try_writer(void *arg,RW &rw)
{
data<RW> *pdata = (data<RW> *) arg;
// std::cout << "-->W" << pdata->m_id << "\n";
typename RW::scoped_try_read_write_lock l(rw, boost::read_write_lock_state::unlocked);
if (l.try_write_lock())
{ {
data<RW>* pdata = (data<RW>*) arg;
TS_CHECK_MSG(pdata->wait_for_lock_secs_ == 0, "pdata->wait_for_lock_secs_: " << pdata->wait_for_lock_secs_);
typename RW::scoped_read_write_lock l( boost::thread::sleep(xsecs(3));
rw, shared_val += 10;
pdata->test_promotion_and_demotion_
? boost::read_write_lock_state::read_locked
: boost::read_write_lock_state::write_locked
);
bool succeeded = true; pdata->m_value = shared_val;
if (pdata->test_promotion_and_demotion_)
{
try
{
l.promote();
}
catch(const boost::lock_error&)
{
succeeded = false;
}
}
if (succeeded)
{
if (pdata->sleep_with_lock_secs_ > 0)
boost::thread::sleep(xsecs(pdata->sleep_with_lock_secs_));
shared_val += 10;
if (pdata->test_promotion_and_demotion_)
l.demote();
pdata->value_ = shared_val;
}
} }
catch(...)
}
template<typename RW>
void try_reader(void *arg,RW &rw)
{
data<RW> *pdata = (data<RW> *) arg;
typename RW::scoped_try_read_write_lock l(rw, boost::read_write_lock_state::unlocked);
if (l.try_read_lock())
{ {
TS_CHECK_MSG(false, "plain_writer() exception!"); pdata->m_value = shared_val;
throw;
} }
} }
template<typename RW> template<typename RW>
void plain_reader(void* arg, RW& rw) void timed_writer(void *arg,RW &rw)
{ {
try data<RW> *pdata = (data<RW> *) arg;
boost::xtime xt;
xt = xsecs(pdata->m_secs);
typename RW::scoped_timed_read_write_lock l(rw,boost::read_write_lock_state::unlocked);
if (l.timed_write_lock(xt))
{ {
data<RW>* pdata = (data<RW>*)arg; boost::thread::sleep(xsecs(3));
TS_CHECK(!pdata->test_promotion_and_demotion_); shared_val += 10;
TS_CHECK_MSG(pdata->wait_for_lock_secs_ == 0, "pdata->wait_for_lock_secs_: " << pdata->wait_for_lock_secs_);
typename RW::scoped_read_write_lock l(rw, boost::read_write_lock_state::read_locked); pdata->m_value = shared_val;
if (pdata->sleep_with_lock_secs_ > 0)
boost::thread::sleep(xsecs(pdata->sleep_with_lock_secs_));
pdata->value_ = shared_val;
}
catch(...)
{
TS_CHECK_MSG(false, "plain_reader() exception!");
throw;
} }
} }
template<typename RW> template<typename RW>
void try_writer(void* arg, RW& rw) void timed_reader(void *arg,RW &rw)
{ {
try data<RW> *pdata = (data<RW> *) arg;
boost::xtime xt;
xt = xsecs(pdata->m_secs);
typename RW::scoped_timed_read_write_lock l(rw,boost::read_write_lock_state::unlocked);
if (l.timed_read_lock(xt))
{ {
data<RW>* pdata = (data<RW>*) arg; pdata->m_value = shared_val;
TS_CHECK_MSG(pdata->wait_for_lock_secs_ == 0, "pdata->wait_for_lock_secs_: " << pdata->wait_for_lock_secs_);
typename RW::scoped_try_read_write_lock l(rw, boost::read_write_lock_state::unlocked);
bool succeeded = false;
if (pdata->test_promotion_and_demotion_)
succeeded = l.try_read_lock() && l.try_promote();
else
succeeded = l.try_write_lock();
if (succeeded)
{
if (pdata->sleep_with_lock_secs_ > 0)
boost::thread::sleep(xsecs(pdata->sleep_with_lock_secs_));
shared_val += 10;
if (pdata->test_promotion_and_demotion_)
l.demote();
pdata->value_ = shared_val;
}
}
catch(...)
{
TS_CHECK_MSG(false, "try_writer() exception!");
throw;
} }
} }
template<typename RW> template<typename RW>
void try_reader(void*arg, RW& rw) void dump_times(const char *prefix,data<RW> *pdata)
{ {
try std::cout << " " << prefix << pdata->m_id <<
{ " In:" << pdata->m_start.LowPart <<
data<RW>* pdata = (data<RW>*)arg; " Holding:" << pdata->m_holding.LowPart <<
TS_CHECK(!pdata->test_promotion_and_demotion_); " Out: " << pdata->m_end.LowPart << std::endl;
TS_CHECK_MSG(pdata->wait_for_lock_secs_ == 0, "pdata->wait_for_lock_secs_: " << pdata->wait_for_lock_secs_);
typename RW::scoped_try_read_write_lock l(rw, boost::read_write_lock_state::unlocked);
if (l.try_read_lock())
{
if (pdata->sleep_with_lock_secs_ > 0)
boost::thread::sleep(xsecs(pdata->sleep_with_lock_secs_));
pdata->value_ = shared_val;
}
}
catch(...)
{
TS_CHECK_MSG(false, "try_reader() exception!");
throw;
}
} }
template<typename RW> template<typename RW>
void timed_writer(void* arg, RW& rw) void test_plain_read_write_mutex(RW &rw)
{
try
{
data<RW>* pdata = (data<RW>*)arg;
typename RW::scoped_timed_read_write_lock l(rw, boost::read_write_lock_state::unlocked);
bool succeeded = false;
boost::xtime xt = xsecs(pdata->wait_for_lock_secs_);
if (pdata->test_promotion_and_demotion_)
succeeded = l.timed_read_lock(xt) && l.timed_promote(xt);
else
succeeded = l.timed_write_lock(xt);
if (succeeded)
{
if (pdata->sleep_with_lock_secs_ > 0)
boost::thread::sleep(xsecs(pdata->sleep_with_lock_secs_));
shared_val += 10;
if (pdata->test_promotion_and_demotion_)
l.demote();
pdata->value_ = shared_val;
}
}
catch(...)
{
TS_CHECK_MSG(false, "timed_writer() exception!");
throw;
}
}
template<typename RW>
void timed_reader(void* arg, RW& rw)
{
try
{
data<RW>* pdata = (data<RW>*)arg;
TS_CHECK(!pdata->test_promotion_and_demotion_);
typename RW::scoped_timed_read_write_lock l(rw,boost::read_write_lock_state::unlocked);
boost::xtime xt = xsecs(pdata->wait_for_lock_secs_);
if (l.timed_read_lock(xt))
{
if (pdata->sleep_with_lock_secs_ > 0)
boost::thread::sleep(xsecs(pdata->sleep_with_lock_secs_));
pdata->value_ = shared_val;
}
}
catch(...)
{
TS_CHECK_MSG(false, "timed_reader() exception!");
throw;
}
}
template<typename RW>
void clear_data(data<RW>& data1, data<RW>& data2, data<RW>& data3, data<RW>& data4)
{ {
shared_val = 0; shared_val = 0;
data1.value_ = k_data_init; data<RW> r1(1,rw);
data2.value_ = k_data_init; data<RW> r2(2,rw);
data3.value_ = k_data_init; data<RW> w1(1,rw);
data4.value_ = k_data_init; data<RW> w2(2,rw);
}
bool shared_test_writelocked = false; // Writer one launches, holds the lock for 3 seconds.
bool shared_test_readlocked = false; boost::thread tw1(thread_adapter<RW>(plain_writer,&w1,rw));
bool shared_test_unlocked = false;
template<typename RW> // Writer two launches, tries to grab the lock, "clearly"
void run_try_tests(void* arg, RW& rw) // after Writer one will already be holding it.
{ boost::thread::sleep(xsecs(1));
try boost::thread tw2(thread_adapter<RW>(plain_writer,&w2,rw));
// Reader one launches, "clearly" after writer two, and "clearly"
// while writer 1 still holds the lock
boost::thread::sleep(xsecs(1));
boost::thread tr1(thread_adapter<RW>(plain_reader,&r1,rw));
boost::thread tr2(thread_adapter<RW>(plain_reader,&r2,rw));
tr2.join();
tr1.join();
tw2.join();
tw1.join();
if (rw.policy() == boost::read_write_scheduling_policy::writer_priority)
{ {
TS_CHECK(shared_test_writelocked || shared_test_readlocked || shared_test_unlocked); BOOST_TEST(w1.m_value == 10);
BOOST_TEST(w2.m_value == 20);
typename RW::scoped_try_read_write_lock l(rw, boost::read_write_lock_state::unlocked); BOOST_TEST(r1.m_value == 20); // Readers get in after 2nd writer
BOOST_TEST(r2.m_value == 20);
if (shared_test_writelocked)
{
//Verify that write lock blocks other write locks
TS_CHECK(!l.try_write_lock());
//Verify that write lock blocks read locks
TS_CHECK(!l.try_read_lock());
}
else if (shared_test_readlocked)
{
//Verify that read lock blocks write locks
TS_CHECK(!l.try_write_lock());
//Verify that read lock does not block other read locks
TS_CHECK(l.try_read_lock());
//Verify that read lock blocks promotion
TS_CHECK(!l.try_promote());
}
else if (shared_test_unlocked)
{
//Verify that unlocked does not blocks write locks
TS_CHECK(l.try_write_lock());
//Verify that unlocked does not block demotion
TS_CHECK(l.try_demote());
l.unlock();
//Verify that unlocked does not block read locks
TS_CHECK(l.try_read_lock());
//Verify that unlocked does not block promotion
TS_CHECK(l.try_promote());
l.unlock();
}
} }
catch(...) else if (rw.policy() == boost::read_write_scheduling_policy::reader_priority)
{ {
TS_CHECK_MSG(false, "run_try_tests() exception!"); BOOST_TEST(w1.m_value == 10);
throw; BOOST_TEST(w2.m_value == 20);
BOOST_TEST(r1.m_value == 10); // Readers get in before 2nd writer
BOOST_TEST(r2.m_value == 10);
}
else if (rw.policy() == boost::read_write_scheduling_policy::alternating_many_reads)
{
BOOST_TEST(w1.m_value == 10);
BOOST_TEST(w2.m_value == 20);
BOOST_TEST(r1.m_value == 10); // Readers get in before 2nd writer
BOOST_TEST(r2.m_value == 10);
}
else if (rw.policy() == boost::read_write_scheduling_policy::alternating_single_read)
{
BOOST_TEST(w1.m_value == 10);
BOOST_TEST(w2.m_value == 20);
// One Reader gets in before 2nd writer, but we can't tell
// which reader will "win", so just check their sum.
BOOST_TEST((r1.m_value + r2.m_value == 30));
} }
} }
template<typename RW> template<typename RW>
void test_plain_read_write_mutex(RW& rw, bool test_promotion_and_demotion) void test_try_read_write_mutex(RW &rw)
{ {
//Verify that a write lock prevents both readers and writers from obtaining a lock data<RW> r1(1,rw);
{ data<RW> w1(2,rw);
shared_val = 0; data<RW> w2(3,rw);
data<RW> r1(1, rw, 0, 0);
data<RW> r2(2, rw, 0, 0);
data<RW> w1(3, rw, 0, 0);
data<RW> w2(4, rw, 0, 0);
//Write-lock the mutex and queue up other readers and writers // We start with some specialized tests for "try" behavior
typename RW::scoped_read_write_lock l(rw, boost::read_write_lock_state::write_locked); shared_val = 0;
boost::thread tr1(thread_adapter<RW>(plain_reader, &r1, rw)); // Writer one launches, holds the lock for 3 seconds.
boost::thread tr2(thread_adapter<RW>(plain_reader, &r2, rw));
boost::thread tw1(thread_adapter<RW>(plain_writer, &w1, rw));
boost::thread tw2(thread_adapter<RW>(plain_writer, &w2, rw));
boost::thread::sleep(xsecs(1)); boost::thread tw1(thread_adapter<RW>(try_writer,&w1,rw));
//At this point, neither queued readers nor queued writers should have obtained access // Reader one launches, "clearly" after writer #1 holds the lock
// and before it releases the lock.
boost::thread::sleep(xsecs(1));
boost::thread tr1(thread_adapter<RW>(try_reader,&r1,rw));
TS_CHECK_MSG(w1.value_ == k_data_init, MESSAGE); // Writer two launches in the same timeframe.
TS_CHECK_MSG(w2.value_ == k_data_init, MESSAGE); boost::thread tw2(thread_adapter<RW>(try_writer,&w2,rw));
TS_CHECK_MSG(r1.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(r2.value_ == k_data_init, MESSAGE);
if (test_promotion_and_demotion) tw2.join();
{ tr1.join();
l.demote(); tw1.join();
boost::thread::sleep(xsecs(1));
//:boost::thread tr3(thread_adapter<RW>(plain_reader, &r3, rw));
if (rw.policy() == boost::read_write_scheduling_policy::writer_priority) BOOST_TEST(w1.m_value == 10);
{ BOOST_TEST(r1.m_value == -1); // Try would return w/o waiting
//Expected result: BOOST_TEST(w2.m_value == -1); // Try would return w/o waiting
//Since writers have priority, demotion doesn't release any readers.
TS_CHECK_MSG(w1.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(w2.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(r1.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(r2.value_ == k_data_init, MESSAGE);
}
else if (rw.policy() == boost::read_write_scheduling_policy::reader_priority)
{
//Expected result:
//Since readers have priority, demotion releases all readers.
TS_CHECK_MSG(w1.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(w2.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(r1.value_ == 0, MESSAGE);
TS_CHECK_MSG(r2.value_ == 0, MESSAGE);
}
else if (rw.policy() == boost::read_write_scheduling_policy::alternating_many_reads)
{
//Expected result:
//Since readers can be released many at a time, demotion releases all queued readers.
TS_CHECK_MSG(w1.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(w2.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(r1.value_ == 0, MESSAGE);
TS_CHECK_MSG(r2.value_ == 0, MESSAGE);
//:TS_CHECK_MSG(r3.value_ == k_data_init, MESSAGE);
}
else if (rw.policy() == boost::read_write_scheduling_policy::alternating_single_read)
{
//Expected result:
//Since readers can be released only one at a time, demotion releases one queued reader.
TS_CHECK_MSG(w1.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(w2.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(r1.value_ == k_data_init || r1.value_ == 0, MESSAGE);
TS_CHECK_MSG(r2.value_ == k_data_init || r2.value_ == 0, MESSAGE);
TS_CHECK_MSG(r1.value_ != r2.value_, MESSAGE);
}
}
l.unlock();
tr2.join(); // We finish by repeating the plain tests with the try lock
tr1.join(); // This is important to verify that try locks are proper read_write_mutexes as
tw2.join(); // well.
tw1.join(); test_plain_read_write_mutex(rw);
if (rw.policy() == boost::read_write_scheduling_policy::writer_priority)
{
if (!test_promotion_and_demotion)
{
//Expected result:
//1) either w1 or w2 obtains and releases the lock
//2) the other of w1 and w2 obtains and releases the lock
//3) r1 and r2 obtain and release the lock "simultaneously"
TS_CHECK_MSG(w1.value_ == 10 || w1.value_ == 20, MESSAGE);
TS_CHECK_MSG(w2.value_ == 10 || w2.value_ == 20, MESSAGE);
TS_CHECK_MSG(w1.value_ != w2.value_, MESSAGE);
TS_CHECK_MSG(r1.value_ == 20, MESSAGE);
TS_CHECK_MSG(r2.value_ == 20, MESSAGE);
}
else
{
//Expected result:
//The same, except that either w1 or w2 (but not both) may
//fail to promote to a write lock,
//and r1, r2, or both may "sneak in" ahead of w1 and/or w2
//by obtaining a read lock before w1 or w2 can promote
//their initial read lock to a write lock.
TS_CHECK_MSG(w1.value_ == k_data_init || w1.value_ == 10 || w1.value_ == 20, MESSAGE);
TS_CHECK_MSG(w2.value_ == k_data_init || w2.value_ == 10 || w2.value_ == 20, MESSAGE);
TS_CHECK_MSG(w1.value_ != w2.value_, MESSAGE);
TS_CHECK_MSG(r1.value_ == k_data_init || r1.value_ == 10 || r1.value_ == 20, MESSAGE);
TS_CHECK_MSG(r2.value_ == k_data_init || r2.value_ == 10 || r2.value_ == 20, MESSAGE);
}
}
else if (rw.policy() == boost::read_write_scheduling_policy::reader_priority)
{
if (!test_promotion_and_demotion)
{
//Expected result:
//1) r1 and r2 obtain and release the lock "simultaneously"
//2) either w1 or w2 obtains and releases the lock
//3) the other of w1 and w2 obtains and releases the lock
TS_CHECK_MSG(w1.value_ == 10 || w1.value_ == 20, MESSAGE);
TS_CHECK_MSG(w2.value_ == 10 || w2.value_ == 20, MESSAGE);
TS_CHECK_MSG(w1.value_ != w2.value_, MESSAGE);
TS_CHECK_MSG(r1.value_ == 0, MESSAGE);
TS_CHECK_MSG(r2.value_ == 0, MESSAGE);
}
else
{
//Expected result:
//The same, except that either w1 or w2 (but not both) may
//fail to promote to a write lock.
TS_CHECK_MSG(w1.value_ == k_data_init || w1.value_ == 10 || w1.value_ == 20, MESSAGE);
TS_CHECK_MSG(w2.value_ == k_data_init || w2.value_ == 10 || w2.value_ == 20, MESSAGE);
TS_CHECK_MSG(w1.value_ != w2.value_, MESSAGE);
TS_CHECK_MSG(r1.value_ == 0, MESSAGE);
TS_CHECK_MSG(r2.value_ == 0, MESSAGE);
}
}
else if (rw.policy() == boost::read_write_scheduling_policy::alternating_many_reads)
{
if (!test_promotion_and_demotion)
{
//Expected result:
//1) r1 and r2 obtain and release the lock "simultaneously"
//2) either w1 or w2 obtains and releases the lock
//3) the other of w1 and w2 obtains and releases the lock
TS_CHECK_MSG(w1.value_ == 10 || w1.value_ == 20, MESSAGE);
TS_CHECK_MSG(w2.value_ == 10 || w2.value_ == 20, MESSAGE);
TS_CHECK_MSG(w1.value_ != w2.value_, MESSAGE);
TS_CHECK_MSG(r1.value_ == 0, MESSAGE);
TS_CHECK_MSG(r2.value_ == 0, MESSAGE);
}
else
{
//Expected result:
//The same, except that either w1 or w2 (but not both) may
//fail to promote to a write lock.
TS_CHECK_MSG(w1.value_ == k_data_init || w1.value_ == 10 || w1.value_ == 20, MESSAGE);
TS_CHECK_MSG(w2.value_ == k_data_init || w2.value_ == 10 || w2.value_ == 20, MESSAGE);
TS_CHECK_MSG(w1.value_ != w2.value_, MESSAGE);
TS_CHECK_MSG(r1.value_ == 0, MESSAGE);
TS_CHECK_MSG(r2.value_ == 0, MESSAGE);
}
}
else if (rw.policy() == boost::read_write_scheduling_policy::alternating_single_read)
{
if (!test_promotion_and_demotion)
{
//Expected result:
//1) either r1 or r2 obtains and releases the lock
//2) either w1 or w2 obtains and releases the lock
//3) the other of r1 and r2 obtains and releases the lock
//4) the other of w1 and w2 obtains and release the lock
TS_CHECK_MSG(w1.value_ == 10 || w1.value_ == 20, MESSAGE);
TS_CHECK_MSG(w2.value_ == 10 || w2.value_ == 20, MESSAGE);
TS_CHECK_MSG(w1.value_ != w2.value_, MESSAGE);
TS_CHECK_MSG(r1.value_ == 0 || r1.value_ == 10, MESSAGE);
TS_CHECK_MSG(r2.value_ == 0 || r2.value_ == 10, MESSAGE);
TS_CHECK_MSG(r1.value_ != r2.value_, MESSAGE);
}
else
{
//Expected result:
//Since w1 and w2 start as read locks, r1, r2, w1, and w2
//obtain read locks "simultaneously". Each of w1 and w2,
//after it obtain a read lock, attempts to promote to a
//write lock; this attempt fails if the other has
//already done so and currently holds the write lock;
//otherwise it will succeed as soon as any other
//read locks have been released.
//In other words, any ordering is possible, and either
//w1 or w2 (but not both) may fail to obtain the lock
//altogether.
TS_CHECK_MSG(w1.value_ == k_data_init || w1.value_ == 10 || w1.value_ == 20, MESSAGE);
TS_CHECK_MSG(w2.value_ == k_data_init || w2.value_ == 10 || w2.value_ == 20, MESSAGE);
TS_CHECK_MSG(w1.value_ != w2.value_, MESSAGE);
TS_CHECK_MSG(r1.value_ == 0 || r1.value_ == 10 || r1.value_ == 20, MESSAGE);
TS_CHECK_MSG(r2.value_ == 0 || r2.value_ == 10 || r2.value_ == 20, MESSAGE);
}
}
}
//Verify that a read lock prevents readers but not writers from obtaining a lock
{
shared_val = 0;
data<RW> r1(1, rw, 0, 0);
data<RW> r2(2, rw, 0, 0);
data<RW> w1(3, rw, 0, 0);
data<RW> w2(4, rw, 0, 0);
//Read-lock the mutex and queue up other readers and writers
typename RW::scoped_read_write_lock l(rw, boost::read_write_lock_state::read_locked);
boost::thread tr1(thread_adapter<RW>(plain_reader, &r1, rw));
boost::thread tr2(thread_adapter<RW>(plain_reader, &r2, rw));
boost::thread::sleep(xsecs(1));
boost::thread tw1(thread_adapter<RW>(plain_writer, &w1, rw));
boost::thread tw2(thread_adapter<RW>(plain_writer, &w2, rw));
boost::thread::sleep(xsecs(1));
//Expected result: all readers passed through before the writers entered
TS_CHECK_MSG(w1.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(w2.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(r1.value_ == 0, MESSAGE);
TS_CHECK_MSG(r2.value_ == 0, MESSAGE);
if (test_promotion_and_demotion)
{
l.promote();
}
l.unlock();
tr2.join();
tr1.join();
tw2.join();
tw1.join();
}
//Verify that a read lock prevents readers but not writers from obtaining a lock
{
shared_val = 0;
data<RW> r1(1, rw, 0, 0);
data<RW> r2(2, rw, 0, 0);
data<RW> w1(3, rw, 0, 0);
data<RW> w2(4, rw, 0, 0);
//Read-lock the mutex and queue up other readers and writers
typename RW::scoped_read_write_lock l(rw, boost::read_write_lock_state::read_locked);
boost::thread tw1(thread_adapter<RW>(plain_writer, &w1, rw));
boost::thread tw2(thread_adapter<RW>(plain_writer, &w2, rw));
boost::thread::sleep(xsecs(1));
boost::thread tr1(thread_adapter<RW>(plain_reader, &r1, rw));
boost::thread tr2(thread_adapter<RW>(plain_reader, &r2, rw));
boost::thread::sleep(xsecs(1));
if (rw.policy() == boost::read_write_scheduling_policy::writer_priority)
{
//Expected result:
//Writers have priority, so no readers have been released
TS_CHECK_MSG(w1.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(w2.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(r1.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(r2.value_ == k_data_init, MESSAGE);
}
else if (rw.policy() == boost::read_write_scheduling_policy::reader_priority)
{
//Expected result:
//Readers have priority, so all readers have been released
TS_CHECK_MSG(w1.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(w2.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(r1.value_ == 0, MESSAGE);
TS_CHECK_MSG(r2.value_ == 0, MESSAGE);
}
else if (rw.policy() == boost::read_write_scheduling_policy::alternating_many_reads)
{
//Expected result:
//It's the writers' turn, so no readers have been released
TS_CHECK_MSG(w1.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(w2.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(r1.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(r2.value_ == k_data_init, MESSAGE);
}
else if (rw.policy() == boost::read_write_scheduling_policy::alternating_single_read)
{
//Expected result:
//It's the writers' turn, so no readers have been released
TS_CHECK_MSG(w1.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(w2.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(r1.value_ == k_data_init, MESSAGE);
TS_CHECK_MSG(r2.value_ == k_data_init, MESSAGE);
}
if (test_promotion_and_demotion)
{
l.promote();
}
l.unlock();
tr2.join();
tr1.join();
tw2.join();
tw1.join();
}
} }
template<typename RW> template<typename RW>
void test_try_read_write_mutex(RW& rw, bool test_promotion_and_demotion) void test_timed_read_write_mutex(RW &rw)
{ {
//Repeat the plain tests with the try lock. data<RW> r1(1,rw,1);
//This is important to verify that try locks are proper data<RW> r2(2,rw,3);
//read_write_mutexes as well. data<RW> w1(3,rw,3);
data<RW> w2(4,rw,1);
test_plain_read_write_mutex(rw, test_promotion_and_demotion); // We begin with some specialized tests for "timed" behavior
//Verify try_* operations with write-locked mutex shared_val = 0;
{
typename RW::scoped_try_read_write_lock l(rw, boost::read_write_lock_state::write_locked);
shared_test_writelocked = true; // Writer one will hold the lock for 3 seconds.
shared_test_readlocked = false; boost::thread tw1(thread_adapter<RW>(timed_writer,&w1,rw));
shared_test_unlocked = false;
boost::thread test_thread(thread_adapter<RW>(run_try_tests, NULL, rw));
test_thread.join();
}
//Verify try_* operations with read-locked mutex boost::thread::sleep(xsecs(1));
{ // Writer two will "clearly" try for the lock after the readers
typename RW::scoped_try_read_write_lock l(rw, boost::read_write_lock_state::read_locked); // have tried for it. Writer will wait up 1 second for the lock.
// This write will fail.
shared_test_writelocked = false; boost::thread tw2(thread_adapter<RW>(timed_writer,&w2,rw));
shared_test_readlocked = true;
shared_test_unlocked = false;
boost::thread test_thread(thread_adapter<RW>(run_try_tests, NULL, rw));
test_thread.join();
}
//Verify try_* operations with unlocked mutex // Readers one and two will "clearly" try for the lock after writer
{ // one already holds it. 1st reader will wait 1 second, and will fail
shared_test_writelocked = false; // to get the lock. 2nd reader will wait 3 seconds, and will get
shared_test_readlocked = false; // the lock.
shared_test_unlocked = true;
boost::thread test_thread(thread_adapter<RW>(run_try_tests, NULL, rw));
test_thread.join();
}
}
template<typename RW> boost::thread tr1(thread_adapter<RW>(timed_reader,&r1,rw));
void test_timed_read_write_mutex(RW& rw, bool test_promotion_and_demotion) boost::thread tr2(thread_adapter<RW>(timed_reader,&r2,rw));
{
//Repeat the try tests with the timed lock.
//This is important to verify that timed locks are proper
//try locks as well.
test_try_read_write_mutex(rw, test_promotion_and_demotion);
//:More tests here tw1.join();
tr1.join();
tr2.join();
tw2.join();
BOOST_TEST(w1.m_value == 10);
BOOST_TEST(r1.m_value == -1);
BOOST_TEST(r2.m_value == 10);
BOOST_TEST(w2.m_value == -1);
// We follow by repeating the try tests with the timed lock.
// This is important to verify that timed locks are proper try locks as
// well
test_try_read_write_mutex(rw);
} }
} // namespace } // namespace
void do_test_read_write_mutex(bool test_promotion_and_demotion) void test_read_write_mutex()
{ {
//Run every test for each scheduling policy int i;
for(i = (int) boost::read_write_scheduling_policy::writer_priority;
for(int i = (int) boost::read_write_scheduling_policy::writer_priority;
i <= (int) boost::read_write_scheduling_policy::alternating_single_read; i <= (int) boost::read_write_scheduling_policy::alternating_single_read;
i++) i++)
{ {
std::cout << "plain test, sp=" << i boost::read_write_mutex plain_rw(static_cast<boost::read_write_scheduling_policy::read_write_scheduling_policy_enum>(i));
<< (test_promotion_and_demotion ? " with promotion & demotion" : " without promotion & demotion") boost::try_read_write_mutex try_rw(static_cast<boost::read_write_scheduling_policy::read_write_scheduling_policy_enum>(i));
<< "\n"; boost::timed_read_write_mutex timed_rw(static_cast<boost::read_write_scheduling_policy::read_write_scheduling_policy_enum>(i));
std::cout.flush();
{ std::cout << "plain test, sp=" << i << "\n";
boost::read_write_mutex plain_rw(static_cast<boost::read_write_scheduling_policy::read_write_scheduling_policy_enum>(i)); test_plain_read_write_mutex(plain_rw);
test_plain_read_write_mutex(plain_rw, test_promotion_and_demotion);
}
std::cout << "try test, sp=" << i std::cout << "try test, sp=" << i << "\n";
<< (test_promotion_and_demotion ? " with promotion & demotion" : " without promotion & demotion") test_try_read_write_mutex(try_rw);
<< "\n";
std::cout.flush();
{ std::cout << "timed test, sp=" << i << "\n";
boost::try_read_write_mutex try_rw(static_cast<boost::read_write_scheduling_policy::read_write_scheduling_policy_enum>(i)); test_timed_read_write_mutex(timed_rw);
test_try_read_write_mutex(try_rw, test_promotion_and_demotion);
}
std::cout << "timed test, sp=" << i
<< (test_promotion_and_demotion ? " with promotion & demotion" : " without promotion & demotion")
<< "\n";
std::cout.flush();
{
boost::timed_read_write_mutex timed_rw(static_cast<boost::read_write_scheduling_policy::read_write_scheduling_policy_enum>(i));
test_timed_read_write_mutex(timed_rw, test_promotion_and_demotion);
}
} }
} }
void test_read_write_mutex()
{
do_test_read_write_mutex(false);
do_test_read_write_mutex(true);
}
boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[]) boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
{ {
boost::unit_test_framework::test_suite* test = boost::unit_test_framework::test_suite* test =

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/config.hpp>
@@ -24,9 +29,9 @@ void simple_thread()
void comparison_thread(boost::thread* parent) void comparison_thread(boost::thread* parent)
{ {
boost::thread thrd; boost::thread thrd;
BOOST_CHECK(thrd != *parent); BOOST_TEST(thrd != *parent);
boost::thread thrd2; boost::thread thrd2;
BOOST_CHECK(thrd == thrd2); BOOST_TEST(thrd == thrd2);
} }
void test_sleep() void test_sleep()
@@ -36,7 +41,7 @@ void test_sleep()
// Ensure it's in a range instead of checking actual equality due to time // Ensure it's in a range instead of checking actual equality due to time
// lapse // lapse
BOOST_CHECK(in_range(xt, 2)); BOOST_CHECK(in_range(xt));
} }
void do_test_creation() void do_test_creation()

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/config.hpp>
@@ -144,12 +149,7 @@ void do_test_tss()
<< "\n"; << "\n";
std::cout.flush(); std::cout.flush();
// The following is not really an error. TSS cleanup support still is available BOOST_CHECK_EQUAL(tss_instances, 0);
// 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_EQUAL(tss_total, 5); BOOST_CHECK_EQUAL(tss_total, 5);
#endif #endif
} }

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/config.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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.
#if !defined(UTIL_INL_WEK01242003) #if !defined(UTIL_INL_WEK01242003)
#define UTIL_INL_WEK01242003 #define UTIL_INL_WEK01242003
@@ -25,8 +30,8 @@ inline boost::xtime delay(int secs, int msecs=0, int nsecs=0)
const int NANOSECONDS_PER_MILLISECOND = 1000000; const int NANOSECONDS_PER_MILLISECOND = 1000000;
boost::xtime xt; boost::xtime xt;
if (boost::TIME_UTC != boost::xtime_get (&xt, boost::TIME_UTC)) BOOST_CHECK_EQUAL(boost::xtime_get(&xt, boost::TIME_UTC),
BOOST_ERROR ("boost::xtime_get != boost::TIME_UTC"); static_cast<int>(boost::TIME_UTC));
nsecs += xt.nsec; nsecs += xt.nsec;
msecs += nsecs / NANOSECONDS_PER_MILLISECOND; msecs += nsecs / NANOSECONDS_PER_MILLISECOND;
@@ -135,10 +140,10 @@ void timed_test(F func, int secs,
} }
template <typename F, typename T> template <typename F, typename T>
class thread_binder class binder
{ {
public: public:
thread_binder(const F& func, const T& param) binder(const F& func, const T& param)
: func(func), param(param) { } : func(func), param(param) { }
void operator()() const { func(param); } void operator()() const { func(param); }
@@ -148,9 +153,9 @@ private:
}; };
template <typename F, typename T> template <typename F, typename T>
thread_binder<F, T> bind(const F& func, const T& param) binder<F, T> bind(const F& func, const T& param)
{ {
return thread_binder<F, T>(func, param); return binder<F, T>(func, param);
} }
} // namespace } // namespace

View File

@@ -1,8 +1,13 @@
# Copyright (C) 2001-2003 # Copyright (C) 2001-2003
# William E. Kempf # William E. Kempf
# #
# Distributed under the Boost Software License, Version 1.0. (See accompanying # Permission to use, copy, modify, distribute and sell this software
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # and its documentation for any purpose is hereby granted without fee,
# provided that the above copyright notice appear in all copies and
# that both that copyright notice and this permission notice appear
# in supporting documentation. William E. Kempf makes no representations
# about the suitability of this software for any purpose.
# It is provided "as is" without express or implied warranty.
# #
# Boost.Threads tutorial Jamfile # Boost.Threads tutorial Jamfile
# #
@@ -16,19 +21,34 @@
# variant to link against (see the pthreads-win32 documentation). # variant to link against (see the pthreads-win32 documentation).
# Example: jam -sPTW32="c:\pthreads-win32 pthreadVCE.lib" # Example: jam -sPTW32="c:\pthreads-win32 pthreadVCE.lib"
project # Declare the location of this subproject relative to the root.
: requirements <library>/boost/thread//boost_thread
<threading>multi subproject libs/thread/tutorial ;
# Include threads.jam for Boost.Threads global build information.
# This greatly simplifies the Jam code needed to configure the build
# for the various Win32 build types.
import ../build/threads ;
{
template tutorial
## sources ##
: <template>thread_base
<dll>../build/boost_thread
## requirements ##
:
## default build ##
:
; ;
exe helloworld : helloworld.cpp ; exe helloworld : <template>tutorial helloworld.cpp ;
exe helloworld2 : helloworld2.cpp ; exe helloworld2 : <template>tutorial helloworld2.cpp ;
exe helloworld3 : helloworld3.cpp ; exe helloworld3 : <template>tutorial helloworld3.cpp ;
exe helloworld4 : helloworld4.cpp ; exe helloworld4 : <template>tutorial helloworld4.cpp ;
exe factorial : factorial.cpp ; exe factorial : <template>tutorial factorial.cpp ;
exe factorial2 : factorial2.cpp ; exe factorial2 : <template>tutorial factorial2.cpp ;
exe factorial3 : factorial3.cpp ; exe factorial3 : <template>tutorial factorial3.cpp ;
exe counter : counter.cpp ; exe counter : <template>tutorial counter.cpp ;
exe bounded_buffer : bounded_buffer.cpp ; exe bounded_buffer : <template>tutorial bounded_buffer.cpp ;
exe once : once.cpp ; exe once : <template>tutorial once.cpp ;
}

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/condition.hpp> #include <boost/thread/condition.hpp>
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>
#include <iostream> #include <iostream>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>
#include <boost/ref.hpp> #include <boost/ref.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>
#include <iostream> #include <iostream>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>
#include <iostream> #include <iostream>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>
#include <iostream> #include <iostream>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>
#include <boost/thread/once.hpp> #include <boost/thread/once.hpp>

View File

@@ -1,8 +1,13 @@
// Copyright (C) 2001-2003 // Copyright (C) 2001-2003
// William E. Kempf // William E. Kempf
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Permission to use, copy, modify, distribute and sell this software
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>
#include <boost/thread/tss.hpp> #include <boost/thread/tss.hpp>