mirror of
https://github.com/boostorg/thread.git
synced 2026-02-03 09:42:16 +00:00
Compare commits
67 Commits
feature/pr
...
fix/10967_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2891aff469 | ||
|
|
c16ec42941 | ||
|
|
b77eac3e37 | ||
|
|
eb14d3d958 | ||
|
|
2c028aa014 | ||
|
|
ab026e239c | ||
|
|
3a48148462 | ||
|
|
9b9590730f | ||
|
|
8edc37930b | ||
|
|
ef48908f35 | ||
|
|
28ead512c1 | ||
|
|
6b60943f3e | ||
|
|
1fcaa47efa | ||
|
|
aac441392a | ||
|
|
6a34fc9c33 | ||
|
|
69d01b9bfd | ||
|
|
7b91ce7b64 | ||
|
|
978884ff0d | ||
|
|
ac8ca6eb04 | ||
|
|
1c16c52fe6 | ||
|
|
9299d26acf | ||
|
|
5577128bd8 | ||
|
|
e62c576944 | ||
|
|
ce8049f83f | ||
|
|
035217985c | ||
|
|
dfe95b3f2c | ||
|
|
e98447f974 | ||
|
|
deffa9aaf7 | ||
|
|
b87d26a900 | ||
|
|
6c9115fe39 | ||
|
|
b5b25eab1c | ||
|
|
803ba458ce | ||
|
|
c0470893d4 | ||
|
|
b2c445a030 | ||
|
|
6e37c55221 | ||
|
|
e1039e61f3 | ||
|
|
063b59e511 | ||
|
|
a342d1ccee | ||
|
|
811f3df98d | ||
|
|
8e1be55c6d | ||
|
|
421469686d | ||
|
|
72dfa02269 | ||
|
|
4c48b2276c | ||
|
|
8c7275cb9e | ||
|
|
14c5cff2ee | ||
|
|
83f38ea52c | ||
|
|
06a9f9ab6d | ||
|
|
e7f140cab6 | ||
|
|
1b99fe5587 | ||
|
|
b9a70f7aca | ||
|
|
ca87cbf57b | ||
|
|
929dc55a5a | ||
|
|
b29d9f850c | ||
|
|
1c81d8a4b1 | ||
|
|
7de29f4d45 | ||
|
|
9b0705cb6f | ||
|
|
3abdb869df | ||
|
|
f90e76a59c | ||
|
|
d4c8185cc9 | ||
|
|
e6501b5485 | ||
|
|
1ae3cb65f7 | ||
|
|
a8ad389bdd | ||
|
|
c3b98129e4 | ||
|
|
3891eeef52 | ||
|
|
f1370b1255 | ||
|
|
69f2a1df72 | ||
|
|
700301e382 |
133
README.md
133
README.md
@@ -6,3 +6,136 @@ Portable C++ multi-threading. C++11, C++14.
|
||||
### License
|
||||
|
||||
Distributed under the [Boost Software License, Version 1.0](http://boost.org/LICENSE_1_0.txt).
|
||||
|
||||
### Current Jenkins CI Test Status for unstable (develop) branch
|
||||
Overall build (nightly): <a href='https://ci.nedprod.com/view/All/job/Boost.Thread%20Build/'><img src='https://ci.nedprod.com/buildStatus/icon?job=Boost.Thread%20Build'></a> Overall tests (weekly, on Sundays): <a href='https://ci.nedprod.com/view/All/job/Boost.Thread%20Test/'><img src='https://ci.nedprod.com/buildStatus/icon?job=Boost.Thread%20Test'></a>
|
||||
|
||||
#### Build (nightly):
|
||||
<table id="configuration-matrix" width="100%" border="1">
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="6" valign="top">android-ndk</td><td class="matrix-leftcolumn" rowspan="2" valign="top">c++03</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.6,LINKTYPE=static,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.6</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.8,LINKTYPE=static,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.5,LINKTYPE=static,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.6,LINKTYPE=shared,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.6</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.8,LINKTYPE=shared,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.5,LINKTYPE=shared,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++11</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.8,LINKTYPE=static,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.5,LINKTYPE=static,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.8,LINKTYPE=shared,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.5,LINKTYPE=shared,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++14</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=clang++-3.5,LINKTYPE=static,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=clang++-3.5,LINKTYPE=shared,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="6" valign="top">winphone8</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++14</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-11.0,LINKTYPE=static,label=winphone8/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-11.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-12.0,LINKTYPE=static,label=winphone8/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-12.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-14.0,LINKTYPE=static,label=winphone8/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-14.0</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-11.0,LINKTYPE=shared,label=winphone8/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-11.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-12.0,LINKTYPE=shared,label=winphone8/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-12.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-14.0,LINKTYPE=shared,label=winphone8/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-14.0</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="6" valign="top">arm-gcc-clang</td><td class="matrix-leftcolumn" rowspan="2" valign="top">c++03</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.9,LINKTYPE=static,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.5,LINKTYPE=static,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.9,LINKTYPE=shared,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.5,LINKTYPE=shared,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++11</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.9,LINKTYPE=static,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.5,LINKTYPE=static,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.9,LINKTYPE=shared,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.5,LINKTYPE=shared,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++14</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=g++-4.9,LINKTYPE=static,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=g++-4.9,LINKTYPE=shared,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="6" valign="top">freebsd10-clang3.3</td><td class="matrix-leftcolumn" rowspan="2" valign="top">c++03</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.3,LINKTYPE=static,label=freebsd10-clang3.3/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.3,LINKTYPE=shared,label=freebsd10-clang3.3/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++11</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.3,LINKTYPE=static,label=freebsd10-clang3.3/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.3,LINKTYPE=shared,label=freebsd10-clang3.3/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="6" valign="top">linux-gcc-clang</td><td class="matrix-leftcolumn" rowspan="2" valign="top">c++03</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.6,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.6</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.7,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.7</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.2,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.2</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.3,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.4,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.4</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.6,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.6</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.7,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.7</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.2,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.2</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.3,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.4,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.4</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++11</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.7,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.7</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.2,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.2</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.3,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.4,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.4</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.7,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.7</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.2,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.2</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.3,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.4,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.4</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="6" valign="top">linux64-gcc-clang</td><td class="matrix-leftcolumn" rowspan="2" valign="top">c++03</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-analyse,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Unstable" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/yellow.png" tooltip="Unstable"/></a>clang++-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.8,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.9,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.5,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-analyse,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Unstable" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/yellow.png" tooltip="Unstable"/></a>clang++-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.8,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.9,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.5,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++11</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-analyse,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.8,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.9,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.5,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-analyse,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.8,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.9,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.5,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++14</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=clang++-analyse,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=g++-4.9,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=clang++-3.5,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=clang++-analyse,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=g++-4.9,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=clang++-3.5,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="6" valign="top">win8-msvc-mingw</td><td class="matrix-leftcolumn" rowspan="2" valign="top">c++03</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=mingw32,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw32</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=mingw64,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw64</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=mingw32,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw32</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=mingw64,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw64</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++11</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=mingw32,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw32</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=mingw64,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw64</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=mingw32,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw32</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=mingw64,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw64</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++14</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-10.0,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-10.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-11.0,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-11.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-12.0,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-12.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-14.0,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-14.0</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-analyse,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-10.0,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-10.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-11.0,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-11.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-12.0,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-12.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-14.0,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-14.0</div></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -63,6 +63,7 @@ project boost/thread
|
||||
<toolset>gcc:<cxxflags>-Wno-variadic-macros
|
||||
#<toolset>gcc:<cxxflags>-Wunused-local-typedefs
|
||||
<toolset>gcc:<cxxflags>-Wunused-function
|
||||
<toolset>gcc:<cxxflags>-Wno-unused-parameter
|
||||
|
||||
<toolset>darwin:<cxxflags>-Wextra
|
||||
<toolset>darwin:<cxxflags>-pedantic
|
||||
@@ -72,18 +73,20 @@ project boost/thread
|
||||
<toolset>darwin:<cxxflags>-Wno-variadic-macros
|
||||
#<toolset>darwin:<cxxflags>-Wunused-local-typedefs
|
||||
<toolset>darwin:<cxxflags>-Wunused-function
|
||||
<toolset>darwin:<cxxflags>-Wno-unused-parameter
|
||||
|
||||
#<toolset>pathscale:<cxxflags>-Wextra
|
||||
<toolset>pathscale:<cxxflags>-Wno-long-long
|
||||
<toolset>pathscale:<cxxflags>-pedantic
|
||||
|
||||
<toolset>clang:<warnings>on
|
||||
<toolset>clang:<cxxflags>-Wextra
|
||||
#<toolset>clang:<cxxflags>-ansi
|
||||
#<toolset>clang:<cxxflags>-fpermissive
|
||||
<toolset>clang:<cxxflags>-Wno-long-long
|
||||
<toolset>clang:<cxxflags>-Wunused-function
|
||||
<toolset>clang:<cxxflags>-Wno-variadic-macros
|
||||
<toolset>clang:<warnings>on
|
||||
<toolset>clang:<cxxflags>-Wno-unused-parameter
|
||||
|
||||
#<toolset>gcc-mingw-4.4.0:<cxxflags>-fdiagnostics-show-option
|
||||
#<toolset>gcc-mingw-4.5.0:<cxxflags>-fdiagnostics-show-option
|
||||
@@ -116,7 +119,9 @@ project boost/thread
|
||||
<toolset>intel:<cxxflags>-wd1418
|
||||
<toolset>intel:<cxxflags>-wd2415
|
||||
|
||||
<toolset>msvc:<cxxflags>/wd4100
|
||||
<toolset>msvc:<cxxflags>/wd4512
|
||||
<toolset>msvc:<cxxflags>/wd6246
|
||||
|
||||
|
||||
# : default-build <threading>multi
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
[warning These features are experimental and subject to change in future versions. There are not too much tests yet, so it is possible that you can find out some trivial bugs :(]
|
||||
|
||||
[note These features are based on the [@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3785.pdf [*N3785 - Executors and Schedulers revision 3]] C++1y proposal from Chris Mysen, Niklas Gustafsson, Matt Austern, Jeffrey Yasskin. The text that follows has been adapted from tis paper to show the differences.]
|
||||
[note These features are based on the [@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3785.pdf [*N3785 - Executors and Schedulers revision 3]] C++1y proposal from Chris Mysen, Niklas Gustafsson, Matt Austern, Jeffrey Yasskin. The text that follows has been adapted from this paper to show the differences.]
|
||||
|
||||
Executors are objects that can execute units of work packaged as function objects. Boost.Thread differs from N3785 mainly in the an Executor doesn't needs to inherit from an abstract class Executor. Static polymorphism is used instead and type erasure is used internally.
|
||||
|
||||
@@ -142,6 +142,7 @@ The third one is related to performance. They assert that "any mechanism for sto
|
||||
|
||||
In addition `std::function<void()>` can not be constructed by moving the closure, so e.g. `std::packaged_task` could not be a Closure.
|
||||
|
||||
[/
|
||||
[heading Scheduled work]
|
||||
|
||||
The approach of this library respect to scheduled work of the N3785 proposal is quite different. Instead of adding the scheduled operations to a specific scheduled_executor polymorphic interface, we opt by adding two member template functions to a class scheduled_executor that wraps an existing executor. This has several advantages:
|
||||
@@ -155,6 +156,25 @@ In order to manage with all the clocks, there are two alternatives:
|
||||
* have a single instance of a `scheduled_executor<Clock>` for each `CLock`.
|
||||
|
||||
The library chose the first of those options, largely for simplicity.
|
||||
]
|
||||
|
||||
[heading Scheduled work]
|
||||
|
||||
The approach of this library respect to scheduled work of the N3785 proposal is quite different. Instead of adding the scheduled operations to a specific scheduled_executor polymorphic interface, we opt by adding a specific `scheduler` class that is not an executor and knows how to manage with the scheduling of timed tasks `submit_at`/`submit_after`.
|
||||
|
||||
|
||||
`scheduler` provides executor factories `at`/`after` given a specific `time_point` or a `duration`. The built executors wrap a reference to this scheduler and the time at which the submitted task will be executed.
|
||||
|
||||
If we want to schedule these operations on an existing executor (as `serial_executor` does), these classes provide a `on` factory taking another executor as parameter and wraps both instance on the returned executor.
|
||||
|
||||
sch.on(tp).after(seconds(i)).submit(boost::bind(fn,i));
|
||||
|
||||
This has several advantages:
|
||||
|
||||
* The scheduled operations are available for all the executors via wrappers.
|
||||
* The template functions could accept any chrono `time_point` and `duration` respectively as we are not working with virtual functions.
|
||||
|
||||
In order to manage with all the clocks, this library propose generic solution. `scheduler<Clock>` know how to manage with the `submit_at`/`submit_after` `Clock::time_point`/`Clock::duration` tasks. Note that the durations on different clocks differ.
|
||||
|
||||
[heading Not Handled Exceptions]
|
||||
As in N3785 and based on the same design decision than `std`/`boost::thread` if a user closure throws an exception, the executor must call the `std::terminate` function.
|
||||
@@ -401,7 +421,7 @@ If invoked closure throws an exception the executor will call std::terminate, as
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [close the executor `e` for submissions.]]
|
||||
[[Effects:] [close the scheduler/executor `e` for submissions.]]
|
||||
|
||||
[[Remark:] [The worker threads will work until there is no more closures to run.]]
|
||||
|
||||
@@ -421,7 +441,7 @@ If invoked closure throws an exception the executor will call std::terminate, as
|
||||
|
||||
[[Return type:] [`bool`.]]
|
||||
|
||||
[[Return:] [whether the pool is closed for submissions.]]
|
||||
[[Return:] [whether the scheduler/executor is closed for submissions.]]
|
||||
|
||||
[[Throws:] [Whatever exception that can be throw while ensuring the thread safety.]]
|
||||
|
||||
@@ -659,8 +679,532 @@ Executor abstract base class.
|
||||
|
||||
[endsect]
|
||||
|
||||
[//////////////////////////////////////////////////////////]
|
||||
[section: scheduler Template Class `scheduler `]
|
||||
|
||||
Scheduler providing time related functions. Note that `scheduler` is not an Executor.
|
||||
|
||||
#include <boost/thread/executors/scheduler.hpp>
|
||||
namespace boost {
|
||||
|
||||
template <class Clock=steady_clock>
|
||||
class scheduler
|
||||
{
|
||||
public:
|
||||
using work = boost::function<void()> ;
|
||||
using clock = Clock;
|
||||
|
||||
scheduler(scheduler const&) = delete;
|
||||
scheduler& operator=(scheduler const&) = delete;
|
||||
|
||||
scheduler();
|
||||
~scheduler();
|
||||
|
||||
void close();
|
||||
bool closed();
|
||||
|
||||
template <class Duration, typename Closure>
|
||||
void submit_at(chrono::time_point<clock,Duration> abs_time, Closure&& closure);
|
||||
template <class Rep, class Period, typename Closure>
|
||||
void submit_after(chrono::duration<Rep,Period> rel_time, Closure&& closure);
|
||||
|
||||
template <class Duration>
|
||||
at_executor<scheduler> submit_at(chrono::time_point<clock,Duration> abs_time);
|
||||
template <class Rep, class Period>
|
||||
at_executor<scheduler> submit_after(chrono::duration<Rep,Period> rel_time);
|
||||
|
||||
template <class Executor>
|
||||
scheduler_executor_wrapper<scheduler, Executor> on(Executor& ex);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
[/////////////////////////////////////]
|
||||
[section:constructor Constructor `scheduler()`]
|
||||
|
||||
scheduler();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Constructs a `scheduler`. ]]
|
||||
|
||||
[[Throws:] [Nothing. ]]
|
||||
|
||||
]
|
||||
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:destructor Destructor `~scheduler()`]
|
||||
|
||||
~scheduler();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Destroys the scheduler.]]
|
||||
|
||||
[[Synchronization:] [The completion of all the closures happen before the completion of the executor destructor.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:submit_at Template Function Member `submit_at()`]
|
||||
|
||||
template <class Clock, class Duration, typename Closure>
|
||||
void submit_at(chrono::time_point<Clock,Duration> abs_time, Closure&& closure);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Schedule a `closure` to be executed at `abs_time`. ]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:submit_after Template Function Member `submit_after()`]
|
||||
|
||||
template <class Rep, class Period, typename Closure>
|
||||
void submit_after(chrono::duration<Rep,Period> rel_time, Closure&& closure);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Schedule a `closure` to be executed after `rel_time`. ]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[//////////////////////////////////////////////////////////]
|
||||
[section:at_executor Template Class `at_executor`]
|
||||
|
||||
|
||||
#include <boost/thread/executors/scheduler.hpp>
|
||||
namespace boost {
|
||||
|
||||
template <class Scheduler>
|
||||
class at_executor
|
||||
{
|
||||
public:
|
||||
using work = Scheduler::work;
|
||||
using clock = Scheduler::clock;
|
||||
|
||||
at_executor(at_executor const&) = default;
|
||||
at_executor(at_executor &&) = default;
|
||||
at_executor& operator=(at_executor const&) = default;
|
||||
at_executor& operator=(at_executor &&) = default;
|
||||
|
||||
at_executor(Scheduler& sch, clock::time_point const& tp);
|
||||
~at_executor();
|
||||
|
||||
void close();
|
||||
bool closed();
|
||||
|
||||
Scheduler& underlying_scheduler();
|
||||
|
||||
template <class Closure>
|
||||
void submit(Closure&& closure);
|
||||
template <class Duration, typename Work>
|
||||
void submit_at(chrono::time_point<clock,Duration> abs_time, Closure&& closure);
|
||||
template <class Rep, class Period, typename Work>
|
||||
void submit_after(chrono::duration<Rep,Period> rel_time, Closure&& closure);
|
||||
|
||||
template <class Executor>
|
||||
resubmit_at_executor<Scheduler, Executor> on(Executor& ex);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
[/////////////////////////////////////]
|
||||
[section:constructor Constructor `at_executor(Scheduler&)`]
|
||||
|
||||
at_executor(Scheduler& sch, clock::time_point const& tp);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Constructs a `at_executor`. ]]
|
||||
|
||||
[[Throws:] [Nothing. ]]
|
||||
|
||||
]
|
||||
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:destructor Destructor `~at_executor()`]
|
||||
|
||||
~at_executor();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Destroys the `at_executor`.]]
|
||||
|
||||
[[Synchronization:] [The completion of all the closures happen before the completion of the executor destructor.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:underlying_scheduler Function member `underlying_scheduler()`]
|
||||
|
||||
Scheduler& underlying_scheduler() noexcept;
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Return:] [The underlying scheduler instance. ]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:submit_at Template Function Member `submit()`]
|
||||
|
||||
template <typename Closure>
|
||||
void submit(Closure&& closure);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Schedule the `closure` to be executed at the `abs_time` given at construction time. ]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:submit_at Template Function Member `submit_at()`]
|
||||
|
||||
template <class Clock, class Duration, typename Closure>
|
||||
void submit_at(chrono::time_point<Clock,Duration> abs_time, Closure&& closure);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Schedule a `closure` to be executed at `abs_time`. ]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:submit_after Template Function Member `submit_after()`]
|
||||
|
||||
template <class Rep, class Period, typename Closure>
|
||||
void submit_after(chrono::duration<Rep,Period> rel_time, Closure&& closure);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Schedule a `closure` to be executed after `rel_time`. ]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[//////////////////////////////////////////////////////////]
|
||||
[section:scheduler_executor_wrapper Template Class `scheduler_executor_wrapper`]
|
||||
|
||||
#include <boost/thread/executors/scheduler.hpp>
|
||||
namespace boost {
|
||||
|
||||
template <class Scheduler, class Executor>
|
||||
class scheduler_executor_wrapper
|
||||
{
|
||||
public:
|
||||
using work = Scheduler::work;
|
||||
using clock = Scheduler::clock;
|
||||
|
||||
scheduler_executor_wrapper(scheduler_executor_wrapper const&) = default;
|
||||
scheduler_executor_wrapper(scheduler_executor_wrapper &&) = default;
|
||||
scheduler_executor_wrapper& operator=(scheduler_executor_wrapper const&) = default;
|
||||
scheduler_executor_wrapper& operator=(scheduler_executor_wrapper &&) = default;
|
||||
|
||||
scheduler_executor_wrapper(Scheduler& sch, Executor& ex);
|
||||
|
||||
~scheduler_executor_wrapper();
|
||||
|
||||
void close();
|
||||
bool closed();
|
||||
|
||||
Executor& underlying_executor();
|
||||
Scheduler& underlying_scheduler();
|
||||
|
||||
template <class Closure>
|
||||
void submit(Closure&& closure);
|
||||
template <class Duration, typename Work>
|
||||
void submit_at(chrono::time_point<clock,Duration> abs_time, Closure&& closure);
|
||||
template <class Rep, class Period, typename Work>
|
||||
void submit_after(chrono::duration<Rep,Period> rel_time, Closure&& closure);
|
||||
|
||||
template <class Duration>
|
||||
resubmit_at_executor<Scheduler, Executor> at(chrono::time_point<clock,Duration> abs_time);
|
||||
template <class Rep, class Period>
|
||||
resubmit_at_executor<Scheduler, Executor> after(chrono::duration<Rep,Period> rel_time);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
[/////////////////////////////////////]
|
||||
[section:constructor Constructor `scheduler_executor_wrapper(Scheduler&, Executor&)`]
|
||||
|
||||
scheduler_executor_wrapper(Scheduler& sch, Executor& ex);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Constructs a `scheduler_executor_wrapper`. ]]
|
||||
|
||||
[[Throws:] [Nothing. ]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:destructor Destructor `~scheduler_executor_wrapper()`]
|
||||
|
||||
~scheduler_executor_wrapper();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Destroys the `scheduler_executor_wrapper`.]]
|
||||
|
||||
[[Synchronization:] [The completion of all the closures happen before the completion of the executor destructor.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:underlying_scheduler Function member `underlying_scheduler()`]
|
||||
|
||||
Scheduler& underlying_scheduler() noexcept;
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Return:] [The underlying scheduler instance. ]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:underlying_executor Function member `underlying_executor()`]
|
||||
|
||||
Executor& underlying_executor() noexcept;
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Return:] [The underlying executor instance. ]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:submit_at Template Function Member `submit()`]
|
||||
|
||||
template <typename Closure>
|
||||
void submit(Closure&& closure);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Submit the `closure` on the underlying executor. ]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:submit_at Template Function Member `submit_at()`]
|
||||
|
||||
template <class Clock, class Duration, typename Closure>
|
||||
void submit_at(chrono::time_point<Clock,Duration> abs_time, Closure&& closure);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Resubmit the `closure` to be executed on the underlying executor at `abs_time`. ]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:submit_after Template Function Member `submit_after()`]
|
||||
|
||||
template <class Rep, class Period, typename Closure>
|
||||
void submit_after(chrono::duration<Rep,Period> rel_time, Closure&& closure);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Resubmit the `closure` to be executed on the underlying executor after `rel_time`. ]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[//////////////////////////////////////////////////////////]
|
||||
[section:resubmit_at_executor Template Class `resubmit_at_executor`]
|
||||
|
||||
`Executor` wrapping an `Scheduler`, an `Executor` and a `time_point` providing an `Executor` interface.
|
||||
|
||||
#include <boost/thread/executors/scheduler.hpp>
|
||||
namespace boost {
|
||||
|
||||
template <class Scheduler, class Executor>
|
||||
class resubmit_at_executor
|
||||
{
|
||||
public:
|
||||
using work = Scheduler::work;
|
||||
using clock = Scheduler::clock;
|
||||
|
||||
resubmit_at_executor(resubmit_at_executor const&) = default;
|
||||
resubmit_at_executor(resubmit_at_executor &&) = default;
|
||||
resubmit_at_executor& operator=(resubmit_at_executor const&) = default;
|
||||
resubmit_at_executor& operator=(resubmit_at_executor &&) = default;
|
||||
|
||||
template <class Duration>
|
||||
resubmit_at_executor(Scheduler& sch, Executor& ex, clock::time_point<Duration> const& tp);
|
||||
~resubmit_at_executor();
|
||||
|
||||
void close();
|
||||
bool closed();
|
||||
|
||||
Executor& underlying_executor();
|
||||
Scheduler& underlying_scheduler();
|
||||
|
||||
template <class Closure>
|
||||
void submit(Closure&& closure);
|
||||
template <class Duration, typename Work>
|
||||
void submit_at(chrono::time_point<clock,Duration> abs_time, Closure&& closure);
|
||||
template <class Rep, class Period, typename Work>
|
||||
void submit_after(chrono::duration<Rep,Period> rel_time, Closure&& closure);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
[/////////////////////////////////////]
|
||||
[section:constructor Constructor `resubmit_at_executor(Scheduler&, Executor&, clock::time_point<Duration>)`]
|
||||
|
||||
template <class Duration>
|
||||
resubmit_at_executor(Scheduler& sch, Executor& ex, clock::time_point<Duration> const& tp);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Constructs a `resubmit_at_executor`. ]]
|
||||
|
||||
[[Throws:] [Nothing. ]]
|
||||
|
||||
]
|
||||
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:destructor Destructor `~resubmit_at_executor()`]
|
||||
|
||||
~resubmit_at_executor();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Destroys the executor_adaptor.]]
|
||||
|
||||
[[Synchronization:] [The completion of all the closures happen before the completion of the executor destructor.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:underlying_executor Function member `underlying_executor()`]
|
||||
|
||||
Executor& underlying_executor() noexcept;
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Return:] [The underlying executor instance. ]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:underlying_scheduler Function member `underlying_scheduler()`]
|
||||
|
||||
Scheduler& underlying_scheduler() noexcept;
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Return:] [The underlying scheduler instance. ]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:submit_at Template Function Member `submit()`]
|
||||
|
||||
template <typename Closure>
|
||||
void submit(Closure&& closure);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Resubmit the `closure` to be executed on the underlying executor at the `abs_time` given at construction time. ]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:submit_at Template Function Member `submit_at()`]
|
||||
|
||||
template <class Clock, class Duration, typename Closure>
|
||||
void submit_at(chrono::time_point<Clock,Duration> abs_time, Closure&& closure);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Resubmit the `closure` to be executed on the underlying executor at `abs_time`. ]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:submit_after Template Function Member `submit_after()`]
|
||||
|
||||
template <class Rep, class Period, typename Closure>
|
||||
void submit_after(chrono::duration<Rep,Period> rel_time, Closure&& closure);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Resubmit the `closure` to be executed on the underlying executor after `rel_time`. ]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[//////////////////////////////////////////////////////////]
|
||||
[/
|
||||
[section:scheduled_executor_ref Template Class `scheduled_executor_ref`]
|
||||
|
||||
Executor providing time related functions.
|
||||
@@ -694,10 +1238,6 @@ Executor providing time related functions.
|
||||
template <typename Pred>
|
||||
bool reschedule_until(Pred const& pred);
|
||||
|
||||
template <class Clock, class Duration>
|
||||
void submit_at(chrono::time_point<Clock,Duration> abs_time, work&& closure);
|
||||
template <class Rep, class Period>
|
||||
void submit_after(chrono::duration<Rep,Period> rel_time, work&& closure);
|
||||
template <class Clock, class Duration, typename Closure>
|
||||
void submit_at(chrono::time_point<Clock,Duration> abs_time, Closure&& closure);
|
||||
template <class Rep, class Period, typename Closure>
|
||||
@@ -746,20 +1286,31 @@ Executor providing time related functions.
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:submit_at Template Function Member `submit()`]
|
||||
|
||||
template <typename Closure>
|
||||
void submit(Closure&& closure);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Resubmit the `closure` to be executed on the underlying executor. ]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[/////////////////////////////////////]
|
||||
[section:submit_at Template Function Member `submit_at()`]
|
||||
|
||||
template <class Clock, class Duration, typename Closure>
|
||||
void submit_at(chrono::time_point<Clock,Duration> abs_time, Closure&& closure);
|
||||
template <class Rep, class Period, typename Closure>
|
||||
void submit_after(chrono::duration<Rep,Period> rel_time, Closure&& closure);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [The underlying executor instance. ]]
|
||||
[[Effects:] [Schedule a `closure` to be executed at `abs_time`. ]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
@@ -767,11 +1318,26 @@ Executor providing time related functions.
|
||||
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:submit_after Template Function Member `submit_after()`]
|
||||
|
||||
template <class Rep, class Period, typename Closure>
|
||||
void submit_after(chrono::duration<Rep,Period> rel_time, Closure&& closure);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Schedule a `closure` to be executed after `rel_time`. ]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[endsect]
|
||||
]
|
||||
|
||||
[//////////////////////////////////////////////////////////]
|
||||
[section:serial_executor Template Class `serial_executor`]
|
||||
|
||||
|
||||
@@ -8,6 +8,40 @@
|
||||
|
||||
[section:changes History]
|
||||
|
||||
[heading Version 4.5.0 - boost 1.58]
|
||||
|
||||
[*Know Bugs:]
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/2442 #2442] Application statically linked with Boost.Thread crashes when Google Desktop is installed (Windows XP)
|
||||
* [@http://svn.boost.org/trac/boost/ticket/3926 #3926] thread_specific_ptr + dlopen library causes a SIGSEGV.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/4833 #4833] MinGW/test_tss_lib: Support of automatic tss cleanup for native threading API not available
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7319 #7319] Take care of c++std-lib-32966 issue
|
||||
* [@http://svn.boost.org/trac/boost/ticket/8600 #8600] wait_for_any hangs, if called with multiple copies of shared_future referencing same task
|
||||
* [@http://svn.boost.org/trac/boost/ticket/9118 #9118] Seg fault on thread join when llvm and libc++ are used
|
||||
* [@http://svn.boost.org/trac/boost/ticket/9309 #9309] test_latch fails often on clang-darwin-tot11
|
||||
* [@http://svn.boost.org/trac/boost/ticket/9310 #9310] test_4648_lib fails on clang-darwin-asan11
|
||||
* [@http://svn.boost.org/trac/boost/ticket/9311 #9311] ex_lambda_future fails on msvc-11.0
|
||||
* [@http://svn.boost.org/trac/boost/ticket/10537 #10537] Application crash on throw exception
|
||||
* [@http://svn.boost.org/trac/boost/ticket/10651 #10651] boost::thread leaks memory when using the MinGW compiler
|
||||
|
||||
Please take a look at [@https://svn.boost.org/trac/boost/query?status=assigned&status=new&status=reopened&component=thread&type=!Feature+Requests&col=id&col=summary&order=id thread Know Bugs] to see the current state.
|
||||
|
||||
Please take a look at [@http://www.boost.org/development/tests/master/developer/thread.html thread trunk regression test] to see the last snapshot.
|
||||
|
||||
[*Sever limitations:]
|
||||
|
||||
There are some severe bugs that prevent the use of the library on concrete contexts, in particular:
|
||||
|
||||
* on thread specific storage that prevent the library to be used with dynamic libraries,
|
||||
|
||||
[*New Experimental Features:]
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/9600 #9600] Async: Add task_region
|
||||
* [@http://svn.boost.org/trac/boost/ticket/10611 #10611] Add emplace promise::set_value and emplace make_ready_future
|
||||
|
||||
[*Fixed Bugs:]
|
||||
|
||||
|
||||
[heading Version 4.4.0 - boost 1.57]
|
||||
|
||||
[*Know Bugs:]
|
||||
@@ -557,9 +591,6 @@ been moved to __thread_id__.
|
||||
|
||||
The following features will be included in next releases.
|
||||
|
||||
# Complete the C++11 missing features, in particular
|
||||
* [@http://svn.boost.org/trac/boost/ticket/6227 #6227] C++11 compliance: Use of variadic templates on Generic Locking Algorithms on compilers providing them.
|
||||
|
||||
# Add some minor features, in particular
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7589 #7589] Synchro: Add polymorphic lockables.
|
||||
|
||||
@@ -567,9 +598,6 @@ The following features will be included in next releases.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/8273 #8273] Synchro: Add externally locked streams.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/8514 #8514] Async: Add a thread_pool executor with work stealing.
|
||||
|
||||
# Add extensions related to fork-join as:
|
||||
* [@http://svn.boost.org/trac/boost/ticket/9600 #9600] Async: Add task_region/task_run.
|
||||
|
||||
# And some additional extensions related to futures as:
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/8517 #8517] Async: Add a variadic shared_future::then.
|
||||
|
||||
482
doc/parallel.qbk
Normal file
482
doc/parallel.qbk
Normal file
@@ -0,0 +1,482 @@
|
||||
[/
|
||||
/ Copyright (c) 2014 Vicente J. Botet Escriba
|
||||
/
|
||||
/ 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)
|
||||
/]
|
||||
|
||||
[//////////////////////////////////////////////////////////]
|
||||
[section:parallel Parallel - Fork-Join -- EXPERIMENTAL]
|
||||
|
||||
[section:fork_join Fork-Join]
|
||||
|
||||
[warning These features are experimental and subject to change in future versions. There are not too much tests yet, so it is possible that you can find out some trivial bugs :(]
|
||||
|
||||
[note These features are based on the [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4088.pdf [* n4088 - Task Region R3]] C++1y proposal from P. Halpern, A. Robison, A. Laksberg, H. Sutter, et al. The text that follows has been adapted from this paper to show the differences.]
|
||||
|
||||
The major difference respect to the standard proposal is that we are able to use a common executor for several task regions.
|
||||
|
||||
[note
|
||||
Up to now, Boost.Thread doesn't implement the parallel algorithms as defined in [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4105.pdf [* n4105 - Information technology – Programming languages, their environments and system software interfaces – Technical Specification for C++ Extensions for Parallelism]].
|
||||
]
|
||||
|
||||
[////////////////////]
|
||||
[section Introduction]
|
||||
|
||||
|
||||
This module introduces a C++11/c++14 library function template `task_region` and a library class `task_region_handle`
|
||||
with member functions `run` and `wait` that together enable developers to write expressive and portable fork-join
|
||||
parallel code.
|
||||
|
||||
The working draft for the Parallelism TS [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4105.pdf [*N4105]] augments the STL algorithms with the inclusion of parallel execution policies. Programmers use these as a basis to write additional high-level algorithms that can be implemented in terms of the provided parallel algorithms. However, the scope of n4105 does not include lower-level mechanisms to express arbitrary fork-join parallelism
|
||||
|
||||
The `task_region`, `run` and the `wait` functions provided by this library are based on the `task_group` concept that is a part of the common subset of the PPL and the TBB libraries.
|
||||
|
||||
[endsect] [/ Introduction]
|
||||
|
||||
|
||||
[/////////////////////////]
|
||||
[section:tutorial Tutorial]
|
||||
|
||||
Consider an example of a parallel traversal of a tree, where a user-provided function compute is applied to each node of the tree, returning the sum of the results:
|
||||
|
||||
template<typename Func>
|
||||
int traverse(node *n, Func&& compute)
|
||||
{
|
||||
int left = 0, right = 0;
|
||||
task_region([&](task_region_handle& tr) {
|
||||
if (n->left)
|
||||
tr.run([&] { left = traverse(n->left, compute); });
|
||||
if (n->right)
|
||||
tr.run([&] { right = traverse(n->right, compute); });
|
||||
});
|
||||
return compute(n) + left + right;
|
||||
}
|
||||
|
||||
The example above demonstrates the use of two of the functions proposed in this paper, `task_region` and
|
||||
`task_region_handle::run`.
|
||||
The `task_region` function delineates a region in a program code potentially containing invocations of tasks
|
||||
spawned by the `run` member function of the `task_region_handle` class.
|
||||
|
||||
The run function spawns a task, a unit of work that is allowed to execute in parallel with respect to the caller.
|
||||
Any parallel tasks spawned by `run` within the `task_region` are joined back to a single thread of execution at
|
||||
the end of the `task_region`.
|
||||
|
||||
`run` takes a user-provided function object `f` and starts it asynchronously - i.e. it may return before the
|
||||
execution of `f` completes. The implementation's scheduler may choose to run `f` immediately or delay running
|
||||
`f` until compute resources become available.
|
||||
|
||||
A `task_region_handle` can be constructed only by `task_region` because it has no public constructors.
|
||||
Thus, `run` can be invoked (directly or indirectly) only from a user-provided function passed to `task_region`:
|
||||
|
||||
void g();
|
||||
void f(task_region_handle& tr)
|
||||
{
|
||||
tr.run(g); // OK, invoked from within task_region in h
|
||||
}
|
||||
void h()
|
||||
{
|
||||
task_region(f);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
task_region_handle tr; // Error: no public constructor
|
||||
tr.run(g); // No way to call run outside of a task_region
|
||||
return 0;
|
||||
}
|
||||
|
||||
[endsect] [/ Tutorial]
|
||||
|
||||
[////////////////]
|
||||
[section:examples Examples]
|
||||
|
||||
[section:fib Parallel Fibonacci]
|
||||
|
||||
|
||||
This is surely the worst implementation of the Fibonacci function. Anyway, here it is, as it is simple and shows the fork-join structure clearly. `Fibonacci(n) = Fibonacci(n-1) + Fibonacci(n-2)`, so the task decomposition is trivial.
|
||||
|
||||
int fib_task_region(int n)
|
||||
{
|
||||
using boost::experimental::parallel::task_region;
|
||||
using boost::experimental::parallel::task_region_handle;
|
||||
|
||||
if (n == 0) return 0;
|
||||
if (n == 1) return 1;
|
||||
|
||||
int n1;
|
||||
int n2;
|
||||
|
||||
task_region([&](task_region_handle& trh)
|
||||
{
|
||||
trh.run([&]
|
||||
{
|
||||
n1 = fib_task_region(n - 1);
|
||||
});
|
||||
|
||||
n2 = fib_task_region(n - 2);
|
||||
});
|
||||
|
||||
return n1 + n2;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
for (int i = 0; i<10; ++i) {
|
||||
std::cout << fib_task_region(i) << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
[endsect] [/ Fib]
|
||||
[section:fibex Parallel Fibonacci - Specific executor]
|
||||
|
||||
The previous example make use of an implementation defined way to spawn the tasks. Often the user wants to master how the task must be spawned. There is an overload of `task_region` that accept an additional `Executor` parameter and a function that takes as parameter a `task_region_handle_gen<Executor>`. `task_region_handle_gen<Executor>` run uses this executor to spawn the tasks.
|
||||
|
||||
template <class Ex>
|
||||
int fib_task_region_gen( Ex& ex, int n)
|
||||
{
|
||||
using boost::experimental::parallel::task_region;
|
||||
using boost::experimental::parallel::task_region_handle_gen;
|
||||
|
||||
if (n == 0) return 0;
|
||||
if (n == 1) return 1;
|
||||
|
||||
int n1;
|
||||
int n2;
|
||||
|
||||
task_region(ex, [&](task_region_handle_gen<Ex>& trh) // (2)
|
||||
{
|
||||
trh.run([&]
|
||||
{
|
||||
n1 = fib_task_region(n - 1);
|
||||
});
|
||||
|
||||
n2 = fib_task_region(n - 2);
|
||||
});
|
||||
|
||||
return n1 + n2;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::basic_thread_pool tp; // (1)
|
||||
for (int i = 0; i<10; ++i) {
|
||||
std::cout << fib_task_region_gen(tp,i) << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
The specific executor is declared in line (1) and it is used in line (2).
|
||||
|
||||
[endsect] [/ Fib ex]
|
||||
|
||||
|
||||
|
||||
|
||||
[section:quick_sort Parallel Accumulate]
|
||||
|
||||
|
||||
[endsect] [/ Accumulate]
|
||||
|
||||
[section:quick_sort Parallel Quick Sort]
|
||||
|
||||
|
||||
|
||||
[endsect] [/ QuickSort]
|
||||
[endsect] [/ Examples]
|
||||
|
||||
|
||||
[////////////////////////]
|
||||
[section:rationale Design Rationale]
|
||||
|
||||
|
||||
[endsect] [/ Design Rationale]
|
||||
[endsect] [/ Fork-Join]
|
||||
|
||||
[/////////////////////]
|
||||
[section:ref Reference -- EXPERIMENTAL]
|
||||
|
||||
[/////////////////////////]
|
||||
[section:v1 Parallel V1]
|
||||
|
||||
[section:exception_list Header `<experimental/exception_list.hpp>`]
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace experimental
|
||||
{
|
||||
namespace parallel
|
||||
{
|
||||
inline namespace v1
|
||||
{
|
||||
|
||||
class exception_list;
|
||||
|
||||
} // v1
|
||||
} // parallel
|
||||
} // experimental
|
||||
} // boost
|
||||
|
||||
|
||||
[/////////////////////////]
|
||||
[section:exception_list Class `exception_list`]
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace experimental
|
||||
{
|
||||
namespace parallel
|
||||
{
|
||||
inline namespace v1
|
||||
{
|
||||
|
||||
class exception_list: public std::exception
|
||||
{
|
||||
public:
|
||||
typedef 'implementation defined' const_iterator;
|
||||
|
||||
~exception_list() noexcept {}
|
||||
|
||||
void add(exception_ptr const& e);
|
||||
size_t size() const noexcept;
|
||||
const_iterator begin() const noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
const char* what() const noexcept;
|
||||
|
||||
};
|
||||
|
||||
} // v1
|
||||
} // parallel
|
||||
} // experimental
|
||||
} // boost
|
||||
|
||||
|
||||
[endsect] [/ exception_list]
|
||||
|
||||
[endsect] [/ exception_list.hpp]
|
||||
|
||||
[endsect] [/ Parallel V1]
|
||||
|
||||
[////////////////////////////////////////////////////////////////////]
|
||||
[section:v2 Parallel V2]
|
||||
[////////////////////////////////////////////////////////////////////]
|
||||
[section:concepts Concepts]
|
||||
[////////////////////////////////////////////////////////////////////]
|
||||
[section:regionCallable Concept `Region_Callable`]
|
||||
|
||||
[endsect] [/ Region_Callable]
|
||||
[////////////////////////////////////////////////////////////////////]
|
||||
[section:taskCallable Concept `Task_Callable`]
|
||||
|
||||
|
||||
[endsect] [/ Task_Callable]
|
||||
[////////////////////////////////////////////////////////////////////]
|
||||
[endsect] [/ Concepts]
|
||||
[////////////////////////////////////////////////////////////////////]
|
||||
[section:task_region Header `<experimental/task_region.hpp>`]
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace experimental
|
||||
{
|
||||
namespace parallel
|
||||
{
|
||||
inline namespace v2
|
||||
{
|
||||
|
||||
class task_canceled_exception;
|
||||
|
||||
template <class Executor>
|
||||
class task_region_handle_gen;
|
||||
|
||||
using default_executor = 'implementation defined';
|
||||
|
||||
class task_region_handle;
|
||||
|
||||
template <typename Executor, typename F>
|
||||
void task_region_final(Executor& ex, F&& f);
|
||||
template <typename F>
|
||||
void task_region_final(F&& f);
|
||||
|
||||
template <typename Executor, typename F>
|
||||
void task_region(Executor& ex, F&& f);
|
||||
template <typename F>
|
||||
void task_region(F&& f);
|
||||
|
||||
} // v2
|
||||
} // parallel
|
||||
} // experimental
|
||||
} // boost
|
||||
|
||||
|
||||
[////////////////////////////////////////////////////////////////////]
|
||||
[section:task_canceled_exception Class `task_canceled_exception `]
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace experimental
|
||||
{
|
||||
namespace parallel
|
||||
{
|
||||
inline namespace v2
|
||||
{
|
||||
|
||||
class task_canceled_exception: public std::exception
|
||||
{
|
||||
public:
|
||||
task_canceled_exception() noexcept;
|
||||
task_canceled_exception(const task_canceled_exception&) noexcept;
|
||||
task_canceled_exception& operator=(const task_canceled_exception&) noexcept;
|
||||
virtual const char* what() const noexcept;
|
||||
};
|
||||
|
||||
} // v2
|
||||
} // parallel
|
||||
} // experimental
|
||||
} // boost
|
||||
|
||||
[endsect] [/ task_canceled_exception]
|
||||
[////////////////////////////////////////////////////////////////////]
|
||||
[section:task_region_handle_gen Template Class `task_region_handle_gen<>`]
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace experimental
|
||||
{
|
||||
namespace parallel
|
||||
{
|
||||
inline namespace v2
|
||||
{
|
||||
|
||||
template <class Executor>
|
||||
class task_region_handle_gen
|
||||
{
|
||||
protected:
|
||||
task_region_handle_gen(Executor& ex);
|
||||
|
||||
~task_region_handle_gen();
|
||||
|
||||
public:
|
||||
task_region_handle_gen(const task_region_handle_gen&) = delete;
|
||||
task_region_handle_gen& operator=(const task_region_handle_gen&) = delete;
|
||||
task_region_handle_gen* operator&() const = delete;
|
||||
|
||||
template<typename F>
|
||||
void run(F&& f);
|
||||
|
||||
void wait();
|
||||
};
|
||||
|
||||
} // v2
|
||||
} // parallel
|
||||
} // experimental
|
||||
} // boost
|
||||
|
||||
[endsect] [/ task_region_handle_gen]
|
||||
[////////////////////////////////////////////////////////////////////]
|
||||
[section:default_executor Class `default_executor `]
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace experimental
|
||||
{
|
||||
namespace parallel
|
||||
{
|
||||
inline namespace v2
|
||||
{
|
||||
|
||||
using default_executor = 'implementation defined';
|
||||
|
||||
} // v2
|
||||
} // parallel
|
||||
} // experimental
|
||||
} // boost
|
||||
|
||||
[endsect] [/ default_executor]
|
||||
[////////////////////////////////////////////////////////////////////]
|
||||
[section:task_region_handle Class `task_region_handle `]
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace experimental
|
||||
{
|
||||
namespace parallel
|
||||
{
|
||||
inline namespace v2
|
||||
{
|
||||
|
||||
class task_region_handle :
|
||||
public task_region_handle_gen<default_executor>
|
||||
{
|
||||
protected:
|
||||
task_region_handle();
|
||||
task_region_handle(const task_region_handle&) = delete;
|
||||
task_region_handle& operator=(const task_region_handle&) = delete;
|
||||
task_region_handle* operator&() const = delete;
|
||||
|
||||
};
|
||||
|
||||
} // v2
|
||||
} // parallel
|
||||
} // experimental
|
||||
} // boost
|
||||
|
||||
[endsect] [/ task_region_handle]
|
||||
[////////////////////////////////////////////////////////////////////]
|
||||
[section:task_region_final Template Function `task_region_final `]
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace experimental
|
||||
{
|
||||
namespace parallel
|
||||
{
|
||||
inline namespace v2
|
||||
{
|
||||
|
||||
template <typename Executor, typename F>
|
||||
void task_region_final(Executor& ex, F&& f);
|
||||
template <typename F>
|
||||
void task_region_final(F&& f);
|
||||
|
||||
} // v2
|
||||
} // parallel
|
||||
} // experimental
|
||||
} // boost
|
||||
|
||||
[endsect] [/ task_region_final]
|
||||
[////////////////////////////////////////////////////////////////////]
|
||||
[section:task_region Template Function `task_region `]
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace experimental
|
||||
{
|
||||
namespace parallel
|
||||
{
|
||||
inline namespace v2
|
||||
{
|
||||
|
||||
template <typename Executor, typename F>
|
||||
void task_region(Executor& ex, F&& f);
|
||||
template <typename F>
|
||||
void task_region(F&& f);
|
||||
|
||||
} // v2
|
||||
} // parallel
|
||||
} // experimental
|
||||
} // boost
|
||||
|
||||
[endsect] [/ task_region]
|
||||
|
||||
|
||||
|
||||
|
||||
[endsect] [/ task_region.hpp]
|
||||
[endsect] [/ Parallel V2]
|
||||
[endsect] [/ Reference]
|
||||
|
||||
[endsect] [/ Parallel]
|
||||
@@ -244,7 +244,6 @@
|
||||
[include futures.qbk]
|
||||
[endsect]
|
||||
|
||||
|
||||
[include tss.qbk]
|
||||
|
||||
[section:sds Synchronized Data Structures]
|
||||
@@ -253,6 +252,8 @@
|
||||
[/include sync_streams.qbk]
|
||||
[endsect]
|
||||
|
||||
[include parallel.qbk]
|
||||
|
||||
[include time.qbk]
|
||||
|
||||
[include emulations.qbk]
|
||||
|
||||
@@ -125,7 +125,7 @@ the user to set the platform specific attributes. Boost.Thread stay in the middl
|
||||
thread::attributes which allows to set at least in a portable way the stack size as follows:
|
||||
|
||||
boost::thread::attributes attrs;
|
||||
attrs.set_size(4096*10);
|
||||
attrs.set_stack_size(4096*10);
|
||||
boost::thread deep_thought_2(attrs, find_the_question, 42);
|
||||
|
||||
Even for this simple attribute there could be portable issues as some platforms could require that the stack size
|
||||
@@ -147,7 +147,7 @@ Next follows how the user could set the stack size and the scheduling policy on
|
||||
// ... window version
|
||||
#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
|
||||
// ... pthread version
|
||||
pthread_attr_setschedpolicy(attr.get_native_handle(), SCHED_RR);
|
||||
pthread_attr_setschedpolicy(attr.native_handle(), SCHED_RR);
|
||||
#else
|
||||
#error "Boost threads unavailable on this platform"
|
||||
#endif
|
||||
|
||||
91
example/fib_task_region.cpp
Normal file
91
example/fib_task_region.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
// Copyright (C) 2012 Vicente Botet
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if ! defined BOOST_NO_CXX11_DECLTYPE
|
||||
#define BOOST_RESULT_OF_USE_DECLTYPE
|
||||
#endif
|
||||
|
||||
#define BOOST_THREAD_VERSION 4
|
||||
#define BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
|
||||
#include <boost/thread/experimental/task_region.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#if ! defined BOOST_NO_CXX11_RANGE_BASED_FOR && ! defined BOOST_NO_CXX11_LAMBDAS
|
||||
|
||||
int fib_task_region(int n)
|
||||
{
|
||||
using boost::experimental::parallel::task_region;
|
||||
using boost::experimental::parallel::task_region_handle;
|
||||
|
||||
if (n == 0) return 0;
|
||||
if (n == 1) return 1;
|
||||
|
||||
int n1;
|
||||
int n2;
|
||||
|
||||
task_region([&](task_region_handle& trh)
|
||||
{
|
||||
trh.run([&]
|
||||
{
|
||||
n1 = fib_task_region(n - 1);
|
||||
});
|
||||
|
||||
n2 = fib_task_region(n - 2);
|
||||
});
|
||||
|
||||
return n1 + n2;
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
template <class Ex>
|
||||
int fib_task_region_gen( Ex& ex, int n)
|
||||
{
|
||||
using boost::experimental::parallel::task_region;
|
||||
using boost::experimental::parallel::task_region_handle_gen;
|
||||
|
||||
if (n == 0) return 0;
|
||||
if (n == 1) return 1;
|
||||
|
||||
int n1;
|
||||
int n2;
|
||||
|
||||
task_region(ex, [&](task_region_handle_gen<Ex>& trh)
|
||||
{
|
||||
trh.run([&]
|
||||
{
|
||||
n1 = fib_task_region(n - 1);
|
||||
});
|
||||
|
||||
n2 = fib_task_region(n - 2);
|
||||
});
|
||||
|
||||
return n1 + n2;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
for (int i = 0; i<10; ++i) {
|
||||
std::cout << fib_task_region(i) << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
boost::basic_thread_pool tp;
|
||||
for (int i = 0; i<10; ++i) {
|
||||
std::cout << fib_task_region_gen(tp,i) << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -22,7 +22,7 @@
|
||||
typedef std::ostream the_ostream;
|
||||
typedef std::istream the_istream;
|
||||
#endif
|
||||
#include <boost/thread/sync_queue.hpp>
|
||||
#include <boost/thread/concurrent_queues/sync_queue.hpp>
|
||||
|
||||
void producer(the_ostream &mos, boost::sync_queue<int> & sbq)
|
||||
{
|
||||
@@ -30,9 +30,9 @@ void producer(the_ostream &mos, boost::sync_queue<int> & sbq)
|
||||
try {
|
||||
for(int i=0; ;++i)
|
||||
{
|
||||
sbq.push_back(i);
|
||||
sbq.push(i);
|
||||
//sbq << i;
|
||||
mos << "push_back(" << i << ") "<< sbq.size()<<"\n";
|
||||
mos << "push(" << i << ") "<< sbq.size()<<"\n";
|
||||
this_thread::sleep_for(chrono::milliseconds(200));
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ void consumer(
|
||||
for(int i=0; ;++i)
|
||||
{
|
||||
int r;
|
||||
sbq.pull_front(r);
|
||||
sbq.pull(r);
|
||||
//sbq >> r;
|
||||
mos << i << " pull(" << r << ") "<< sbq.size()<<"\n";
|
||||
|
||||
@@ -78,7 +78,7 @@ void consumer2(the_ostream &mos, boost::sync_queue<int> & sbq)
|
||||
for(int i=0; ;++i)
|
||||
{
|
||||
int r;
|
||||
queue_op_status st = sbq.try_pull_front(r);
|
||||
queue_op_status st = sbq.try_pull(r);
|
||||
if (queue_op_status::closed == st) break;
|
||||
if (queue_op_status::success == st) {
|
||||
mos << i << " pull(" << r << ")\n";
|
||||
@@ -98,9 +98,9 @@ void consumer3(the_ostream &mos, boost::sync_queue<int> & sbq)
|
||||
for(int i=0; ;++i)
|
||||
{
|
||||
int r;
|
||||
queue_op_status res = sbq.wait_pull_front(r);
|
||||
queue_op_status res = sbq.wait_pull(r);
|
||||
if (res==queue_op_status::closed) break;
|
||||
mos << i << " wait_pull_front(" << r << ")\n";
|
||||
mos << i << " wait_pull(" << r << ")\n";
|
||||
this_thread::sleep_for(chrono::milliseconds(250));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
typedef std::ostream the_ostream;
|
||||
typedef std::istream the_istream;
|
||||
#endif
|
||||
#include <boost/thread/sync_queue.hpp>
|
||||
#include <boost/thread/concurrent_queues/sync_queue.hpp>
|
||||
#include <boost/thread/concurrent_queues/queue_adaptor.hpp>
|
||||
#include <boost/thread/concurrent_queues/queue_views.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
209
include/boost/thread/concurrent_queues/deque_adaptor.hpp
Normal file
209
include/boost/thread/concurrent_queues/deque_adaptor.hpp
Normal file
@@ -0,0 +1,209 @@
|
||||
#ifndef BOOST_THREAD_CONCURRENT_DEQUE_ADAPTOR_HPP
|
||||
#define BOOST_THREAD_CONCURRENT_DEQUE_ADAPTOR_HPP
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Vicente J. Botet Escriba 2014. 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/thread for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/thread/detail/move.hpp>
|
||||
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
|
||||
#include <boost/thread/concurrent_queues/deque_base.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace concurrent
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename Queue>
|
||||
class deque_adaptor_copyable_only :
|
||||
public boost::deque_base<typename Queue::value_type>
|
||||
{
|
||||
Queue queue;
|
||||
public:
|
||||
typedef typename Queue::value_type value_type;
|
||||
typedef std::size_t size_type;
|
||||
|
||||
// Constructors/Assignment/Destructors
|
||||
deque_adaptor_copyable_only() {}
|
||||
|
||||
// Observers
|
||||
bool empty() const { return queue.empty(); }
|
||||
bool full() const { return queue.full(); }
|
||||
size_type size() const { return queue.size(); }
|
||||
bool closed() const { return queue.closed(); }
|
||||
|
||||
// Modifiers
|
||||
void close() { queue.close(); }
|
||||
|
||||
void push_back(const value_type& x) { queue.push_back(x); }
|
||||
|
||||
void pull_front(value_type& x) { queue.pull_front(x); };
|
||||
value_type pull_front() { return queue.pull_front(); }
|
||||
|
||||
queue_op_status try_push_back(const value_type& x) { return queue.try_push_back(x); }
|
||||
queue_op_status try_pull_front(value_type& x) { return queue.try_pull_front(x); }
|
||||
|
||||
queue_op_status nonblocking_push_back(const value_type& x) { return queue.nonblocking_push_back(x); }
|
||||
queue_op_status nonblocking_pull_front(value_type& x) { return queue.nonblocking_pull_front(x); }
|
||||
|
||||
queue_op_status wait_push_back(const value_type& x) { return queue.wait_push_back(x); }
|
||||
queue_op_status wait_pull_front(value_type& x) { return queue.wait_pull_front(x); }
|
||||
|
||||
};
|
||||
template <typename Queue>
|
||||
class deque_adaptor_movable_only :
|
||||
public boost::deque_base<typename Queue::value_type>
|
||||
{
|
||||
Queue queue;
|
||||
public:
|
||||
typedef typename Queue::value_type value_type;
|
||||
typedef std::size_t size_type;
|
||||
|
||||
// Constructors/Assignment/Destructors
|
||||
|
||||
deque_adaptor_movable_only() {}
|
||||
|
||||
// Observers
|
||||
bool empty() const { return queue.empty(); }
|
||||
bool full() const { return queue.full(); }
|
||||
size_type size() const { return queue.size(); }
|
||||
bool closed() const { return queue.closed(); }
|
||||
|
||||
// Modifiers
|
||||
void close() { queue.close(); }
|
||||
|
||||
|
||||
void pull_front(value_type& x) { queue.pull_front(x); };
|
||||
// enable_if is_nothrow_copy_movable<value_type>
|
||||
value_type pull_front() { return queue.pull_front(); }
|
||||
|
||||
queue_op_status try_pull_front(value_type& x) { return queue.try_pull_front(x); }
|
||||
|
||||
queue_op_status nonblocking_pull_front(value_type& x) { return queue.nonblocking_pull_front(x); }
|
||||
|
||||
queue_op_status wait_pull_front(value_type& x) { return queue.wait_pull_front(x); }
|
||||
|
||||
void push_back(BOOST_THREAD_RV_REF(value_type) x) { queue.push_back(boost::move(x)); }
|
||||
queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.try_push_back(boost::move(x)); }
|
||||
queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.nonblocking_push_back(boost::move(x)); }
|
||||
queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.wait_push_back(boost::move(x)); }
|
||||
};
|
||||
|
||||
template <typename Queue>
|
||||
class deque_adaptor_copyable_and_movable :
|
||||
public boost::deque_base<typename Queue::value_type>
|
||||
{
|
||||
Queue queue;
|
||||
public:
|
||||
typedef typename Queue::value_type value_type;
|
||||
typedef std::size_t size_type;
|
||||
|
||||
// Constructors/Assignment/Destructors
|
||||
|
||||
deque_adaptor_copyable_and_movable() {}
|
||||
|
||||
// Observers
|
||||
bool empty() const { return queue.empty(); }
|
||||
bool full() const { return queue.full(); }
|
||||
size_type size() const { return queue.size(); }
|
||||
bool closed() const { return queue.closed(); }
|
||||
|
||||
// Modifiers
|
||||
void close() { queue.close(); }
|
||||
|
||||
|
||||
void push_back(const value_type& x) { queue.push_back(x); }
|
||||
|
||||
void pull_front(value_type& x) { queue.pull_front(x); };
|
||||
// enable_if is_nothrow_copy_movable<value_type>
|
||||
value_type pull_front() { return queue.pull_front(); }
|
||||
|
||||
queue_op_status try_push_back(const value_type& x) { return queue.try_push_back(x); }
|
||||
queue_op_status try_pull_front(value_type& x) { return queue.try_pull_front(x); }
|
||||
|
||||
queue_op_status nonblocking_push_back(const value_type& x) { return queue.nonblocking_push_back(x); }
|
||||
queue_op_status nonblocking_pull_front(value_type& x) { return queue.nonblocking_pull_front(x); }
|
||||
|
||||
queue_op_status wait_push_back(const value_type& x) { return queue.wait_push_back(x); }
|
||||
queue_op_status wait_pull_front(value_type& x) { return queue.wait_pull_front(x); }
|
||||
|
||||
void push_back(BOOST_THREAD_RV_REF(value_type) x) { queue.push_back(boost::move(x)); }
|
||||
queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.try_push_back(boost::move(x)); }
|
||||
queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.nonblocking_push_back(boost::move(x)); }
|
||||
queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.wait_push_back(boost::move(x)); }
|
||||
};
|
||||
|
||||
|
||||
template <class Q, class T,
|
||||
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#if defined __GNUC__ && ! defined __clang__
|
||||
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
bool Copyable = is_copy_constructible<T>::value,
|
||||
bool Movable = true
|
||||
#else
|
||||
bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
|
||||
bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
|
||||
#endif // __GNUC__
|
||||
#elif defined _MSC_VER
|
||||
#if _MSC_VER < 1700
|
||||
bool Copyable = is_copy_constructible<T>::value,
|
||||
bool Movable = true
|
||||
#else
|
||||
bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
|
||||
bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
|
||||
#endif // _MSC_VER
|
||||
#else
|
||||
bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
|
||||
bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
|
||||
#endif
|
||||
#else
|
||||
bool Copyable = is_copy_constructible<T>::value,
|
||||
bool Movable = has_move_emulation_enabled<T>::value
|
||||
#endif
|
||||
>
|
||||
struct deque_adaptor;
|
||||
|
||||
template <class Q, class T>
|
||||
struct deque_adaptor<Q, T, true, true> {
|
||||
typedef deque_adaptor_copyable_and_movable<Q> type;
|
||||
};
|
||||
template <class Q, class T>
|
||||
struct deque_adaptor<Q, T, true, false> {
|
||||
typedef deque_adaptor_copyable_only<Q> type;
|
||||
};
|
||||
template <class Q, class T>
|
||||
struct deque_adaptor<Q, T, false, true> {
|
||||
typedef deque_adaptor_movable_only<Q> type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <typename Queue>
|
||||
class deque_adaptor :
|
||||
public detail::deque_adaptor<Queue, typename Queue::value_type>::type
|
||||
{
|
||||
public:
|
||||
typedef typename Queue::value_type value_type;
|
||||
typedef std::size_t size_type;
|
||||
// Constructors/Assignment/Destructors
|
||||
virtual ~deque_adaptor() {};
|
||||
};
|
||||
}
|
||||
using concurrent::deque_adaptor;
|
||||
|
||||
}
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
#endif
|
||||
202
include/boost/thread/concurrent_queues/deque_base.hpp
Normal file
202
include/boost/thread/concurrent_queues/deque_base.hpp
Normal file
@@ -0,0 +1,202 @@
|
||||
#ifndef BOOST_THREAD_CONCURRENT_DEQUE_BASE_HPP
|
||||
#define BOOST_THREAD_CONCURRENT_DEQUE_BASE_HPP
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Vicente J. Botet Escriba 2014. 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/thread for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/thread/detail/move.hpp>
|
||||
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
|
||||
#include <boost/type_traits/conditional.hpp>
|
||||
#include <boost/type_traits/is_copy_constructible.hpp>
|
||||
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace concurrent
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename ValueType>
|
||||
class deque_base_copyable_only
|
||||
{
|
||||
public:
|
||||
typedef ValueType value_type;
|
||||
typedef std::size_t size_type;
|
||||
|
||||
// Constructors/Assignment/Destructors
|
||||
virtual ~deque_base_copyable_only() {};
|
||||
|
||||
// Observers
|
||||
virtual bool empty() const = 0;
|
||||
virtual bool full() const = 0;
|
||||
virtual size_type size() const = 0;
|
||||
virtual bool closed() const = 0;
|
||||
|
||||
// Modifiers
|
||||
virtual void close() = 0;
|
||||
|
||||
virtual void push_back(const value_type& x) = 0;
|
||||
|
||||
virtual void pull_front(value_type&) = 0;
|
||||
virtual value_type pull_front() = 0;
|
||||
|
||||
virtual queue_op_status try_push_back(const value_type& x) = 0;
|
||||
virtual queue_op_status try_pull_front(value_type&) = 0;
|
||||
|
||||
virtual queue_op_status nonblocking_push_back(const value_type& x) = 0;
|
||||
virtual queue_op_status nonblocking_pull_front(value_type&) = 0;
|
||||
|
||||
virtual queue_op_status wait_push_back(const value_type& x) = 0;
|
||||
virtual queue_op_status wait_pull_front(ValueType& elem) = 0;
|
||||
|
||||
};
|
||||
|
||||
template <typename ValueType>
|
||||
class deque_base_movable_only
|
||||
{
|
||||
public:
|
||||
typedef ValueType value_type;
|
||||
typedef std::size_t size_type;
|
||||
// Constructors/Assignment/Destructors
|
||||
virtual ~deque_base_movable_only() {};
|
||||
|
||||
// Observers
|
||||
virtual bool empty() const = 0;
|
||||
virtual bool full() const = 0;
|
||||
virtual size_type size() const = 0;
|
||||
virtual bool closed() const = 0;
|
||||
|
||||
// Modifiers
|
||||
virtual void close() = 0;
|
||||
|
||||
virtual void pull_front(value_type&) = 0;
|
||||
// enable_if is_nothrow_movable<value_type>
|
||||
virtual value_type pull_front() = 0;
|
||||
|
||||
virtual queue_op_status try_pull_front(value_type&) = 0;
|
||||
|
||||
virtual queue_op_status nonblocking_pull_front(value_type&) = 0;
|
||||
|
||||
virtual queue_op_status wait_pull_front(ValueType& elem) = 0;
|
||||
|
||||
virtual void push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
virtual queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
virtual queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
virtual queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
};
|
||||
|
||||
|
||||
template <typename ValueType>
|
||||
class deque_base_copyable_and_movable
|
||||
{
|
||||
public:
|
||||
typedef ValueType value_type;
|
||||
typedef std::size_t size_type;
|
||||
// Constructors/Assignment/Destructors
|
||||
virtual ~deque_base_copyable_and_movable() {};
|
||||
|
||||
|
||||
// Observers
|
||||
virtual bool empty() const = 0;
|
||||
virtual bool full() const = 0;
|
||||
virtual size_type size() const = 0;
|
||||
virtual bool closed() const = 0;
|
||||
|
||||
// Modifiers
|
||||
virtual void close() = 0;
|
||||
|
||||
virtual void push_back(const value_type& x) = 0;
|
||||
|
||||
virtual void pull_front(value_type&) = 0;
|
||||
// enable_if is_nothrow_copy_movable<value_type>
|
||||
virtual value_type pull_front() = 0;
|
||||
|
||||
virtual queue_op_status try_push_back(const value_type& x) = 0;
|
||||
virtual queue_op_status try_pull_front(value_type&) = 0;
|
||||
|
||||
virtual queue_op_status nonblocking_push_back(const value_type& x) = 0;
|
||||
virtual queue_op_status nonblocking_pull_front(value_type&) = 0;
|
||||
|
||||
virtual queue_op_status wait_push_back(const value_type& x) = 0;
|
||||
virtual queue_op_status wait_pull_front(ValueType& elem) = 0;
|
||||
|
||||
virtual void push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
virtual queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
virtual queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
virtual queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
};
|
||||
|
||||
template <class T,
|
||||
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#if defined __GNUC__ && ! defined __clang__
|
||||
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
bool Copyable = is_copy_constructible<T>::value,
|
||||
bool Movable = true
|
||||
#else
|
||||
bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
|
||||
bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
|
||||
#endif // __GNUC__
|
||||
#elif defined _MSC_VER
|
||||
#if _MSC_VER < 1700
|
||||
bool Copyable = is_copy_constructible<T>::value,
|
||||
bool Movable = true
|
||||
#else
|
||||
bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
|
||||
bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
|
||||
#endif // _MSC_VER
|
||||
#else
|
||||
bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
|
||||
bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
|
||||
#endif
|
||||
#else
|
||||
bool Copyable = is_copy_constructible<T>::value,
|
||||
bool Movable = has_move_emulation_enabled<T>::value
|
||||
#endif
|
||||
>
|
||||
struct deque_base;
|
||||
|
||||
template <class T>
|
||||
struct deque_base<T, true, true> {
|
||||
typedef deque_base_copyable_and_movable<T> type;
|
||||
};
|
||||
template <class T>
|
||||
struct deque_base<T, true, false> {
|
||||
typedef deque_base_copyable_only<T> type;
|
||||
};
|
||||
template <class T>
|
||||
struct deque_base<T, false, true> {
|
||||
typedef deque_base_movable_only<T> type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
class deque_base :
|
||||
public detail::deque_base<ValueType>::type
|
||||
{
|
||||
public:
|
||||
typedef ValueType value_type;
|
||||
typedef std::size_t size_type;
|
||||
// Constructors/Assignment/Destructors
|
||||
virtual ~deque_base() {};
|
||||
};
|
||||
|
||||
}
|
||||
using concurrent::deque_base;
|
||||
|
||||
}
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
#endif
|
||||
165
include/boost/thread/concurrent_queues/deque_views.hpp
Normal file
165
include/boost/thread/concurrent_queues/deque_views.hpp
Normal file
@@ -0,0 +1,165 @@
|
||||
#ifndef BOOST_THREAD_QUEUE_VIEWS_HPP
|
||||
#define BOOST_THREAD_QUEUE_VIEWS_HPP
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Vicente J. Botet Escriba 2014. 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/thread for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/thread/detail/move.hpp>
|
||||
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
|
||||
#include <boost/thread/concurrent_queues/deque_base.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace concurrent
|
||||
{
|
||||
|
||||
template <typename Queue>
|
||||
class deque_back_view
|
||||
{
|
||||
Queue* queue;
|
||||
public:
|
||||
typedef typename Queue::value_type value_type;
|
||||
typedef typename Queue::size_type size_type;
|
||||
|
||||
// Constructors/Assignment/Destructors
|
||||
deque_back_view(Queue& q) BOOST_NOEXCEPT : queue(&q) {}
|
||||
|
||||
// Observers
|
||||
bool empty() const { return queue->empty(); }
|
||||
bool full() const { return queue->full(); }
|
||||
size_type size() const { return queue->size(); }
|
||||
bool closed() const { return queue->closed(); }
|
||||
|
||||
// Modifiers
|
||||
void close() { queue->close(); }
|
||||
|
||||
void push(const value_type& x) { queue->push_back(x); }
|
||||
|
||||
void pull(value_type& x) { queue->pull_back(x); }
|
||||
// enable_if is_nothrow_copy_movable<value_type>
|
||||
value_type pull() { return queue->pull_back(); }
|
||||
|
||||
queue_op_status try_push(const value_type& x) { return queue->try_push_back(x); }
|
||||
|
||||
queue_op_status try_pull(value_type& x) { return queue->try_pull_back(x); }
|
||||
|
||||
queue_op_status nonblocking_push(const value_type& x) { return queue->nonblocking_push_back(x); }
|
||||
|
||||
queue_op_status nonblocking_pull(value_type& x) { return queue->nonblocking_pull_back(x); }
|
||||
|
||||
queue_op_status wait_push(const value_type& x) { return queue->wait_push_back(x); }
|
||||
queue_op_status wait_pull(value_type& x) { return queue->wait_pull_back(x); }
|
||||
|
||||
void push(BOOST_THREAD_RV_REF(value_type) x) { queue->push_back(boost::move(x)); }
|
||||
queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->try_push_back(boost::move(x)); }
|
||||
queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->nonblocking_push_back(boost::move(x)); }
|
||||
queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->wait_push_back(boost::move(x)); }
|
||||
};
|
||||
|
||||
template <typename Queue>
|
||||
class deque_front_view
|
||||
{
|
||||
Queue* queue;
|
||||
public:
|
||||
typedef typename Queue::value_type value_type;
|
||||
typedef typename Queue::size_type size_type;
|
||||
|
||||
// Constructors/Assignment/Destructors
|
||||
deque_front_view(Queue& q) BOOST_NOEXCEPT : queue(&q) {}
|
||||
|
||||
// Observers
|
||||
bool empty() const { return queue->empty(); }
|
||||
bool full() const { return queue->full(); }
|
||||
size_type size() const { return queue->size(); }
|
||||
bool closed() const { return queue->closed(); }
|
||||
|
||||
// Modifiers
|
||||
void close() { queue->close(); }
|
||||
|
||||
void push(const value_type& x) { queue->push_front(x); }
|
||||
|
||||
void pull(value_type& x) { queue->pull_front(x); };
|
||||
// enable_if is_nothrow_copy_movable<value_type>
|
||||
value_type pull() { return queue->pull_front(); }
|
||||
|
||||
queue_op_status try_push(const value_type& x) { return queue->try_push_front(x); }
|
||||
|
||||
queue_op_status try_pull(value_type& x) { return queue->try_pull_front(x); }
|
||||
|
||||
queue_op_status nonblocking_push(const value_type& x) { return queue->nonblocking_push_front(x); }
|
||||
|
||||
queue_op_status nonblocking_pull(value_type& x) { return queue->nonblocking_pull_front(x); }
|
||||
|
||||
queue_op_status wait_push(const value_type& x) { return queue->wait_push_front(x); }
|
||||
queue_op_status wait_pull(value_type& x) { return queue->wait_pull_front(x); }
|
||||
void push(BOOST_THREAD_RV_REF(value_type) x) { queue->push_front(forward<value_type>(x)); }
|
||||
queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->try_push_front(forward<value_type>(x)); }
|
||||
queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->nonblocking_push_front(forward<value_type>(x)); }
|
||||
queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->wait_push_front(forward<value_type>(x)); }
|
||||
|
||||
};
|
||||
|
||||
#if ! defined BOOST_NO_CXX11_TEMPLATE_ALIASES
|
||||
|
||||
template <class T>
|
||||
using deque_back = deque_back_view<deque_base<T> > ;
|
||||
template <class T>
|
||||
using deque_front = deque_front_view<deque_base<T> > ;
|
||||
|
||||
#else
|
||||
|
||||
template <class T>
|
||||
struct deque_back : deque_back_view<deque_base<T> >
|
||||
{
|
||||
typedef deque_back_view<deque_base<T> > base_type;
|
||||
deque_back(deque_base<T>& q) BOOST_NOEXCEPT : base_type(q) {}
|
||||
};
|
||||
template <class T>
|
||||
struct deque_front : deque_front_view<deque_base<T> >
|
||||
{
|
||||
typedef deque_front_view<deque_base<T> > base_type;
|
||||
deque_front(deque_base<T>& q) BOOST_NOEXCEPT : base_type(q) {}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// template <class Queue>
|
||||
// deque_back_view<Queue> back(Queue & q) { return deque_back_view<Queue>(q); }
|
||||
// template <class Queue>
|
||||
// deque_front_view<Queue> front(Queue & q) { return deque_front_view<Queue>(q); }
|
||||
//#if 0
|
||||
// template <class T>
|
||||
// deque_back<T> back(deque_base<T> & q) { return deque_back<T>(q); }
|
||||
// template <class T>
|
||||
// deque_front<T> front(deque_base<T> & q) { return deque_front<T>(q); }
|
||||
//#else
|
||||
// template <class T>
|
||||
// typename deque_back<T>::type back(deque_base<T> & q) { return typename deque_back<T>::type(q); }
|
||||
// template <class T>
|
||||
// typename deque_front<T>::type front(deque_base<T> & q) { return typename deque_front<T>::type(q); }
|
||||
//#endif
|
||||
}
|
||||
|
||||
using concurrent::deque_back_view;
|
||||
using concurrent::deque_front_view;
|
||||
using concurrent::deque_back;
|
||||
using concurrent::deque_front;
|
||||
//using concurrent::back;
|
||||
//using concurrent::front;
|
||||
|
||||
}
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,223 @@
|
||||
#ifndef BOOST_THREAD_CONCURRENT_QUEUES_DETAIL_SYNC_DEQUE_BASE_HPP
|
||||
#define BOOST_THREAD_CONCURRENT_QUEUES_DETAIL_SYNC_DEQUE_BASE_HPP
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Vicente J. Botet Escriba 2013-2014. 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/thread for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
#include <boost/thread/detail/move.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
|
||||
|
||||
#include <boost/chrono/duration.hpp>
|
||||
#include <boost/chrono/time_point.hpp>
|
||||
#include <boost/chrono/system_clocks.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace concurrent
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <class ValueType, class Queue>
|
||||
class sync_deque_base
|
||||
{
|
||||
public:
|
||||
typedef ValueType value_type;
|
||||
typedef Queue underlying_queue_type;
|
||||
typedef std::size_t size_type;
|
||||
typedef queue_op_status op_status;
|
||||
|
||||
typedef typename chrono::steady_clock clock;
|
||||
typedef typename clock::duration duration;
|
||||
typedef typename clock::time_point time_point;
|
||||
|
||||
// Constructors/Assignment/Destructors
|
||||
BOOST_THREAD_NO_COPYABLE(sync_deque_base)
|
||||
inline sync_deque_base();
|
||||
//template <typename Range>
|
||||
//inline explicit sync_deque(Range range);
|
||||
inline ~sync_deque_base();
|
||||
|
||||
// Observers
|
||||
inline bool empty() const;
|
||||
inline bool full() const;
|
||||
inline size_type size() const;
|
||||
inline bool closed() const;
|
||||
|
||||
// Modifiers
|
||||
inline void close();
|
||||
|
||||
inline underlying_queue_type underlying_queue() {
|
||||
lock_guard<mutex> lk(mtx_);
|
||||
return boost::move(data_);
|
||||
}
|
||||
|
||||
protected:
|
||||
mutable mutex mtx_;
|
||||
condition_variable not_empty_;
|
||||
underlying_queue_type data_;
|
||||
bool closed_;
|
||||
|
||||
inline bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return data_.empty();
|
||||
}
|
||||
inline bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return data_.empty();
|
||||
}
|
||||
|
||||
inline size_type size(lock_guard<mutex>& ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return data_.size();
|
||||
}
|
||||
inline bool closed(unique_lock<mutex>& lk) const;
|
||||
inline bool closed(lock_guard<mutex>& lk) const;
|
||||
|
||||
inline void throw_if_closed(unique_lock<mutex>&);
|
||||
inline void throw_if_closed(lock_guard<mutex>&);
|
||||
|
||||
inline void wait_until_not_empty(unique_lock<mutex>& lk);
|
||||
inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk);
|
||||
inline queue_op_status wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&);
|
||||
|
||||
inline void notify_not_empty_if_needed(unique_lock<mutex>& )
|
||||
{
|
||||
not_empty_.notify_one();
|
||||
}
|
||||
inline void notify_not_empty_if_needed(lock_guard<mutex>& )
|
||||
{
|
||||
not_empty_.notify_one();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <class ValueType, class Queue>
|
||||
sync_deque_base<ValueType, Queue>::sync_deque_base() :
|
||||
data_(), closed_(false)
|
||||
{
|
||||
BOOST_ASSERT(data_.empty());
|
||||
}
|
||||
|
||||
template <class ValueType, class Queue>
|
||||
sync_deque_base<ValueType, Queue>::~sync_deque_base()
|
||||
{
|
||||
}
|
||||
|
||||
template <class ValueType, class Queue>
|
||||
void sync_deque_base<ValueType, Queue>::close()
|
||||
{
|
||||
{
|
||||
lock_guard<mutex> lk(mtx_);
|
||||
closed_ = true;
|
||||
}
|
||||
not_empty_.notify_all();
|
||||
}
|
||||
|
||||
template <class ValueType, class Queue>
|
||||
bool sync_deque_base<ValueType, Queue>::closed() const
|
||||
{
|
||||
lock_guard<mutex> lk(mtx_);
|
||||
return closed(lk);
|
||||
}
|
||||
template <class ValueType, class Queue>
|
||||
bool sync_deque_base<ValueType, Queue>::closed(unique_lock<mutex>&) const
|
||||
{
|
||||
return closed_;
|
||||
}
|
||||
template <class ValueType, class Queue>
|
||||
bool sync_deque_base<ValueType, Queue>::closed(lock_guard<mutex>&) const
|
||||
{
|
||||
return closed_;
|
||||
}
|
||||
|
||||
template <class ValueType, class Queue>
|
||||
bool sync_deque_base<ValueType, Queue>::empty() const
|
||||
{
|
||||
lock_guard<mutex> lk(mtx_);
|
||||
return empty(lk);
|
||||
}
|
||||
template <class ValueType, class Queue>
|
||||
bool sync_deque_base<ValueType, Queue>::full() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class ValueType, class Queue>
|
||||
typename sync_deque_base<ValueType, Queue>::size_type sync_deque_base<ValueType, Queue>::size() const
|
||||
{
|
||||
lock_guard<mutex> lk(mtx_);
|
||||
return size(lk);
|
||||
}
|
||||
|
||||
template <class ValueType, class Queue>
|
||||
void sync_deque_base<ValueType, Queue>::throw_if_closed(unique_lock<mutex>& lk)
|
||||
{
|
||||
if (closed(lk))
|
||||
{
|
||||
BOOST_THROW_EXCEPTION( sync_deque_is_closed() );
|
||||
}
|
||||
}
|
||||
template <class ValueType, class Queue>
|
||||
void sync_deque_base<ValueType, Queue>::throw_if_closed(lock_guard<mutex>& lk)
|
||||
{
|
||||
if (closed(lk))
|
||||
{
|
||||
BOOST_THROW_EXCEPTION( sync_deque_is_closed() );
|
||||
}
|
||||
}
|
||||
|
||||
template <class ValueType, class Queue>
|
||||
void sync_deque_base<ValueType, Queue>::wait_until_not_empty(unique_lock<mutex>& lk)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (! empty(lk)) break;
|
||||
throw_if_closed(lk);
|
||||
not_empty_.wait(lk);
|
||||
}
|
||||
}
|
||||
template <class ValueType, class Queue>
|
||||
bool sync_deque_base<ValueType, Queue>::wait_until_not_empty_or_closed(unique_lock<mutex>& lk)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (! empty(lk)) break;
|
||||
if (closed(lk)) return true;
|
||||
not_empty_.wait(lk);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class ValueType, class Queue>
|
||||
queue_op_status sync_deque_base<ValueType, Queue>::wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&tp)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (! empty(lk)) return queue_op_status::success;
|
||||
throw_if_closed(lk);
|
||||
if (not_empty_.wait_until(lk, tp) == cv_status::timeout ) return queue_op_status::timeout;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // detail
|
||||
} // concurrent
|
||||
} // boost
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
#endif
|
||||
@@ -46,19 +46,19 @@ namespace detail
|
||||
// Modifiers
|
||||
void close() { queue.close(); }
|
||||
|
||||
void push_back(const value_type& x) { queue.push_back(x); }
|
||||
void push(const value_type& x) { queue.push(x); }
|
||||
|
||||
void pull_front(value_type& x) { queue.pull_front(x); };
|
||||
value_type pull_front() { return queue.pull_front(); }
|
||||
void pull(value_type& x) { queue.pull(x); };
|
||||
value_type pull() { return queue.pull(); }
|
||||
|
||||
queue_op_status try_push_back(const value_type& x) { return queue.try_push_back(x); }
|
||||
queue_op_status try_pull_front(value_type& x) { return queue.try_pull_front(x); }
|
||||
queue_op_status try_push(const value_type& x) { return queue.try_push(x); }
|
||||
queue_op_status try_pull(value_type& x) { return queue.try_pull(x); }
|
||||
|
||||
queue_op_status nonblocking_push_back(const value_type& x) { return queue.nonblocking_push_back(x); }
|
||||
queue_op_status nonblocking_pull_front(value_type& x) { return queue.nonblocking_pull_front(x); }
|
||||
queue_op_status nonblocking_push(const value_type& x) { return queue.nonblocking_push(x); }
|
||||
queue_op_status nonblocking_pull(value_type& x) { return queue.nonblocking_pull(x); }
|
||||
|
||||
queue_op_status wait_push_back(const value_type& x) { return queue.wait_push_back(x); }
|
||||
queue_op_status wait_pull_front(value_type& x) { return queue.wait_pull_front(x); }
|
||||
queue_op_status wait_push(const value_type& x) { return queue.wait_push(x); }
|
||||
queue_op_status wait_pull(value_type& x) { return queue.wait_pull(x); }
|
||||
|
||||
};
|
||||
template <typename Queue>
|
||||
@@ -84,20 +84,20 @@ namespace detail
|
||||
void close() { queue.close(); }
|
||||
|
||||
|
||||
void pull_front(value_type& x) { queue.pull_front(x); };
|
||||
void pull(value_type& x) { queue.pull(x); };
|
||||
// enable_if is_nothrow_copy_movable<value_type>
|
||||
value_type pull_front() { return queue.pull_front(); }
|
||||
value_type pull() { return queue.pull(); }
|
||||
|
||||
queue_op_status try_pull_front(value_type& x) { return queue.try_pull_front(x); }
|
||||
queue_op_status try_pull(value_type& x) { return queue.try_pull(x); }
|
||||
|
||||
queue_op_status nonblocking_pull_front(value_type& x) { return queue.nonblocking_pull_front(x); }
|
||||
queue_op_status nonblocking_pull(value_type& x) { return queue.nonblocking_pull(x); }
|
||||
|
||||
queue_op_status wait_pull_front(value_type& x) { return queue.wait_pull_front(x); }
|
||||
queue_op_status wait_pull(value_type& x) { return queue.wait_pull(x); }
|
||||
|
||||
void push_back(BOOST_THREAD_RV_REF(value_type) x) { queue.push_back(boost::move(x)); }
|
||||
queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.try_push_back(boost::move(x)); }
|
||||
queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.nonblocking_push_back(boost::move(x)); }
|
||||
queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.wait_push_back(boost::move(x)); }
|
||||
void push(BOOST_THREAD_RV_REF(value_type) x) { queue.push(boost::move(x)); }
|
||||
queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.try_push(boost::move(x)); }
|
||||
queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.nonblocking_push(boost::move(x)); }
|
||||
queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.wait_push(boost::move(x)); }
|
||||
};
|
||||
|
||||
template <typename Queue>
|
||||
@@ -123,31 +123,31 @@ namespace detail
|
||||
void close() { queue.close(); }
|
||||
|
||||
|
||||
void push_back(const value_type& x) { queue.push_back(x); }
|
||||
void push(const value_type& x) { queue.push(x); }
|
||||
|
||||
void pull_front(value_type& x) { queue.pull_front(x); };
|
||||
void pull(value_type& x) { queue.pull(x); };
|
||||
// enable_if is_nothrow_copy_movable<value_type>
|
||||
value_type pull_front() { return queue.pull_front(); }
|
||||
value_type pull() { return queue.pull(); }
|
||||
|
||||
queue_op_status try_push_back(const value_type& x) { return queue.try_push_back(x); }
|
||||
queue_op_status try_pull_front(value_type& x) { return queue.try_pull_front(x); }
|
||||
queue_op_status try_push(const value_type& x) { return queue.try_push(x); }
|
||||
queue_op_status try_pull(value_type& x) { return queue.try_pull(x); }
|
||||
|
||||
queue_op_status nonblocking_push_back(const value_type& x) { return queue.nonblocking_push_back(x); }
|
||||
queue_op_status nonblocking_pull_front(value_type& x) { return queue.nonblocking_pull_front(x); }
|
||||
queue_op_status nonblocking_push(const value_type& x) { return queue.nonblocking_push(x); }
|
||||
queue_op_status nonblocking_pull(value_type& x) { return queue.nonblocking_pull(x); }
|
||||
|
||||
queue_op_status wait_push_back(const value_type& x) { return queue.wait_push_back(x); }
|
||||
queue_op_status wait_pull_front(value_type& x) { return queue.wait_pull_front(x); }
|
||||
queue_op_status wait_push(const value_type& x) { return queue.wait_push(x); }
|
||||
queue_op_status wait_pull(value_type& x) { return queue.wait_pull(x); }
|
||||
|
||||
void push_back(BOOST_THREAD_RV_REF(value_type) x) { queue.push_back(boost::move(x)); }
|
||||
queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.try_push_back(boost::move(x)); }
|
||||
queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.nonblocking_push_back(boost::move(x)); }
|
||||
queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.wait_push_back(boost::move(x)); }
|
||||
void push(BOOST_THREAD_RV_REF(value_type) x) { queue.push(boost::move(x)); }
|
||||
queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.try_push(boost::move(x)); }
|
||||
queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.nonblocking_push(boost::move(x)); }
|
||||
queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.wait_push(boost::move(x)); }
|
||||
};
|
||||
|
||||
|
||||
template <class Q, class T,
|
||||
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#if defined __GNUC__
|
||||
#if defined __GNUC__ && ! defined __clang__
|
||||
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
bool Copyable = is_copy_constructible<T>::value,
|
||||
bool Movable = true
|
||||
|
||||
@@ -46,19 +46,19 @@ namespace detail
|
||||
// Modifiers
|
||||
virtual void close() = 0;
|
||||
|
||||
virtual void push_back(const value_type& x) = 0;
|
||||
virtual void push(const value_type& x) = 0;
|
||||
|
||||
virtual void pull_front(value_type&) = 0;
|
||||
virtual value_type pull_front() = 0;
|
||||
virtual void pull(value_type&) = 0;
|
||||
virtual value_type pull() = 0;
|
||||
|
||||
virtual queue_op_status try_push_back(const value_type& x) = 0;
|
||||
virtual queue_op_status try_pull_front(value_type&) = 0;
|
||||
virtual queue_op_status try_push(const value_type& x) = 0;
|
||||
virtual queue_op_status try_pull(value_type&) = 0;
|
||||
|
||||
virtual queue_op_status nonblocking_push_back(const value_type& x) = 0;
|
||||
virtual queue_op_status nonblocking_pull_front(value_type&) = 0;
|
||||
virtual queue_op_status nonblocking_push(const value_type& x) = 0;
|
||||
virtual queue_op_status nonblocking_pull(value_type&) = 0;
|
||||
|
||||
virtual queue_op_status wait_push_back(const value_type& x) = 0;
|
||||
virtual queue_op_status wait_pull_front(ValueType& elem) = 0;
|
||||
virtual queue_op_status wait_push(const value_type& x) = 0;
|
||||
virtual queue_op_status wait_pull(ValueType& elem) = 0;
|
||||
|
||||
};
|
||||
|
||||
@@ -80,20 +80,20 @@ namespace detail
|
||||
// Modifiers
|
||||
virtual void close() = 0;
|
||||
|
||||
virtual void pull_front(value_type&) = 0;
|
||||
virtual void pull(value_type&) = 0;
|
||||
// enable_if is_nothrow_movable<value_type>
|
||||
virtual value_type pull_front() = 0;
|
||||
virtual value_type pull() = 0;
|
||||
|
||||
virtual queue_op_status try_pull_front(value_type&) = 0;
|
||||
virtual queue_op_status try_pull(value_type&) = 0;
|
||||
|
||||
virtual queue_op_status nonblocking_pull_front(value_type&) = 0;
|
||||
virtual queue_op_status nonblocking_pull(value_type&) = 0;
|
||||
|
||||
virtual queue_op_status wait_pull_front(ValueType& elem) = 0;
|
||||
virtual queue_op_status wait_pull(ValueType& elem) = 0;
|
||||
|
||||
virtual void push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
virtual queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
virtual queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
virtual queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
virtual void push(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
virtual queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
virtual queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
virtual queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -116,30 +116,30 @@ namespace detail
|
||||
// Modifiers
|
||||
virtual void close() = 0;
|
||||
|
||||
virtual void push_back(const value_type& x) = 0;
|
||||
virtual void push(const value_type& x) = 0;
|
||||
|
||||
virtual void pull_front(value_type&) = 0;
|
||||
virtual void pull(value_type&) = 0;
|
||||
// enable_if is_nothrow_copy_movable<value_type>
|
||||
virtual value_type pull_front() = 0;
|
||||
virtual value_type pull() = 0;
|
||||
|
||||
virtual queue_op_status try_push_back(const value_type& x) = 0;
|
||||
virtual queue_op_status try_pull_front(value_type&) = 0;
|
||||
virtual queue_op_status try_push(const value_type& x) = 0;
|
||||
virtual queue_op_status try_pull(value_type&) = 0;
|
||||
|
||||
virtual queue_op_status nonblocking_push_back(const value_type& x) = 0;
|
||||
virtual queue_op_status nonblocking_pull_front(value_type&) = 0;
|
||||
virtual queue_op_status nonblocking_push(const value_type& x) = 0;
|
||||
virtual queue_op_status nonblocking_pull(value_type&) = 0;
|
||||
|
||||
virtual queue_op_status wait_push_back(const value_type& x) = 0;
|
||||
virtual queue_op_status wait_pull_front(ValueType& elem) = 0;
|
||||
virtual queue_op_status wait_push(const value_type& x) = 0;
|
||||
virtual queue_op_status wait_pull(ValueType& elem) = 0;
|
||||
|
||||
virtual void push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
virtual queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
virtual queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
virtual queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
virtual void push(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
virtual queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
virtual queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
virtual queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) = 0;
|
||||
};
|
||||
|
||||
template <class T,
|
||||
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#if defined __GNUC__
|
||||
#if defined __GNUC__ && ! defined __clang__
|
||||
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
bool Copyable = is_copy_constructible<T>::value,
|
||||
bool Movable = true
|
||||
|
||||
@@ -43,27 +43,17 @@ namespace concurrent
|
||||
// Modifiers
|
||||
void close() { queue->close(); }
|
||||
|
||||
void push(const value_type& x) { queue->push_back(x); }
|
||||
void push(const value_type& x) { queue->push(x); }
|
||||
|
||||
void pull(value_type& x) { queue->pull_back(x); }
|
||||
// enable_if is_nothrow_copy_movable<value_type>
|
||||
value_type pull() { return queue->pull_back(); }
|
||||
queue_op_status try_push(const value_type& x) { return queue->try_push(x); }
|
||||
|
||||
queue_op_status try_push(const value_type& x) { return queue->try_push_back(x); }
|
||||
queue_op_status nonblocking_push(const value_type& x) { return queue->nonblocking_push(x); }
|
||||
queue_op_status wait_push(const value_type& x) { return queue->wait_push(x); }
|
||||
|
||||
queue_op_status try_pull(value_type& x) { return queue->try_pull_back(x); }
|
||||
|
||||
queue_op_status nonblocking_push(const value_type& x) { return queue->nonblocking_push_back(x); }
|
||||
|
||||
queue_op_status nonblocking_pull(value_type& x) { return queue->nonblocking_pull_back(x); }
|
||||
|
||||
queue_op_status wait_push(const value_type& x) { return queue->wait_push_back(x); }
|
||||
queue_op_status wait_pull(value_type& x) { return queue->wait_pull_back(x); }
|
||||
|
||||
void push(BOOST_THREAD_RV_REF(value_type) x) { queue->push_back(boost::move(x)); }
|
||||
queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->try_push_back(boost::move(x)); }
|
||||
queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->nonblocking_push_back(boost::move(x)); }
|
||||
queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->wait_push_back(boost::move(x)); }
|
||||
void push(BOOST_THREAD_RV_REF(value_type) x) { queue->push(boost::move(x)); }
|
||||
queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->try_push(boost::move(x)); }
|
||||
queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->nonblocking_push(boost::move(x)); }
|
||||
queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->wait_push(boost::move(x)); }
|
||||
};
|
||||
|
||||
template <typename Queue>
|
||||
@@ -88,20 +78,20 @@ namespace concurrent
|
||||
|
||||
void push(const value_type& x) { queue->push_front(x); }
|
||||
|
||||
void pull(value_type& x) { queue->pull_front(x); };
|
||||
void pull(value_type& x) { queue->pull(x); };
|
||||
// enable_if is_nothrow_copy_movable<value_type>
|
||||
value_type pull() { return queue->pull_front(); }
|
||||
value_type pull() { return queue->pull(); }
|
||||
|
||||
queue_op_status try_push(const value_type& x) { return queue->try_push_front(x); }
|
||||
|
||||
queue_op_status try_pull(value_type& x) { return queue->try_pull_front(x); }
|
||||
queue_op_status try_pull(value_type& x) { return queue->try_pull(x); }
|
||||
|
||||
queue_op_status nonblocking_push(const value_type& x) { return queue->nonblocking_push_front(x); }
|
||||
|
||||
queue_op_status nonblocking_pull(value_type& x) { return queue->nonblocking_pull_front(x); }
|
||||
queue_op_status nonblocking_pull(value_type& x) { return queue->nonblocking_pull(x); }
|
||||
|
||||
queue_op_status wait_push(const value_type& x) { return queue->wait_push_front(x); }
|
||||
queue_op_status wait_pull(value_type& x) { return queue->wait_pull_front(x); }
|
||||
queue_op_status wait_pull(value_type& x) { return queue->wait_pull(x); }
|
||||
void push(BOOST_THREAD_RV_REF(value_type) x) { queue->push_front(forward<value_type>(x)); }
|
||||
queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->try_push_front(forward<value_type>(x)); }
|
||||
queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->nonblocking_push_front(forward<value_type>(x)); }
|
||||
|
||||
327
include/boost/thread/concurrent_queues/sync_deque.hpp
Normal file
327
include/boost/thread/concurrent_queues/sync_deque.hpp
Normal file
@@ -0,0 +1,327 @@
|
||||
#ifndef BOOST_THREAD_CONCURRENT_QUEUES_SYNC_DEQUE_HPP
|
||||
#define BOOST_THREAD_CONCURRENT_QUEUES_SYNC_DEQUE_HPP
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Vicente J. Botet Escriba 2013-2014. 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/thread for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/thread/concurrent_queues/detail/sync_queue_base.hpp>
|
||||
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
#include <boost/thread/csbl/devector.hpp>
|
||||
#include <boost/thread/detail/move.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/smart_ptr/make_shared.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace concurrent
|
||||
{
|
||||
template <class ValueType, class Container = csbl::devector<ValueType> >
|
||||
class sync_deque
|
||||
: public detail::sync_queue_base<ValueType, Container >
|
||||
{
|
||||
typedef detail::sync_queue_base<ValueType, Container > super;
|
||||
|
||||
public:
|
||||
typedef ValueType value_type;
|
||||
//typedef typename super::value_type value_type; // fixme
|
||||
typedef typename super::underlying_queue_type underlying_queue_type;
|
||||
typedef typename super::size_type size_type;
|
||||
typedef typename super::op_status op_status;
|
||||
|
||||
// Constructors/Assignment/Destructors
|
||||
BOOST_THREAD_NO_COPYABLE(sync_deque)
|
||||
inline sync_deque();
|
||||
//template <typename Range>
|
||||
//inline explicit sync_deque(Range range);
|
||||
inline ~sync_deque();
|
||||
|
||||
// Modifiers
|
||||
inline void push_back(const value_type& x);
|
||||
inline queue_op_status try_push_back(const value_type& x);
|
||||
inline queue_op_status nonblocking_push_back(const value_type& x);
|
||||
inline queue_op_status wait_push_back(const value_type& x);
|
||||
inline void push_back(BOOST_THREAD_RV_REF(value_type) x);
|
||||
inline queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x);
|
||||
inline queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x);
|
||||
inline queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x);
|
||||
|
||||
// Observers/Modifiers
|
||||
inline void pull_front(value_type&);
|
||||
// enable_if is_nothrow_copy_movable<value_type>
|
||||
inline value_type pull_front();
|
||||
|
||||
inline queue_op_status try_pull_front(value_type&);
|
||||
inline queue_op_status nonblocking_pull_front(value_type&);
|
||||
inline queue_op_status wait_pull_front(ValueType& elem);
|
||||
|
||||
private:
|
||||
|
||||
inline queue_op_status try_pull_front(value_type& x, unique_lock<mutex>& lk);
|
||||
inline queue_op_status wait_pull_front(value_type& x, unique_lock<mutex>& lk);
|
||||
inline queue_op_status try_push_back(const value_type& x, unique_lock<mutex>& lk);
|
||||
inline queue_op_status wait_push_back(const value_type& x, unique_lock<mutex>& lk);
|
||||
inline queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
|
||||
inline queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
|
||||
|
||||
inline void pull_front(value_type& elem, unique_lock<mutex>& )
|
||||
{
|
||||
elem = boost::move(super::data_.front());
|
||||
super::data_.pop_front();
|
||||
}
|
||||
inline value_type pull_front(unique_lock<mutex>& )
|
||||
{
|
||||
value_type e = boost::move(super::data_.front());
|
||||
super::data_.pop_front();
|
||||
return boost::move(e);
|
||||
}
|
||||
|
||||
inline void push_back(const value_type& elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
super::data_.push_back(elem);
|
||||
super::notify_not_empty_if_needed(lk);
|
||||
}
|
||||
|
||||
inline void push_back(BOOST_THREAD_RV_REF(value_type) elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
super::data_.push_back(boost::move(elem));
|
||||
super::notify_not_empty_if_needed(lk);
|
||||
}
|
||||
};
|
||||
|
||||
template <class ValueType, class Container>
|
||||
sync_deque<ValueType, Container>::sync_deque() :
|
||||
super()
|
||||
{
|
||||
}
|
||||
|
||||
// template <class ValueType, class Container>
|
||||
// template <class Range>
|
||||
// explicit sync_deque<ValueType, Container>::sync_deque(Range range) :
|
||||
// data_(), closed_(false)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// typedef typename Range::iterator iterator_t;
|
||||
// iterator_t first = boost::begin(range);
|
||||
// iterator_t end = boost::end(range);
|
||||
// for (iterator_t cur = first; cur != end; ++cur)
|
||||
// {
|
||||
// data_.push(boost::move(*cur));;
|
||||
// }
|
||||
// notify_not_empty_if_needed(lk);
|
||||
// }
|
||||
// catch (...)
|
||||
// {
|
||||
// delete[] data_;
|
||||
// }
|
||||
// }
|
||||
|
||||
template <class ValueType, class Container>
|
||||
sync_deque<ValueType, Container>::~sync_deque()
|
||||
{
|
||||
}
|
||||
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_deque<ValueType, Container>::try_pull_front(ValueType& elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
if (super::empty(lk))
|
||||
{
|
||||
if (super::closed(lk)) return queue_op_status::closed;
|
||||
return queue_op_status::empty;
|
||||
}
|
||||
pull_front(elem, lk);
|
||||
return queue_op_status::success;
|
||||
}
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_deque<ValueType, Container>::wait_pull_front(ValueType& elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
if (super::empty(lk))
|
||||
{
|
||||
if (super::closed(lk)) return queue_op_status::closed;
|
||||
}
|
||||
bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
|
||||
if (has_been_closed) return queue_op_status::closed;
|
||||
pull_front(elem, lk);
|
||||
return queue_op_status::success;
|
||||
}
|
||||
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_deque<ValueType, Container>::try_pull_front(ValueType& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
return try_pull_front(elem, lk);
|
||||
}
|
||||
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_deque<ValueType, Container>::wait_pull_front(ValueType& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
return wait_pull_front(elem, lk);
|
||||
}
|
||||
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_deque<ValueType, Container>::nonblocking_pull_front(ValueType& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_, try_to_lock);
|
||||
if (!lk.owns_lock())
|
||||
{
|
||||
return queue_op_status::busy;
|
||||
}
|
||||
return try_pull_front(elem, lk);
|
||||
}
|
||||
|
||||
template <class ValueType, class Container>
|
||||
void sync_deque<ValueType, Container>::pull_front(ValueType& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
super::wait_until_not_empty(lk);
|
||||
pull_front(elem, lk);
|
||||
}
|
||||
|
||||
// enable if ValueType is nothrow movable
|
||||
template <class ValueType, class Container>
|
||||
ValueType sync_deque<ValueType, Container>::pull_front()
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
super::wait_until_not_empty(lk);
|
||||
return pull_front(lk);
|
||||
}
|
||||
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_deque<ValueType, Container>::try_push_back(const ValueType& elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
if (super::closed(lk)) return queue_op_status::closed;
|
||||
push_back(elem, lk);
|
||||
return queue_op_status::success;
|
||||
}
|
||||
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_deque<ValueType, Container>::try_push_back(const ValueType& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
return try_push_back(elem, lk);
|
||||
}
|
||||
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_deque<ValueType, Container>::wait_push_back(const ValueType& elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
if (super::closed(lk)) return queue_op_status::closed;
|
||||
push_back(elem, lk);
|
||||
return queue_op_status::success;
|
||||
}
|
||||
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_deque<ValueType, Container>::wait_push_back(const ValueType& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
return wait_push_back(elem, lk);
|
||||
}
|
||||
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_deque<ValueType, Container>::nonblocking_push_back(const ValueType& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_, try_to_lock);
|
||||
if (!lk.owns_lock()) return queue_op_status::busy;
|
||||
return try_push_back(elem, lk);
|
||||
}
|
||||
|
||||
template <class ValueType, class Container>
|
||||
void sync_deque<ValueType, Container>::push_back(const ValueType& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
super::throw_if_closed(lk);
|
||||
push_back(elem, lk);
|
||||
}
|
||||
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_deque<ValueType, Container>::try_push_back(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
if (super::closed(lk)) return queue_op_status::closed;
|
||||
push_back(boost::move(elem), lk);
|
||||
return queue_op_status::success;
|
||||
}
|
||||
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_deque<ValueType, Container>::try_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
return try_push_back(boost::move(elem), lk);
|
||||
}
|
||||
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_deque<ValueType, Container>::wait_push_back(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
if (super::closed(lk)) return queue_op_status::closed;
|
||||
push_back(boost::move(elem), lk);
|
||||
return queue_op_status::success;
|
||||
}
|
||||
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_deque<ValueType, Container>::wait_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
return wait_push_back(boost::move(elem), lk);
|
||||
}
|
||||
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_deque<ValueType, Container>::nonblocking_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_, try_to_lock);
|
||||
if (!lk.owns_lock())
|
||||
{
|
||||
return queue_op_status::busy;
|
||||
}
|
||||
return try_push_back(boost::move(elem), lk);
|
||||
}
|
||||
|
||||
template <class ValueType, class Container>
|
||||
void sync_deque<ValueType, Container>::push_back(BOOST_THREAD_RV_REF(ValueType) elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
super::throw_if_closed(lk);
|
||||
push_back(boost::move(elem), lk);
|
||||
}
|
||||
|
||||
template <class ValueType, class Container>
|
||||
sync_deque<ValueType, Container>& operator<<(sync_deque<ValueType, Container>& sbq, BOOST_THREAD_RV_REF(ValueType) elem)
|
||||
{
|
||||
sbq.push_back(boost::move(elem));
|
||||
return sbq;
|
||||
}
|
||||
|
||||
template <class ValueType, class Container>
|
||||
sync_deque<ValueType, Container>& operator<<(sync_deque<ValueType, Container>& sbq, ValueType const&elem)
|
||||
{
|
||||
sbq.push_back(elem);
|
||||
return sbq;
|
||||
}
|
||||
|
||||
template <class ValueType, class Container>
|
||||
sync_deque<ValueType, Container>& operator>>(sync_deque<ValueType, Container>& sbq, ValueType &elem)
|
||||
{
|
||||
sbq.pull_front(elem);
|
||||
return sbq;
|
||||
}
|
||||
|
||||
}
|
||||
using concurrent::sync_deque;
|
||||
|
||||
}
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
#endif
|
||||
@@ -39,9 +39,11 @@ namespace detail {
|
||||
class priority_queue
|
||||
{
|
||||
private:
|
||||
std::vector<Type> _elements;
|
||||
Container _elements;
|
||||
Compare _compare;
|
||||
public:
|
||||
typedef Type value_type;
|
||||
|
||||
explicit priority_queue(const Compare& compare = Compare())
|
||||
: _elements(), _compare(compare)
|
||||
{ }
|
||||
@@ -67,17 +69,21 @@ namespace detail {
|
||||
std::push_heap(_elements.begin(), _elements.end(), _compare);
|
||||
}
|
||||
|
||||
Type pull()
|
||||
void pop()
|
||||
{
|
||||
std::pop_heap(_elements.begin(), _elements.end(), _compare);
|
||||
Type result = boost::move(_elements.back());
|
||||
_elements.pop_back();
|
||||
}
|
||||
Type pull()
|
||||
{
|
||||
Type result = boost::move(_elements.front());
|
||||
pop();
|
||||
return boost::move(result);
|
||||
}
|
||||
|
||||
Type const& top()
|
||||
{
|
||||
return _elements.back();
|
||||
return _elements.front();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <boost/thread/concurrent_queues/detail/sync_queue_base.hpp>
|
||||
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
#include <boost/thread/csbl/deque.hpp>
|
||||
#include <boost/thread/csbl/devector.hpp>
|
||||
#include <boost/thread/detail/move.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
@@ -29,11 +29,11 @@ namespace boost
|
||||
{
|
||||
namespace concurrent
|
||||
{
|
||||
template <typename ValueType>
|
||||
template <class ValueType, class Container = csbl::devector<ValueType> >
|
||||
class sync_queue
|
||||
: public detail::sync_queue_base<ValueType, csbl::deque<ValueType> >
|
||||
: public detail::sync_queue_base<ValueType, Container >
|
||||
{
|
||||
typedef detail::sync_queue_base<ValueType, csbl::deque<ValueType> > super;
|
||||
typedef detail::sync_queue_base<ValueType, Container > super;
|
||||
|
||||
public:
|
||||
typedef ValueType value_type;
|
||||
@@ -45,65 +45,39 @@ namespace concurrent
|
||||
// Constructors/Assignment/Destructors
|
||||
BOOST_THREAD_NO_COPYABLE(sync_queue)
|
||||
inline sync_queue();
|
||||
//template <typename Range>
|
||||
//template <class Range>
|
||||
//inline explicit sync_queue(Range range);
|
||||
inline ~sync_queue();
|
||||
|
||||
// Modifiers
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
|
||||
inline void push(const value_type& x);
|
||||
inline bool try_push(const value_type& x);
|
||||
inline bool try_push(no_block_tag, const value_type& x);
|
||||
inline queue_op_status try_push(const value_type& x);
|
||||
inline queue_op_status nonblocking_push(const value_type& x);
|
||||
inline queue_op_status wait_push(const value_type& x);
|
||||
inline void push(BOOST_THREAD_RV_REF(value_type) x);
|
||||
inline bool try_push(BOOST_THREAD_RV_REF(value_type) x);
|
||||
inline bool try_push(no_block_tag, BOOST_THREAD_RV_REF(value_type) x);
|
||||
#endif
|
||||
inline void push_back(const value_type& x);
|
||||
inline queue_op_status try_push_back(const value_type& x);
|
||||
inline queue_op_status nonblocking_push_back(const value_type& x);
|
||||
inline queue_op_status wait_push_back(const value_type& x);
|
||||
inline void push_back(BOOST_THREAD_RV_REF(value_type) x);
|
||||
inline queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x);
|
||||
inline queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x);
|
||||
inline queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x);
|
||||
inline queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x);
|
||||
inline queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x);
|
||||
inline queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x);
|
||||
|
||||
// Observers/Modifiers
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
inline void pull(value_type&);
|
||||
inline void pull(ValueType& elem, bool & closed);
|
||||
// enable_if is_nothrow_copy_movable<value_type>
|
||||
inline value_type pull();
|
||||
inline shared_ptr<ValueType> ptr_pull();
|
||||
#endif
|
||||
inline void pull_front(value_type&);
|
||||
// enable_if is_nothrow_copy_movable<value_type>
|
||||
inline value_type pull_front();
|
||||
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
inline bool try_pull(value_type&);
|
||||
inline bool try_pull(no_block_tag,value_type&);
|
||||
inline shared_ptr<ValueType> try_pull();
|
||||
#endif
|
||||
inline queue_op_status try_pull_front(value_type&);
|
||||
inline queue_op_status nonblocking_pull_front(value_type&);
|
||||
inline queue_op_status wait_pull_front(ValueType& elem);
|
||||
inline queue_op_status try_pull(value_type&);
|
||||
inline queue_op_status nonblocking_pull(value_type&);
|
||||
inline queue_op_status wait_pull(ValueType& elem);
|
||||
|
||||
private:
|
||||
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
inline bool try_pull(value_type& x, unique_lock<mutex>& lk);
|
||||
inline bool try_push(const value_type& x, unique_lock<mutex>& lk);
|
||||
inline bool try_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
|
||||
inline shared_ptr<value_type> try_pull(unique_lock<mutex>& lk);
|
||||
#endif
|
||||
inline queue_op_status try_pull_front(value_type& x, unique_lock<mutex>& lk);
|
||||
inline queue_op_status wait_pull_front(value_type& x, unique_lock<mutex>& lk);
|
||||
inline queue_op_status try_push_back(const value_type& x, unique_lock<mutex>& lk);
|
||||
inline queue_op_status wait_push_back(const value_type& x, unique_lock<mutex>& lk);
|
||||
inline queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
|
||||
inline queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
|
||||
inline queue_op_status try_pull(value_type& x, unique_lock<mutex>& lk);
|
||||
inline queue_op_status wait_pull(value_type& x, unique_lock<mutex>& lk);
|
||||
inline queue_op_status try_push(const value_type& x, unique_lock<mutex>& lk);
|
||||
inline queue_op_status wait_push(const value_type& x, unique_lock<mutex>& lk);
|
||||
inline queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
|
||||
inline queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
|
||||
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
inline void pull(value_type& elem, unique_lock<mutex>& )
|
||||
{
|
||||
elem = boost::move(super::data_.front());
|
||||
@@ -115,26 +89,7 @@ namespace concurrent
|
||||
super::data_.pop_front();
|
||||
return boost::move(e);
|
||||
}
|
||||
inline boost::shared_ptr<value_type> ptr_pull(unique_lock<mutex>& )
|
||||
{
|
||||
shared_ptr<value_type> res = make_shared<value_type>(boost::move(super::data_.front()));
|
||||
super::data_.pop_front();
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
inline void pull_front(value_type& elem, unique_lock<mutex>& )
|
||||
{
|
||||
elem = boost::move(super::data_.front());
|
||||
super::data_.pop_front();
|
||||
}
|
||||
inline value_type pull_front(unique_lock<mutex>& )
|
||||
{
|
||||
value_type e = boost::move(super::data_.front());
|
||||
super::data_.pop_front();
|
||||
return boost::move(e);
|
||||
}
|
||||
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
inline void push(const value_type& elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
super::data_.push_back(elem);
|
||||
@@ -146,29 +101,17 @@ namespace concurrent
|
||||
super::data_.push_back(boost::move(elem));
|
||||
super::notify_not_empty_if_needed(lk);
|
||||
}
|
||||
#endif
|
||||
inline void push_back(const value_type& elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
super::data_.push_back(elem);
|
||||
super::notify_not_empty_if_needed(lk);
|
||||
}
|
||||
|
||||
inline void push_back(BOOST_THREAD_RV_REF(value_type) elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
super::data_.push_back(boost::move(elem));
|
||||
super::notify_not_empty_if_needed(lk);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ValueType>
|
||||
sync_queue<ValueType>::sync_queue() :
|
||||
template <class ValueType, class Container>
|
||||
sync_queue<ValueType, Container>::sync_queue() :
|
||||
super()
|
||||
{
|
||||
}
|
||||
|
||||
// template <typename ValueType>
|
||||
// template <typename Range>
|
||||
// explicit sync_queue<ValueType>::sync_queue(Range range) :
|
||||
// template <class ValueType, class Container>
|
||||
// template <class Range>
|
||||
// explicit sync_queue<ValueType, Container>::sync_queue(Range range) :
|
||||
// data_(), closed_(false)
|
||||
// {
|
||||
// try
|
||||
@@ -188,47 +131,24 @@ namespace concurrent
|
||||
// }
|
||||
// }
|
||||
|
||||
template <typename ValueType>
|
||||
sync_queue<ValueType>::~sync_queue()
|
||||
template <class ValueType, class Container>
|
||||
sync_queue<ValueType, Container>::~sync_queue()
|
||||
{
|
||||
}
|
||||
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
template <typename ValueType>
|
||||
bool sync_queue<ValueType>::try_pull(ValueType& elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
if (super::empty(lk))
|
||||
{
|
||||
super::throw_if_closed(lk);
|
||||
return false;
|
||||
}
|
||||
pull(elem, lk);
|
||||
return true;
|
||||
}
|
||||
template <typename ValueType>
|
||||
shared_ptr<ValueType> sync_queue<ValueType>::try_pull(unique_lock<mutex>& lk)
|
||||
{
|
||||
if (super::empty(lk))
|
||||
{
|
||||
super::throw_if_closed(lk);
|
||||
return shared_ptr<ValueType>();
|
||||
}
|
||||
return ptr_pull(lk);
|
||||
}
|
||||
#endif
|
||||
template <typename ValueType>
|
||||
queue_op_status sync_queue<ValueType>::try_pull_front(ValueType& elem, unique_lock<mutex>& lk)
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_queue<ValueType, Container>::try_pull(ValueType& elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
if (super::empty(lk))
|
||||
{
|
||||
if (super::closed(lk)) return queue_op_status::closed;
|
||||
return queue_op_status::empty;
|
||||
}
|
||||
pull_front(elem, lk);
|
||||
pull(elem, lk);
|
||||
return queue_op_status::success;
|
||||
}
|
||||
template <typename ValueType>
|
||||
queue_op_status sync_queue<ValueType>::wait_pull_front(ValueType& elem, unique_lock<mutex>& lk)
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_queue<ValueType, Container>::wait_pull(ValueType& elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
if (super::empty(lk))
|
||||
{
|
||||
@@ -236,301 +156,165 @@ namespace concurrent
|
||||
}
|
||||
bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
|
||||
if (has_been_closed) return queue_op_status::closed;
|
||||
pull_front(elem, lk);
|
||||
pull(elem, lk);
|
||||
return queue_op_status::success;
|
||||
}
|
||||
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
template <typename ValueType>
|
||||
bool sync_queue<ValueType>::try_pull(ValueType& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
return try_pull(elem, lk);
|
||||
}
|
||||
#endif
|
||||
template <typename ValueType>
|
||||
queue_op_status sync_queue<ValueType>::try_pull_front(ValueType& elem)
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_queue<ValueType, Container>::try_pull(ValueType& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
return try_pull_front(elem, lk);
|
||||
return try_pull(elem, lk);
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
queue_op_status sync_queue<ValueType>::wait_pull_front(ValueType& elem)
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_queue<ValueType, Container>::wait_pull(ValueType& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
return wait_pull_front(elem, lk);
|
||||
return wait_pull(elem, lk);
|
||||
}
|
||||
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
template <typename ValueType>
|
||||
bool sync_queue<ValueType>::try_pull(no_block_tag,ValueType& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_, try_to_lock);
|
||||
if (!lk.owns_lock())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return try_pull(elem, lk);
|
||||
}
|
||||
template <typename ValueType>
|
||||
boost::shared_ptr<ValueType> sync_queue<ValueType>::try_pull()
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
return try_pull(lk);
|
||||
}
|
||||
#endif
|
||||
template <typename ValueType>
|
||||
queue_op_status sync_queue<ValueType>::nonblocking_pull_front(ValueType& elem)
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_queue<ValueType, Container>::nonblocking_pull(ValueType& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_, try_to_lock);
|
||||
if (!lk.owns_lock())
|
||||
{
|
||||
return queue_op_status::busy;
|
||||
}
|
||||
return try_pull_front(elem, lk);
|
||||
return try_pull(elem, lk);
|
||||
}
|
||||
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
template <typename ValueType>
|
||||
void sync_queue<ValueType>::pull(ValueType& elem)
|
||||
template <class ValueType, class Container>
|
||||
void sync_queue<ValueType, Container>::pull(ValueType& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
super::wait_until_not_empty(lk);
|
||||
pull(elem, lk);
|
||||
}
|
||||
template <typename ValueType>
|
||||
void sync_queue<ValueType>::pull(ValueType& elem, bool & has_been_closed)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
has_been_closed = super::wait_until_not_empty_or_closed(lk);
|
||||
if (has_been_closed) {return;}
|
||||
pull(elem, lk);
|
||||
}
|
||||
|
||||
// enable if ValueType is nothrow movable
|
||||
template <typename ValueType>
|
||||
ValueType sync_queue<ValueType>::pull()
|
||||
template <class ValueType, class Container>
|
||||
ValueType sync_queue<ValueType, Container>::pull()
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
super::wait_until_not_empty(lk);
|
||||
return pull(lk);
|
||||
}
|
||||
template <typename ValueType>
|
||||
boost::shared_ptr<ValueType> sync_queue<ValueType>::ptr_pull()
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
super::wait_until_not_empty(lk);
|
||||
return ptr_pull(lk);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename ValueType>
|
||||
void sync_queue<ValueType>::pull_front(ValueType& elem)
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_queue<ValueType, Container>::try_push(const ValueType& elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
super::wait_until_not_empty(lk);
|
||||
pull_front(elem, lk);
|
||||
}
|
||||
|
||||
// enable if ValueType is nothrow movable
|
||||
template <typename ValueType>
|
||||
ValueType sync_queue<ValueType>::pull_front()
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
super::wait_until_not_empty(lk);
|
||||
return pull_front(lk);
|
||||
}
|
||||
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
template <typename ValueType>
|
||||
bool sync_queue<ValueType>::try_push(const ValueType& elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
super::throw_if_closed(lk);
|
||||
if (super::closed(lk)) return queue_op_status::closed;
|
||||
push(elem, lk);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
bool sync_queue<ValueType>::try_push(const ValueType& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
return try_push(elem, lk);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename ValueType>
|
||||
queue_op_status sync_queue<ValueType>::try_push_back(const ValueType& elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
if (super::closed(lk)) return queue_op_status::closed;
|
||||
push_back(elem, lk);
|
||||
return queue_op_status::success;
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
queue_op_status sync_queue<ValueType>::try_push_back(const ValueType& elem)
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_queue<ValueType, Container>::try_push(const ValueType& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
return try_push_back(elem, lk);
|
||||
return try_push(elem, lk);
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
queue_op_status sync_queue<ValueType>::wait_push_back(const ValueType& elem, unique_lock<mutex>& lk)
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_queue<ValueType, Container>::wait_push(const ValueType& elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
if (super::closed(lk)) return queue_op_status::closed;
|
||||
push_back(elem, lk);
|
||||
push(elem, lk);
|
||||
return queue_op_status::success;
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
queue_op_status sync_queue<ValueType>::wait_push_back(const ValueType& elem)
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_queue<ValueType, Container>::wait_push(const ValueType& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
return wait_push_back(elem, lk);
|
||||
return wait_push(elem, lk);
|
||||
}
|
||||
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
template <typename ValueType>
|
||||
bool sync_queue<ValueType>::try_push(no_block_tag, const ValueType& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_, try_to_lock);
|
||||
if (!lk.owns_lock()) return false;
|
||||
return try_push(elem, lk);
|
||||
}
|
||||
#endif
|
||||
template <typename ValueType>
|
||||
queue_op_status sync_queue<ValueType>::nonblocking_push_back(const ValueType& elem)
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_queue<ValueType, Container>::nonblocking_push(const ValueType& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_, try_to_lock);
|
||||
if (!lk.owns_lock()) return queue_op_status::busy;
|
||||
return try_push_back(elem, lk);
|
||||
return try_push(elem, lk);
|
||||
}
|
||||
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
template <typename ValueType>
|
||||
void sync_queue<ValueType>::push(const ValueType& elem)
|
||||
template <class ValueType, class Container>
|
||||
void sync_queue<ValueType, Container>::push(const ValueType& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
super::throw_if_closed(lk);
|
||||
push(elem, lk);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename ValueType>
|
||||
void sync_queue<ValueType>::push_back(const ValueType& elem)
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_queue<ValueType, Container>::try_push(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
super::throw_if_closed(lk);
|
||||
push_back(elem, lk);
|
||||
}
|
||||
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
template <typename ValueType>
|
||||
bool sync_queue<ValueType>::try_push(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
super::throw_if_closed(lk);
|
||||
if (super::closed(lk)) return queue_op_status::closed;
|
||||
push(boost::move(elem), lk);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
bool sync_queue<ValueType>::try_push(BOOST_THREAD_RV_REF(ValueType) elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
return try_push(boost::move(elem), lk);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename ValueType>
|
||||
queue_op_status sync_queue<ValueType>::try_push_back(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
if (super::closed(lk)) return queue_op_status::closed;
|
||||
push_back(boost::move(elem), lk);
|
||||
return queue_op_status::success;
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
queue_op_status sync_queue<ValueType>::try_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_queue<ValueType, Container>::try_push(BOOST_THREAD_RV_REF(ValueType) elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
return try_push_back(boost::move(elem), lk);
|
||||
return try_push(boost::move(elem), lk);
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
queue_op_status sync_queue<ValueType>::wait_push_back(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_queue<ValueType, Container>::wait_push(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
if (super::closed(lk)) return queue_op_status::closed;
|
||||
push_back(boost::move(elem), lk);
|
||||
push(boost::move(elem), lk);
|
||||
return queue_op_status::success;
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
queue_op_status sync_queue<ValueType>::wait_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_queue<ValueType, Container>::wait_push(BOOST_THREAD_RV_REF(ValueType) elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
return wait_push_back(boost::move(elem), lk);
|
||||
return wait_push(boost::move(elem), lk);
|
||||
}
|
||||
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
template <typename ValueType>
|
||||
bool sync_queue<ValueType>::try_push(no_block_tag, BOOST_THREAD_RV_REF(ValueType) elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_, try_to_lock);
|
||||
if (!lk.owns_lock())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return try_push(boost::move(elem), lk);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename ValueType>
|
||||
queue_op_status sync_queue<ValueType>::nonblocking_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
|
||||
template <class ValueType, class Container>
|
||||
queue_op_status sync_queue<ValueType, Container>::nonblocking_push(BOOST_THREAD_RV_REF(ValueType) elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_, try_to_lock);
|
||||
if (!lk.owns_lock())
|
||||
{
|
||||
return queue_op_status::busy;
|
||||
}
|
||||
return try_push_back(boost::move(elem), lk);
|
||||
return try_push(boost::move(elem), lk);
|
||||
}
|
||||
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
template <typename ValueType>
|
||||
void sync_queue<ValueType>::push(BOOST_THREAD_RV_REF(ValueType) elem)
|
||||
template <class ValueType, class Container>
|
||||
void sync_queue<ValueType, Container>::push(BOOST_THREAD_RV_REF(ValueType) elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
super::throw_if_closed(lk);
|
||||
push(boost::move(elem), lk);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename ValueType>
|
||||
void sync_queue<ValueType>::push_back(BOOST_THREAD_RV_REF(ValueType) elem)
|
||||
template <class ValueType, class Container>
|
||||
sync_queue<ValueType, Container>& operator<<(sync_queue<ValueType, Container>& sbq, BOOST_THREAD_RV_REF(ValueType) elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
super::throw_if_closed(lk);
|
||||
push_back(boost::move(elem), lk);
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
sync_queue<ValueType>& operator<<(sync_queue<ValueType>& sbq, BOOST_THREAD_RV_REF(ValueType) elem)
|
||||
{
|
||||
sbq.push_back(boost::move(elem));
|
||||
sbq.push(boost::move(elem));
|
||||
return sbq;
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
sync_queue<ValueType>& operator<<(sync_queue<ValueType>& sbq, ValueType const&elem)
|
||||
template <class ValueType, class Container>
|
||||
sync_queue<ValueType, Container>& operator<<(sync_queue<ValueType, Container>& sbq, ValueType const&elem)
|
||||
{
|
||||
sbq.push_back(elem);
|
||||
sbq.push(elem);
|
||||
return sbq;
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
sync_queue<ValueType>& operator>>(sync_queue<ValueType>& sbq, ValueType &elem)
|
||||
template <class ValueType, class Container>
|
||||
sync_queue<ValueType, Container>& operator>>(sync_queue<ValueType, Container>& sbq, ValueType &elem)
|
||||
{
|
||||
sbq.pull_front(elem);
|
||||
sbq.pull(elem);
|
||||
return sbq;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,11 +24,12 @@ namespace concurrent
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
template <class T, class Clock = chrono::steady_clock>
|
||||
struct scheduled_type
|
||||
{
|
||||
typedef typename chrono::steady_clock clock;
|
||||
typedef chrono::steady_clock::time_point time_point;
|
||||
typedef T value_type;
|
||||
typedef Clock clock;
|
||||
typedef typename clock::time_point time_point;
|
||||
T data;
|
||||
time_point time;
|
||||
|
||||
@@ -64,20 +65,17 @@ namespace detail
|
||||
|
||||
} //end detail namespace
|
||||
|
||||
template <class T>
|
||||
template <class T, class Clock = chrono::steady_clock>
|
||||
class sync_timed_queue
|
||||
: private sync_priority_queue<detail::scheduled_type<T> >
|
||||
: private sync_priority_queue<detail::scheduled_type<T, Clock> >
|
||||
{
|
||||
typedef detail::scheduled_type<T> stype;
|
||||
typedef sync_priority_queue<stype> super;
|
||||
public:
|
||||
//typedef typename stype::clock clock; // fixme
|
||||
typedef typename chrono::steady_clock clock;
|
||||
|
||||
typedef T value_type;
|
||||
typedef Clock clock;
|
||||
typedef typename clock::duration duration;
|
||||
typedef typename clock::time_point time_point;
|
||||
typedef T value_type;
|
||||
//typedef typename super::value_type value_type; // fixme
|
||||
typedef typename super::underlying_queue_type underlying_queue_type;
|
||||
typedef typename super::size_type size_type;
|
||||
typedef typename super::op_status op_status;
|
||||
@@ -94,21 +92,29 @@ namespace detail
|
||||
T pull();
|
||||
void pull(T& elem);
|
||||
|
||||
queue_op_status pull_until(const clock::time_point& tp, T& elem);
|
||||
queue_op_status pull_for(const clock::duration& dura, T& elem);
|
||||
template <class Duration>
|
||||
queue_op_status pull_until(chrono::time_point<clock,Duration> const& tp, T& elem);
|
||||
template <class Rep, class Period>
|
||||
queue_op_status pull_for(chrono::duration<Rep,Period> const& dura, T& elem);
|
||||
|
||||
queue_op_status try_pull(T& elem);
|
||||
queue_op_status wait_pull(T& elem);
|
||||
queue_op_status nonblocking_pull(T& elem);
|
||||
|
||||
void push(const T& elem, const time_point& tp);
|
||||
void push(const T& elem, const duration& dura);
|
||||
template <class Duration>
|
||||
void push(const T& elem, chrono::time_point<clock,Duration> const& tp);
|
||||
template <class Rep, class Period>
|
||||
void push(const T& elem, chrono::duration<Rep,Period> const& dura);
|
||||
|
||||
queue_op_status try_push(const T& elem, const time_point& tp);
|
||||
queue_op_status try_push(const T& elem, const duration& dura);
|
||||
template <class Duration>
|
||||
queue_op_status try_push(const T& elem, chrono::time_point<clock,Duration> const& tp);
|
||||
template <class Rep, class Period>
|
||||
queue_op_status try_push(const T& elem, chrono::duration<Rep,Period> const& dura);
|
||||
|
||||
queue_op_status try_push(BOOST_THREAD_RV_REF(T) elem, const time_point& tp);
|
||||
queue_op_status try_push(BOOST_THREAD_RV_REF(T) elem, const duration& dura);
|
||||
template <class Duration>
|
||||
queue_op_status try_push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp);
|
||||
template <class Rep, class Period>
|
||||
queue_op_status try_push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura);
|
||||
|
||||
private:
|
||||
T pull(unique_lock<mutex>&);
|
||||
@@ -122,11 +128,10 @@ namespace detail
|
||||
|
||||
queue_op_status wait_pull(unique_lock<mutex>& lk, T& elem);
|
||||
|
||||
//queue_op_status nonblocking_pull(unique_lock<mutex>& lk, T& elem);
|
||||
|
||||
bool wait_until_not_empty_time_reached_or_closed(unique_lock<mutex>&);
|
||||
T pull_when_time_reached(unique_lock<mutex>&);
|
||||
queue_op_status pull_when_time_reached_until(unique_lock<mutex>&, const clock::time_point& tp, T& elem);
|
||||
template <class Duration>
|
||||
queue_op_status pull_when_time_reached_until(unique_lock<mutex>&, chrono::time_point<clock,Duration> const& tp, T& elem);
|
||||
bool time_not_reached(unique_lock<mutex>&);
|
||||
bool time_not_reached(lock_guard<mutex>&);
|
||||
bool empty_or_time_not_reached(unique_lock<mutex>&);
|
||||
@@ -139,58 +144,64 @@ namespace detail
|
||||
}; //end class
|
||||
|
||||
|
||||
template <class T>
|
||||
void sync_timed_queue<T>::push(const T& elem, const time_point& tp)
|
||||
template <class T, class Clock>
|
||||
template <class Duration>
|
||||
void sync_timed_queue<T, Clock>::push(const T& elem, chrono::time_point<clock,Duration> const& tp)
|
||||
{
|
||||
super::push(stype(elem,tp));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void sync_timed_queue<T>::push(const T& elem, const duration& dura)
|
||||
template <class T, class Clock>
|
||||
template <class Rep, class Period>
|
||||
void sync_timed_queue<T, Clock>::push(const T& elem, chrono::duration<Rep,Period> const& dura)
|
||||
{
|
||||
push(elem, clock::now() + dura);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
queue_op_status sync_timed_queue<T>::try_push(const T& elem, const time_point& tp)
|
||||
template <class T, class Clock>
|
||||
template <class Duration>
|
||||
queue_op_status sync_timed_queue<T, Clock>::try_push(const T& elem, chrono::time_point<clock,Duration> const& tp)
|
||||
{
|
||||
return super::try_push(stype(elem,tp));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
queue_op_status sync_timed_queue<T>::try_push(const T& elem, const duration& dura)
|
||||
template <class T, class Clock>
|
||||
template <class Rep, class Period>
|
||||
queue_op_status sync_timed_queue<T, Clock>::try_push(const T& elem, chrono::duration<Rep,Period> const& dura)
|
||||
{
|
||||
return try_push(elem,clock::now() + dura);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
queue_op_status sync_timed_queue<T>::try_push(BOOST_THREAD_RV_REF(T) elem, const time_point& tp)
|
||||
template <class T, class Clock>
|
||||
template <class Duration>
|
||||
queue_op_status sync_timed_queue<T, Clock>::try_push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp)
|
||||
{
|
||||
return super::try_push(stype(boost::move(elem), tp));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
queue_op_status sync_timed_queue<T>::try_push(BOOST_THREAD_RV_REF(T) elem, const duration& dura)
|
||||
template <class T, class Clock>
|
||||
template <class Rep, class Period>
|
||||
queue_op_status sync_timed_queue<T, Clock>::try_push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura)
|
||||
{
|
||||
return try_push(boost::move(elem), clock::now() + dura);
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
template <class T>
|
||||
bool sync_timed_queue<T>::time_not_reached(unique_lock<mutex>&)
|
||||
template <class T, class Clock>
|
||||
bool sync_timed_queue<T, Clock>::time_not_reached(unique_lock<mutex>&)
|
||||
{
|
||||
return super::data_.top().time_not_reached();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool sync_timed_queue<T>::time_not_reached(lock_guard<mutex>&)
|
||||
template <class T, class Clock>
|
||||
bool sync_timed_queue<T, Clock>::time_not_reached(lock_guard<mutex>&)
|
||||
{
|
||||
return super::data_.top().time_not_reached();
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
template <class T>
|
||||
bool sync_timed_queue<T>::wait_until_not_empty_time_reached_or_closed(unique_lock<mutex>& lk)
|
||||
template <class T, class Clock>
|
||||
bool sync_timed_queue<T, Clock>::wait_until_not_empty_time_reached_or_closed(unique_lock<mutex>& lk)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
@@ -207,8 +218,8 @@ namespace detail
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
template <class T>
|
||||
T sync_timed_queue<T>::pull_when_time_reached(unique_lock<mutex>& lk)
|
||||
template <class T, class Clock>
|
||||
T sync_timed_queue<T, Clock>::pull_when_time_reached(unique_lock<mutex>& lk)
|
||||
{
|
||||
while (time_not_reached(lk))
|
||||
{
|
||||
@@ -219,11 +230,12 @@ namespace detail
|
||||
return pull(lk);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class T, class Clock>
|
||||
template <class Duration>
|
||||
queue_op_status
|
||||
sync_timed_queue<T>::pull_when_time_reached_until(unique_lock<mutex>& lk, const clock::time_point& tp, T& elem)
|
||||
sync_timed_queue<T, Clock>::pull_when_time_reached_until(unique_lock<mutex>& lk, chrono::time_point<clock,Duration> const& tp, T& elem)
|
||||
{
|
||||
clock::time_point tpmin = (tp < super::data_.top().time) ? tp : super::data_.top().time;
|
||||
chrono::time_point<clock,Duration> tpmin = (tp < super::data_.top().time) ? tp : super::data_.top().time;
|
||||
while (time_not_reached(lk))
|
||||
{
|
||||
super::throw_if_closed(lk);
|
||||
@@ -237,15 +249,15 @@ namespace detail
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
template <class T>
|
||||
bool sync_timed_queue<T>::empty_or_time_not_reached(unique_lock<mutex>& lk)
|
||||
template <class T, class Clock>
|
||||
bool sync_timed_queue<T, Clock>::empty_or_time_not_reached(unique_lock<mutex>& lk)
|
||||
{
|
||||
if ( super::empty(lk) ) return true;
|
||||
if ( time_not_reached(lk) ) return true;
|
||||
return false;
|
||||
}
|
||||
template <class T>
|
||||
bool sync_timed_queue<T>::empty_or_time_not_reached(lock_guard<mutex>& lk)
|
||||
template <class T, class Clock>
|
||||
bool sync_timed_queue<T, Clock>::empty_or_time_not_reached(lock_guard<mutex>& lk)
|
||||
{
|
||||
if ( super::empty(lk) ) return true;
|
||||
if ( time_not_reached(lk) ) return true;
|
||||
@@ -253,8 +265,8 @@ namespace detail
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
template <class T>
|
||||
T sync_timed_queue<T>::pull(unique_lock<mutex>&)
|
||||
template <class T, class Clock>
|
||||
T sync_timed_queue<T, Clock>::pull(unique_lock<mutex>&)
|
||||
{
|
||||
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
return boost::move(super::data_.pull().data);
|
||||
@@ -263,8 +275,8 @@ namespace detail
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T sync_timed_queue<T>::pull(lock_guard<mutex>&)
|
||||
template <class T, class Clock>
|
||||
T sync_timed_queue<T, Clock>::pull(lock_guard<mutex>&)
|
||||
{
|
||||
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
return boost::move(super::data_.pull().data);
|
||||
@@ -272,8 +284,8 @@ namespace detail
|
||||
return super::data_.pull().data;
|
||||
#endif
|
||||
}
|
||||
template <class T>
|
||||
T sync_timed_queue<T>::pull()
|
||||
template <class T, class Clock>
|
||||
T sync_timed_queue<T, Clock>::pull()
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
super::wait_until_not_empty(lk);
|
||||
@@ -281,8 +293,8 @@ namespace detail
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
template <class T>
|
||||
void sync_timed_queue<T>::pull(unique_lock<mutex>&, T& elem)
|
||||
template <class T, class Clock>
|
||||
void sync_timed_queue<T, Clock>::pull(unique_lock<mutex>&, T& elem)
|
||||
{
|
||||
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
elem = boost::move(super::data_.pull().data);
|
||||
@@ -291,8 +303,8 @@ namespace detail
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void sync_timed_queue<T>::pull(lock_guard<mutex>&, T& elem)
|
||||
template <class T, class Clock>
|
||||
void sync_timed_queue<T, Clock>::pull(lock_guard<mutex>&, T& elem)
|
||||
{
|
||||
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
elem = boost::move(super::data_.pull().data);
|
||||
@@ -301,8 +313,8 @@ namespace detail
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void sync_timed_queue<T>::pull(T& elem)
|
||||
template <class T, class Clock>
|
||||
void sync_timed_queue<T, Clock>::pull(T& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
super::wait_until_not_empty(lk);
|
||||
@@ -310,9 +322,10 @@ namespace detail
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
template <class T>
|
||||
template <class T, class Clock>
|
||||
template <class Duration>
|
||||
queue_op_status
|
||||
sync_timed_queue<T>::pull_until(const clock::time_point& tp, T& elem)
|
||||
sync_timed_queue<T, Clock>::pull_until(chrono::time_point<clock,Duration> const& tp, T& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
|
||||
@@ -322,16 +335,17 @@ namespace detail
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
template <class T>
|
||||
template <class T, class Clock>
|
||||
template <class Rep, class Period>
|
||||
queue_op_status
|
||||
sync_timed_queue<T>::pull_for(const clock::duration& dura, T& elem)
|
||||
sync_timed_queue<T, Clock>::pull_for(chrono::duration<Rep,Period> const& dura, T& elem)
|
||||
{
|
||||
return pull_until(clock::now() + dura, elem);
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
template <class T>
|
||||
queue_op_status sync_timed_queue<T>::try_pull(unique_lock<mutex>& lk, T& elem)
|
||||
template <class T, class Clock>
|
||||
queue_op_status sync_timed_queue<T, Clock>::try_pull(unique_lock<mutex>& lk, T& elem)
|
||||
{
|
||||
if ( super::empty(lk) )
|
||||
{
|
||||
@@ -347,8 +361,8 @@ namespace detail
|
||||
pull(lk, elem);
|
||||
return queue_op_status::success;
|
||||
}
|
||||
template <class T>
|
||||
queue_op_status sync_timed_queue<T>::try_pull(lock_guard<mutex>& lk, T& elem)
|
||||
template <class T, class Clock>
|
||||
queue_op_status sync_timed_queue<T, Clock>::try_pull(lock_guard<mutex>& lk, T& elem)
|
||||
{
|
||||
if ( super::empty(lk) )
|
||||
{
|
||||
@@ -364,16 +378,16 @@ namespace detail
|
||||
return queue_op_status::success;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
queue_op_status sync_timed_queue<T>::try_pull(T& elem)
|
||||
template <class T, class Clock>
|
||||
queue_op_status sync_timed_queue<T, Clock>::try_pull(T& elem)
|
||||
{
|
||||
lock_guard<mutex> lk(super::mtx_);
|
||||
return try_pull(lk, elem);
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
template <class T>
|
||||
queue_op_status sync_timed_queue<T>::wait_pull(unique_lock<mutex>& lk, T& elem)
|
||||
template <class T, class Clock>
|
||||
queue_op_status sync_timed_queue<T, Clock>::wait_pull(unique_lock<mutex>& lk, T& elem)
|
||||
{
|
||||
if (super::empty(lk))
|
||||
{
|
||||
@@ -385,16 +399,16 @@ namespace detail
|
||||
return queue_op_status::success;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
queue_op_status sync_timed_queue<T>::wait_pull(T& elem)
|
||||
template <class T, class Clock>
|
||||
queue_op_status sync_timed_queue<T, Clock>::wait_pull(T& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
return wait_pull(lk, elem);
|
||||
}
|
||||
|
||||
// ///////////////////////////
|
||||
// template <class T>
|
||||
// queue_op_status sync_timed_queue<T>::wait_pull(unique_lock<mutex> &lk, T& elem)
|
||||
// template <class T, class Clock>
|
||||
// queue_op_status sync_timed_queue<T, Clock>::wait_pull(unique_lock<mutex> &lk, T& elem)
|
||||
// {
|
||||
// if (super::empty(lk))
|
||||
// {
|
||||
@@ -406,15 +420,15 @@ namespace detail
|
||||
// return queue_op_status::success;
|
||||
// }
|
||||
// template <class T>
|
||||
// queue_op_status sync_timed_queue<T>::wait_pull(T& elem)
|
||||
// queue_op_status sync_timed_queue<T, Clock>::wait_pull(T& elem)
|
||||
// {
|
||||
// unique_lock<mutex> lk(super::mtx_);
|
||||
// return wait_pull(lk, elem);
|
||||
// }
|
||||
|
||||
///////////////////////////
|
||||
template <class T>
|
||||
queue_op_status sync_timed_queue<T>::nonblocking_pull(T& elem)
|
||||
template <class T, class Clock>
|
||||
queue_op_status sync_timed_queue<T, Clock>::nonblocking_pull(T& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_, try_to_lock);
|
||||
if (! lk.owns_lock()) return queue_op_status::busy;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
// [
|
||||
// _Ty=non_copyable
|
||||
// ]
|
||||
#if defined BOOST_THREAD_USES_BOOST_DEQUE || defined BOOST_NO_CXX11_HDR_DEQUE || defined BOOST_NO_CXX11_RVALUE_REFERENCES || (defined _MSC_VER && _MSC_FULL_VER < 180020827)
|
||||
#if defined BOOST_THREAD_USES_BOOST_DEQUE || defined BOOST_NO_CXX11_RVALUE_REFERENCES || (defined _MSC_VER && _MSC_FULL_VER < 180020827)
|
||||
#ifndef BOOST_THREAD_USES_BOOST_DEQUE
|
||||
#define BOOST_THREAD_USES_BOOST_DEQUE
|
||||
#endif
|
||||
|
||||
100
include/boost/thread/csbl/devector.hpp
Normal file
100
include/boost/thread/csbl/devector.hpp
Normal file
@@ -0,0 +1,100 @@
|
||||
// Copyright (C) 2013 Vicente J. Botet Escriba
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// 2013/10 Vicente J. Botet Escriba
|
||||
// Creation.
|
||||
|
||||
#ifndef BOOST_CSBL_DEVECTOR_HPP
|
||||
#define BOOST_CSBL_DEVECTOR_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/thread/csbl/vector.hpp>
|
||||
#include <boost/move/detail/move_helpers.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace csbl
|
||||
{
|
||||
template <class T>
|
||||
class devector
|
||||
{
|
||||
typedef vector<T> vector_type;
|
||||
vector<T> data_;
|
||||
std::size_t front_index_;
|
||||
|
||||
BOOST_COPYABLE_AND_MOVABLE(devector)
|
||||
|
||||
template <class U>
|
||||
void priv_push_back(BOOST_FWD_REF(U) x)
|
||||
{ data_.push_back(boost::forward<U>(x)); }
|
||||
|
||||
public:
|
||||
typedef typename vector_type::size_type size_type;
|
||||
typedef typename vector_type::reference reference;
|
||||
typedef typename vector_type::const_reference const_reference;
|
||||
|
||||
|
||||
devector() : front_index_(0) {}
|
||||
devector(devector const& x) BOOST_NOEXCEPT
|
||||
: data_(x.data_),
|
||||
front_index_(x.front_index_)
|
||||
{}
|
||||
devector(BOOST_RV_REF(devector) x) BOOST_NOEXCEPT
|
||||
: data_(boost::move(x.data_)),
|
||||
front_index_(x.front_index_)
|
||||
{}
|
||||
|
||||
devector& operator=(BOOST_COPY_ASSIGN_REF(devector) x)
|
||||
{
|
||||
if (&x != this)
|
||||
{
|
||||
data_ = x.data_;
|
||||
front_index_ = x.front_index_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
devector& operator=(BOOST_RV_REF(devector) x)
|
||||
BOOST_NOEXCEPT_IF(vector<T>::allocator_traits_type::propagate_on_container_move_assignment::value)
|
||||
{
|
||||
data_ = boost::move(x.data_);
|
||||
front_index_ = x.front_index_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool empty() const BOOST_NOEXCEPT
|
||||
{ return data_.size() == front_index_; }
|
||||
|
||||
size_type size() const BOOST_NOEXCEPT
|
||||
{ return data_.size() - front_index_; }
|
||||
|
||||
reference front() BOOST_NOEXCEPT
|
||||
{ return data_[front_index_]; }
|
||||
|
||||
const_reference front() const BOOST_NOEXCEPT
|
||||
{ return data_[front_index_]; }
|
||||
|
||||
reference back() BOOST_NOEXCEPT
|
||||
{ return data_.back(); }
|
||||
|
||||
const_reference back() const BOOST_NOEXCEPT
|
||||
{ return data_.back(); }
|
||||
|
||||
BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
|
||||
|
||||
void pop_front()
|
||||
{
|
||||
++front_index_;
|
||||
if (empty()) {
|
||||
data_.clear();
|
||||
front_index_=0;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif // header
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined BOOST_THREAD_USES_BOOST_LIST || defined BOOST_NO_CXX11_HDR_LIST || defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#if defined BOOST_THREAD_USES_BOOST_LIST || defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_THREAD_USES_BOOST_LIST
|
||||
#define BOOST_THREAD_USES_BOOST_LIST
|
||||
#endif
|
||||
|
||||
45
include/boost/thread/csbl/queue.hpp
Normal file
45
include/boost/thread/csbl/queue.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright (C) 2015 Vicente J. Botet Escriba
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// 2013/10 Vicente J. Botet Escriba
|
||||
// Creation.
|
||||
|
||||
#ifndef BOOST_CSBL_QUEUE_HPP
|
||||
#define BOOST_CSBL_QUEUE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
// MSVC has some trouble instantiating a non_copyable type
|
||||
//C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xmemory0(606) : error C2248: 'non_copyable::non_copyable' : cannot access private member declared in class 'non_copyable'
|
||||
// ..\libs\thread\test\sync\mutual_exclusion\queue_views\single_thread_pass.cpp(24) : see declaration of 'non_copyable::non_copyable'
|
||||
// ..\libs\thread\test\sync\mutual_exclusion\queue_views\single_thread_pass.cpp(23) : see declaration of 'non_copyable'
|
||||
// C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xmemory0(605) : while compiling class template member function 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)'
|
||||
// with
|
||||
// [
|
||||
// _Ty=non_copyable
|
||||
// ]
|
||||
#if defined BOOST_THREAD_USES_BOOST_QUEUE || defined BOOST_NO_CXX11_RVALUE_REFERENCES || (defined _MSC_VER && _MSC_FULL_VER < 180020827)
|
||||
#ifndef BOOST_THREAD_USES_BOOST_QUEUE
|
||||
#define BOOST_THREAD_USES_BOOST_QUEUE
|
||||
#endif
|
||||
#include <boost/container/queue.hpp>
|
||||
#else
|
||||
#include <queue>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace csbl
|
||||
{
|
||||
#if defined BOOST_THREAD_USES_BOOST_QUEUE
|
||||
using ::boost::container::queue;
|
||||
|
||||
#else
|
||||
using ::std::queue;
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
#endif // header
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined BOOST_THREAD_USES_BOOST_VECTOR || defined BOOST_NO_CXX11_HDR_VECTOR || defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#if defined BOOST_THREAD_USES_BOOST_VECTOR || defined BOOST_NO_CXX11_RVALUE_REFERENCES || defined BOOST_MSVC
|
||||
#ifndef BOOST_THREAD_USES_BOOST_VECTOR
|
||||
#define BOOST_THREAD_USES_BOOST_VECTOR
|
||||
#endif
|
||||
|
||||
@@ -134,7 +134,7 @@ namespace boost
|
||||
//BOOST_THREAD_DCL_MOVABLE_BEG(X) invoker<Fp> BOOST_THREAD_DCL_MOVABLE_END
|
||||
#else
|
||||
|
||||
#if ! defined BOOST_MSVC
|
||||
#if ! defined BOOST_MSVC && defined(BOOST_THREAD_PROVIDES_INVOKE)
|
||||
|
||||
#define BOOST_THREAD_RV_REF_ARG_T(z, n, unused) BOOST_PP_COMMA_IF(n) BOOST_THREAD_RV_REF(Arg##n)
|
||||
#define BOOST_THREAD_RV_REF_A_T(z, n, unused) BOOST_PP_COMMA_IF(n) BOOST_THREAD_RV_REF(A##n)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <boost/thread/detail/delete.hpp>
|
||||
#include <boost/thread/detail/move.hpp>
|
||||
#include <boost/thread/scoped_thread.hpp>
|
||||
#include <boost/thread/sync_queue.hpp>
|
||||
#include <boost/thread/concurrent_queues/sync_queue.hpp>
|
||||
#include <boost/thread/executors/work.hpp>
|
||||
#include <boost/thread/csbl/vector.hpp>
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace executors
|
||||
try
|
||||
{
|
||||
work task;
|
||||
if (work_queue.try_pull_front(task) == queue_op_status::success)
|
||||
if (work_queue.try_pull(task) == queue_op_status::success)
|
||||
{
|
||||
task();
|
||||
return true;
|
||||
@@ -87,7 +87,7 @@ namespace executors
|
||||
for(;;)
|
||||
{
|
||||
work task;
|
||||
queue_op_status st = work_queue.wait_pull_front(task);
|
||||
queue_op_status st = work_queue.wait_pull(task);
|
||||
if (st == queue_op_status::closed) return;
|
||||
task();
|
||||
}
|
||||
@@ -269,18 +269,18 @@ namespace executors
|
||||
template <typename Closure>
|
||||
void submit(Closure & closure)
|
||||
{
|
||||
work_queue.push_back(work(closure));
|
||||
work_queue.push(work(closure));
|
||||
}
|
||||
#endif
|
||||
void submit(void (*closure)())
|
||||
{
|
||||
work_queue.push_back(work(closure));
|
||||
work_queue.push(work(closure));
|
||||
}
|
||||
|
||||
template <typename Closure>
|
||||
void submit(BOOST_THREAD_RV_REF(Closure) closure)
|
||||
{
|
||||
work_queue.push_back(work(boost::forward<Closure>(closure)));
|
||||
work_queue.push(work(boost::forward<Closure>(closure)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
// Copyright (C) 2014 Ian Forbed
|
||||
// Copyright (C) 2014 Vicente J. Botet Escriba
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
|
||||
#ifndef BOOST_THREAD_EXECUTORS_DETAIL_PRIORITY_EXECUTOR_BASE_HPP
|
||||
#define BOOST_THREAD_EXECUTORS_DETAIL_PRIORITY_EXECUTOR_BASE_HPP
|
||||
|
||||
#include <boost/atomic.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/thread/concurrent_queues/sync_timed_queue.hpp>
|
||||
#include <boost/thread/executors/work.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace executors
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template <class Queue>
|
||||
class priority_executor_base
|
||||
{
|
||||
public:
|
||||
typedef boost::function<void()> work;
|
||||
//typedef executors::work work;
|
||||
protected:
|
||||
typedef Queue queue_type;
|
||||
queue_type _workq;
|
||||
|
||||
priority_executor_base() {}
|
||||
public:
|
||||
|
||||
~priority_executor_base()
|
||||
{
|
||||
if(!closed())
|
||||
{
|
||||
this->close();
|
||||
}
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
_workq.close();
|
||||
}
|
||||
|
||||
bool closed()
|
||||
{
|
||||
return _workq.closed();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
try
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
work task;
|
||||
queue_op_status st = _workq.wait_pull(task);
|
||||
if (st == queue_op_status::closed) return;
|
||||
task();
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::terminate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}; //end class
|
||||
|
||||
} //end detail namespace
|
||||
} //end executors namespace
|
||||
} //end boost namespace
|
||||
#endif
|
||||
@@ -5,14 +5,16 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SCHEDULED_EXECUTOR_HPP
|
||||
#define SCHEDULED_EXECUTOR_HPP
|
||||
#ifndef BOOST_THREAD_EXECUTORS_DETAIL_SCHEDULED_EXECUTOR_BASE_HPP
|
||||
#define BOOST_THREAD_EXECUTORS_DETAIL_SCHEDULED_EXECUTOR_BASE_HPP
|
||||
|
||||
#include <boost/thread/concurrent_queues/sync_timed_queue.hpp>
|
||||
#include <boost/thread/executors/detail/priority_executor_base.hpp>
|
||||
#include <boost/thread/executors/work.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
#include <boost/atomic.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/thread/concurrent_queues/sync_timed_queue.hpp>
|
||||
#include <boost/thread/executors/work.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -20,71 +22,38 @@ namespace executors
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class scheduled_executor_base
|
||||
template <class Clock=chrono::steady_clock>
|
||||
class scheduled_executor_base : public priority_executor_base<concurrent::sync_timed_queue<boost::function<void()>, Clock > >
|
||||
{
|
||||
public:
|
||||
typedef boost::function<void()> work;
|
||||
//typedef executors::work work;
|
||||
typedef chrono::steady_clock clock;
|
||||
typedef clock::duration duration;
|
||||
typedef clock::time_point time_point;
|
||||
typedef Clock clock;
|
||||
typedef typename clock::duration duration;
|
||||
typedef typename clock::time_point time_point;
|
||||
protected:
|
||||
concurrent::sync_timed_queue<work> _workq;
|
||||
|
||||
scheduled_executor_base() {}
|
||||
public:
|
||||
|
||||
~scheduled_executor_base()
|
||||
{
|
||||
if(!closed())
|
||||
if(! this->closed())
|
||||
{
|
||||
this->close();
|
||||
}
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
_workq.close();
|
||||
}
|
||||
|
||||
bool closed()
|
||||
{
|
||||
return _workq.closed();
|
||||
}
|
||||
|
||||
void submit(work w)
|
||||
{
|
||||
_workq.push(w, clock::now());
|
||||
}
|
||||
|
||||
void submit_at(work w, const time_point& tp)
|
||||
{
|
||||
_workq.push(w, tp);
|
||||
this->_workq.push(w, tp);
|
||||
}
|
||||
|
||||
void submit_after(work w, const duration& dura)
|
||||
{
|
||||
_workq.push(w, dura);
|
||||
this->_workq.push(w, dura+clock::now());
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
try
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
work task;
|
||||
queue_op_status st = _workq.wait_pull(task);
|
||||
if (st == queue_op_status::closed) return;
|
||||
task();
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::terminate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}; //end class
|
||||
|
||||
} //end detail namespace
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/thread/detail/delete.hpp>
|
||||
#include <boost/thread/detail/move.hpp>
|
||||
#include <boost/thread/sync_queue.hpp>
|
||||
#include <boost/thread/concurrent_queues/sync_queue.hpp>
|
||||
#include <boost/thread/executors/work.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
@@ -44,7 +44,7 @@ namespace executors
|
||||
work task;
|
||||
try
|
||||
{
|
||||
if (work_queue.try_pull_front(task) == queue_op_status::success)
|
||||
if (work_queue.try_pull(task) == queue_op_status::success)
|
||||
{
|
||||
task();
|
||||
return true;
|
||||
@@ -143,18 +143,18 @@ namespace executors
|
||||
template <typename Closure>
|
||||
void submit(Closure & closure)
|
||||
{
|
||||
work_queue.push_back(work(closure));
|
||||
work_queue.push(work(closure));
|
||||
}
|
||||
#endif
|
||||
void submit(void (*closure)())
|
||||
{
|
||||
work_queue.push_back(work(closure));
|
||||
work_queue.push(work(closure));
|
||||
}
|
||||
|
||||
template <typename Closure>
|
||||
void submit(BOOST_THREAD_RV_REF(Closure) closure)
|
||||
{
|
||||
work_queue.push_back(work(boost::forward<Closure>(closure)));
|
||||
work_queue.push(work(boost::forward<Closure>(closure)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace boost
|
||||
namespace executors
|
||||
{
|
||||
|
||||
class scheduled_thread_pool : public detail::scheduled_executor_base
|
||||
class scheduled_thread_pool : public detail::scheduled_executor_base<>
|
||||
{
|
||||
private:
|
||||
thread_group _workers;
|
||||
@@ -36,29 +36,9 @@ namespace executors
|
||||
}
|
||||
|
||||
private:
|
||||
typedef detail::scheduled_executor_base super;
|
||||
inline void loop();
|
||||
typedef detail::scheduled_executor_base<> super;
|
||||
}; //end class
|
||||
|
||||
void scheduled_thread_pool::loop()
|
||||
{
|
||||
try
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
super::work task;
|
||||
queue_op_status st = super::_workq.wait_pull(task);
|
||||
if (st == queue_op_status::closed) return;
|
||||
task();
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::terminate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} //end executors namespace
|
||||
|
||||
using executors::scheduled_thread_pool;
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/thread/executors/detail/scheduled_executor_base.hpp>
|
||||
|
||||
#include <boost/chrono/time_point.hpp>
|
||||
#include <boost/chrono/duration.hpp>
|
||||
#include <boost/chrono/system_clocks.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
@@ -51,9 +53,11 @@ namespace boost
|
||||
class resubmit_at_executor
|
||||
{
|
||||
public:
|
||||
typedef chrono::steady_clock clock;
|
||||
typedef typename Scheduler::clock clock;
|
||||
typedef typename Scheduler::work work;
|
||||
|
||||
resubmit_at_executor(Scheduler& sch, Executor& ex, clock::time_point const& tp) :
|
||||
template <class Duration>
|
||||
resubmit_at_executor(Scheduler& sch, Executor& ex, chrono::time_point<clock, Duration> const& tp) :
|
||||
sch(sch),
|
||||
ex(ex),
|
||||
tp(tp),
|
||||
@@ -98,7 +102,7 @@ namespace boost
|
||||
private:
|
||||
Scheduler& sch;
|
||||
Executor& ex;
|
||||
clock::time_point tp;
|
||||
typename clock::time_point tp;
|
||||
bool is_closed;
|
||||
};
|
||||
|
||||
@@ -111,7 +115,8 @@ namespace boost
|
||||
class scheduler_executor_wrapper
|
||||
{
|
||||
public:
|
||||
typedef chrono::steady_clock clock;
|
||||
typedef typename Scheduler::clock clock;
|
||||
typedef typename Scheduler::work work;
|
||||
typedef resubmit_at_executor<Scheduler, Executor> the_executor;
|
||||
|
||||
scheduler_executor_wrapper(Scheduler& sch, Executor& ex) :
|
||||
@@ -132,13 +137,14 @@ namespace boost
|
||||
return sch;
|
||||
}
|
||||
|
||||
template <class Duration>
|
||||
the_executor after(Duration const& rel_time)
|
||||
template <class Rep, class Period>
|
||||
the_executor after(chrono::duration<Rep,Period> const& rel_time)
|
||||
{
|
||||
return at(clock::now() + rel_time );
|
||||
}
|
||||
|
||||
the_executor at(clock::time_point const& abs_time)
|
||||
template <class Duration>
|
||||
the_executor at(chrono::time_point<clock,Duration> const& abs_time)
|
||||
{
|
||||
return the_executor(sch, ex, abs_time);
|
||||
}
|
||||
@@ -154,9 +160,12 @@ namespace boost
|
||||
class at_executor
|
||||
{
|
||||
public:
|
||||
typedef chrono::steady_clock clock;
|
||||
typedef typename Scheduler::clock clock;
|
||||
typedef typename Scheduler::work work;
|
||||
typedef typename clock::time_point time_point;
|
||||
|
||||
at_executor(Scheduler& sch, clock::time_point const& tp) :
|
||||
template <class Duration>
|
||||
at_executor(Scheduler& sch, chrono::time_point<clock,Duration> const& tp) :
|
||||
sch(sch),
|
||||
tp(tp),
|
||||
is_closed(false)
|
||||
@@ -200,18 +209,20 @@ namespace boost
|
||||
|
||||
private:
|
||||
Scheduler& sch;
|
||||
clock::time_point tp;
|
||||
time_point tp;
|
||||
bool is_closed;
|
||||
}; //end class
|
||||
|
||||
/// A @c Scheduler using a specific thread. Note that a Scheduler is not an Executor.
|
||||
/// It provides factory helper functions such as at/after that convert a @c Scheduler into an @c Executor
|
||||
/// that submit the work at/after a specific time/duration respectively.
|
||||
class scheduler : public detail::scheduled_executor_base
|
||||
template <class Clock = chrono::steady_clock>
|
||||
class scheduler : public detail::scheduled_executor_base<Clock>
|
||||
{
|
||||
public:
|
||||
typedef chrono::steady_clock clock;
|
||||
typedef clock::time_point time_point;
|
||||
typedef typename detail::scheduled_executor_base<Clock>::work work;
|
||||
|
||||
typedef Clock clock;
|
||||
|
||||
scheduler()
|
||||
: super(),
|
||||
@@ -228,19 +239,20 @@ namespace boost
|
||||
return scheduler_executor_wrapper<scheduler, Ex>(*this, ex);
|
||||
}
|
||||
|
||||
template <class Duration>
|
||||
at_executor<scheduler> after(Duration const& rel_time)
|
||||
template <class Rep, class Period>
|
||||
at_executor<scheduler> after(chrono::duration<Rep,Period> const& rel_time)
|
||||
{
|
||||
return at(rel_time + clock::now());
|
||||
}
|
||||
|
||||
at_executor<scheduler> at(time_point const& tp)
|
||||
template <class Duration>
|
||||
at_executor<scheduler> at(chrono::time_point<clock,Duration> const& tp)
|
||||
{
|
||||
return at_executor<scheduler>(*this, tp);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef detail::scheduled_executor_base super;
|
||||
typedef detail::scheduled_executor_base<Clock> super;
|
||||
thread thr;
|
||||
};
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace executors
|
||||
{
|
||||
|
||||
template <typename Executor>
|
||||
class scheduling_adpator : public detail::scheduled_executor_base
|
||||
class scheduling_adpator : public detail::scheduled_executor_base<>
|
||||
{
|
||||
private:
|
||||
Executor& _exec;
|
||||
@@ -26,7 +26,7 @@ namespace executors
|
||||
scheduling_adpator(Executor& ex)
|
||||
: super(),
|
||||
_exec(ex),
|
||||
_scheduler(&scheduling_adpator::loop, this) {}
|
||||
_scheduler(&super::loop, this) {}
|
||||
|
||||
~scheduling_adpator()
|
||||
{
|
||||
@@ -40,30 +40,9 @@ namespace executors
|
||||
}
|
||||
|
||||
private:
|
||||
typedef detail::scheduled_executor_base super;
|
||||
void loop();
|
||||
typedef detail::scheduled_executor_base<> super;
|
||||
}; //end class
|
||||
|
||||
template<typename Executor>
|
||||
void scheduling_adpator<Executor>::loop()
|
||||
{
|
||||
try
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
super::work task;
|
||||
queue_op_status st = super::_workq.wait_pull(task);
|
||||
if (st == queue_op_status::closed) return;
|
||||
_exec.submit(task);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::terminate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} //end executors
|
||||
|
||||
using executors::scheduling_adpator;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/thread/detail/delete.hpp>
|
||||
#include <boost/thread/detail/move.hpp>
|
||||
#include <boost/thread/sync_queue.hpp>
|
||||
#include <boost/thread/concurrent_queues/sync_queue.hpp>
|
||||
#include <boost/thread/executors/work.hpp>
|
||||
#include <boost/thread/executors/generic_executor_ref.hpp>
|
||||
#include <boost/thread/future.hpp>
|
||||
@@ -43,8 +43,13 @@ namespace executors
|
||||
try_executing_one_task(work& task, boost::promise<void> &p)
|
||||
: task(task), p(p) {}
|
||||
void operator()() {
|
||||
task();
|
||||
p.set_value();
|
||||
try {
|
||||
task();
|
||||
p.set_value();
|
||||
} catch (...)
|
||||
{
|
||||
p.set_exception(current_exception());
|
||||
}
|
||||
}
|
||||
};
|
||||
public:
|
||||
@@ -64,7 +69,7 @@ namespace executors
|
||||
work task;
|
||||
try
|
||||
{
|
||||
if (work_queue.try_pull_front(task) == queue_op_status::success)
|
||||
if (work_queue.try_pull(task) == queue_op_status::success)
|
||||
{
|
||||
boost::promise<void> p;
|
||||
try_executing_one_task tmp(task,p);
|
||||
@@ -165,18 +170,18 @@ namespace executors
|
||||
template <typename Closure>
|
||||
void submit(Closure & closure)
|
||||
{
|
||||
work_queue.push_back(work(closure));
|
||||
work_queue.push(work(closure));
|
||||
}
|
||||
#endif
|
||||
void submit(void (*closure)())
|
||||
{
|
||||
work_queue.push_back(work(closure));
|
||||
work_queue.push(work(closure));
|
||||
}
|
||||
|
||||
template <typename Closure>
|
||||
void submit(BOOST_THREAD_RV_REF(Closure) closure)
|
||||
{
|
||||
work_queue.push_back(work(boost::forward<Closure>(closure)));
|
||||
work_queue.push(work(boost::forward<Closure>(closure)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef BOOST_THREAD_EXPERIMENTAL_CONFIG_INLINE_NAMESPACE_HPP
|
||||
#define BOOST_THREAD_EXPERIMENTAL_CONFIG_INLINE_NAMESPACE_HPP
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Vicente J. Botet Escriba 2014. 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/thread for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_INLINE_NAMESPACES)
|
||||
# define BOOST_THREAD_INLINE_NAMESPACE(name) inline namespace name
|
||||
#else
|
||||
# define BOOST_THREAD_INLINE_NAMESPACE(name) namespace name
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
16
include/boost/thread/experimental/exception_list.hpp
Normal file
16
include/boost/thread/experimental/exception_list.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef BOOST_THREAD_EXPERIMENTAL_EXCEPTION_LIST_HPP
|
||||
#define BOOST_THREAD_EXPERIMENTAL_EXCEPTION_LIST_HPP
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Vicente J. Botet Escriba 2014. 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/thread for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <boost/thread/experimental/parallel/v1/exception_list.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,70 @@
|
||||
#ifndef BOOST_THREAD_EXPERIMENTAL_PARALLEL_V1_EXCEPTION_LIST_HPP
|
||||
#define BOOST_THREAD_EXPERIMENTAL_PARALLEL_V1_EXCEPTION_LIST_HPP
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Vicente J. Botet Escriba 2014. 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/thread for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/thread/experimental/parallel/v1/inline_namespace.hpp>
|
||||
|
||||
#include <boost/exception_ptr.hpp>
|
||||
#include <exception>
|
||||
#include <list>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace experimental
|
||||
{
|
||||
namespace parallel
|
||||
{
|
||||
BOOST_THREAD_INLINE_NAMESPACE(v1)
|
||||
{
|
||||
|
||||
class BOOST_SYMBOL_VISIBLE exception_list: public std::exception
|
||||
{
|
||||
typedef std::list<exception_ptr> exception_ptr_list;
|
||||
exception_ptr_list list_;
|
||||
public:
|
||||
typedef exception_ptr_list::const_iterator const_iterator;
|
||||
|
||||
~exception_list() BOOST_NOEXCEPT_OR_NOTHROW {}
|
||||
|
||||
void add(exception_ptr const& e)
|
||||
{
|
||||
list_.push_back(e);
|
||||
}
|
||||
size_t size() const BOOST_NOEXCEPT
|
||||
{
|
||||
return list_.size();
|
||||
}
|
||||
const_iterator begin() const BOOST_NOEXCEPT
|
||||
{
|
||||
return list_.begin();
|
||||
}
|
||||
const_iterator end() const BOOST_NOEXCEPT
|
||||
{
|
||||
return list_.end();
|
||||
}
|
||||
const char* what() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
return "exception_list";
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
} // parallel
|
||||
} // experimental
|
||||
} // boost
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef BOOST_THREAD_EXPERIMENTAL_PARALLEL_V1_INLINE_NAMESPACE_HPP
|
||||
#define BOOST_THREAD_EXPERIMENTAL_PARALLEL_V1_INLINE_NAMESPACE_HPP
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Vicente J. Botet Escriba 2014. 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/thread for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <boost/thread/experimental/config/inline_namespace.hpp>
|
||||
namespace boost {
|
||||
namespace experimental {
|
||||
namespace parallel {
|
||||
|
||||
BOOST_THREAD_INLINE_NAMESPACE(v1) {}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_INLINE_NAMESPACES)
|
||||
using namespace v1;
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef BOOST_THREAD_EXPERIMENTAL_PARALLEL_V2_INLINE_NAMESPACE_HPP
|
||||
#define BOOST_THREAD_EXPERIMENTAL_PARALLEL_V2_INLINE_NAMESPACE_HPP
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Vicente J. Botet Escriba 2014. 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/thread for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <boost/thread/experimental/config/inline_namespace.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace experimental {
|
||||
namespace parallel {
|
||||
|
||||
BOOST_THREAD_INLINE_NAMESPACE(v2) {}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_INLINE_NAMESPACES)
|
||||
using namespace v2;
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
320
include/boost/thread/experimental/parallel/v2/task_region.hpp
Executable file
320
include/boost/thread/experimental/parallel/v2/task_region.hpp
Executable file
@@ -0,0 +1,320 @@
|
||||
#ifndef BOOST_THREAD_EXPERIMENTAL_PARALLEL_V2_TASK_REGION_HPP
|
||||
#define BOOST_THREAD_EXPERIMENTAL_PARALLEL_V2_TASK_REGION_HPP
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Vicente J. Botet Escriba 2014. 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/thread for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#include <boost/thread/future.hpp>
|
||||
#if defined BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
#include <boost/thread/executors/basic_thread_pool.hpp>
|
||||
#endif
|
||||
#include <boost/thread/experimental/exception_list.hpp>
|
||||
#include <boost/thread/experimental/parallel/v2/inline_namespace.hpp>
|
||||
#include <boost/thread/detail/move.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
#define BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace experimental
|
||||
{
|
||||
namespace parallel
|
||||
{
|
||||
BOOST_THREAD_INLINE_NAMESPACE(v2)
|
||||
{
|
||||
class BOOST_SYMBOL_VISIBLE task_canceled_exception: public std::exception
|
||||
{
|
||||
public:
|
||||
//task_canceled_exception() BOOST_NOEXCEPT {}
|
||||
//task_canceled_exception(const task_canceled_exception&) BOOST_NOEXCEPT {}
|
||||
//task_canceled_exception& operator=(const task_canceled_exception&) BOOST_NOEXCEPT {}
|
||||
virtual const char* what() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return "task_canceled_exception";}
|
||||
};
|
||||
|
||||
template <class Executor>
|
||||
class task_region_handle_gen;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
void handle_task_region_exceptions(exception_list& errors)
|
||||
{
|
||||
try {
|
||||
boost::rethrow_exception(boost::current_exception());
|
||||
//throw boost::current_exception();
|
||||
}
|
||||
catch (task_canceled_exception& ex)
|
||||
{
|
||||
}
|
||||
catch (exception_list const& el)
|
||||
{
|
||||
for (exception_list::const_iterator it = el.begin(); it != el.end(); ++it)
|
||||
{
|
||||
boost::exception_ptr const& e = *it;
|
||||
try {
|
||||
rethrow_exception(e);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
handle_task_region_exceptions(errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
errors.add(boost::current_exception());
|
||||
}
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
|
||||
template <class TRH, class F>
|
||||
struct wrapped
|
||||
{
|
||||
TRH& tr;
|
||||
F f;
|
||||
wrapped(TRH& tr, BOOST_THREAD_RV_REF(F) f) : tr(tr), f(move(f))
|
||||
{}
|
||||
void operator()()
|
||||
{
|
||||
try
|
||||
{
|
||||
f();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
lock_guard<mutex> lk(tr.mtx);
|
||||
tr.canceled = true;
|
||||
handle_task_region_exceptions(tr.exs);
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class Executor>
|
||||
class task_region_handle_gen
|
||||
{
|
||||
private:
|
||||
// Private members and friends
|
||||
#if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
|
||||
template <class TRH, class F>
|
||||
friend struct detail::wrapped;
|
||||
#endif
|
||||
template <typename F>
|
||||
friend void task_region(BOOST_THREAD_FWD_REF(F) f);
|
||||
template<typename F>
|
||||
friend void task_region_final(BOOST_THREAD_FWD_REF(F) f);
|
||||
template <class Ex, typename F>
|
||||
friend void task_region(Ex&, BOOST_THREAD_FWD_REF(F) f);
|
||||
template<class Ex, typename F>
|
||||
friend void task_region_final(Ex&, BOOST_THREAD_FWD_REF(F) f);
|
||||
|
||||
void wait_all()
|
||||
{
|
||||
wait_for_all(group.begin(), group.end());
|
||||
|
||||
#if ! defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
|
||||
|
||||
for (group_type::iterator it = group.begin(); it != group.end(); ++it)
|
||||
{
|
||||
future<void>& f = *it;
|
||||
if (f.has_exception())
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::rethrow_exception(f.get_exception_ptr());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
detail::handle_task_region_exceptions(exs);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (exs.size() != 0)
|
||||
{
|
||||
boost::throw_exception(exs);
|
||||
//throw exs;
|
||||
}
|
||||
}
|
||||
protected:
|
||||
#if ! defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED && ! defined BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
task_region_handle_gen()
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED && defined BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
task_region_handle_gen()
|
||||
: canceled(false)
|
||||
, ex(0)
|
||||
{}
|
||||
task_region_handle_gen(Executor& ex)
|
||||
: canceled(false)
|
||||
, ex(&ex)
|
||||
{}
|
||||
|
||||
#endif
|
||||
|
||||
#if ! defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED && defined BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
task_region_handle_gen()
|
||||
: ex(0)
|
||||
{}
|
||||
task_region_handle_gen(Executor& ex)
|
||||
: ex(&ex)
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED && ! defined BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
task_region_handle_gen()
|
||||
: canceled(false)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
~task_region_handle_gen()
|
||||
{
|
||||
//wait_all();
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
|
||||
bool canceled;
|
||||
#endif
|
||||
#if defined BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
Executor* ex;
|
||||
#endif
|
||||
exception_list exs;
|
||||
typedef csbl::vector<future<void> > group_type;
|
||||
group_type group;
|
||||
mutable mutex mtx;
|
||||
|
||||
|
||||
public:
|
||||
BOOST_DELETED_FUNCTION(task_region_handle_gen(const task_region_handle_gen&))
|
||||
BOOST_DELETED_FUNCTION(task_region_handle_gen& operator=(const task_region_handle_gen&))
|
||||
BOOST_DELETED_FUNCTION(task_region_handle_gen* operator&() const)
|
||||
|
||||
public:
|
||||
template<typename F>
|
||||
void run(BOOST_THREAD_FWD_REF(F) f)
|
||||
{
|
||||
lock_guard<mutex> lk(mtx);
|
||||
#if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
|
||||
if (canceled) {
|
||||
boost::throw_exception(task_canceled_exception());
|
||||
//throw task_canceled_exception();
|
||||
}
|
||||
#if defined BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
group.push_back(async(*ex, detail::wrapped<task_region_handle_gen<Executor>, F>(*this, forward<F>(f))));
|
||||
#else
|
||||
group.push_back(async(detail::wrapped<task_region_handle_gen<Executor>, F>(*this, forward<F>(f))));
|
||||
#endif
|
||||
#else
|
||||
#if defined BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
group.push_back(async(*ex, forward<F>(f)));
|
||||
#else
|
||||
group.push_back(async(forward<F>(f)));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void wait()
|
||||
{
|
||||
lock_guard<mutex> lk(mtx);
|
||||
#if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
|
||||
if (canceled) {
|
||||
boost::throw_exception(task_canceled_exception());
|
||||
//throw task_canceled_exception{};
|
||||
}
|
||||
#endif
|
||||
wait_all();
|
||||
}
|
||||
};
|
||||
#if defined BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
typedef basic_thread_pool default_executor;
|
||||
#else
|
||||
typedef int default_executor;
|
||||
#endif
|
||||
class task_region_handle :
|
||||
public task_region_handle_gen<default_executor>
|
||||
{
|
||||
default_executor tp;
|
||||
template <typename F>
|
||||
friend void task_region(BOOST_THREAD_FWD_REF(F) f);
|
||||
template<typename F>
|
||||
friend void task_region_final(BOOST_THREAD_FWD_REF(F) f);
|
||||
|
||||
protected:
|
||||
task_region_handle() : task_region_handle_gen<default_executor>()
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
ex = &tp;
|
||||
#endif
|
||||
}
|
||||
BOOST_DELETED_FUNCTION(task_region_handle(const task_region_handle&))
|
||||
BOOST_DELETED_FUNCTION(task_region_handle& operator=(const task_region_handle&))
|
||||
BOOST_DELETED_FUNCTION(task_region_handle* operator&() const)
|
||||
|
||||
};
|
||||
|
||||
template <typename Executor, typename F>
|
||||
void task_region_final(Executor& ex, BOOST_THREAD_FWD_REF(F) f)
|
||||
{
|
||||
task_region_handle_gen<Executor> tr(ex);
|
||||
try
|
||||
{
|
||||
f(tr);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
lock_guard<mutex> lk(tr.mtx);
|
||||
detail::handle_task_region_exceptions(tr.exs);
|
||||
}
|
||||
tr.wait_all();
|
||||
}
|
||||
|
||||
template <typename Executor, typename F>
|
||||
void task_region(Executor& ex, BOOST_THREAD_FWD_REF(F) f)
|
||||
{
|
||||
task_region_final(ex, forward<F>(f));
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void task_region_final(BOOST_THREAD_FWD_REF(F) f)
|
||||
{
|
||||
task_region_handle tr;
|
||||
try
|
||||
{
|
||||
f(tr);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
lock_guard<mutex> lk(tr.mtx);
|
||||
detail::handle_task_region_exceptions(tr.exs);
|
||||
}
|
||||
tr.wait_all();
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void task_region(BOOST_THREAD_FWD_REF(F) f)
|
||||
{
|
||||
task_region_final(forward<F>(f));
|
||||
}
|
||||
|
||||
} // v2
|
||||
} // parallel
|
||||
} // experimental
|
||||
} // boost
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
#endif // header
|
||||
16
include/boost/thread/experimental/task_region.hpp
Normal file
16
include/boost/thread/experimental/task_region.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef BOOST_THREAD_EXPERIMENTAL_TASK_REGION_HPP
|
||||
#define BOOST_THREAD_EXPERIMENTAL_TASK_REGION_HPP
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Vicente J. Botet Escriba 2014. 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/thread for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <boost/thread/experimental/parallel/v2/task_region.hpp>
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
// (C) Copyright 2008-10 Anthony Williams
|
||||
// (C) Copyright 2011-2014 Vicente J. Botet Escriba
|
||||
// (C) Copyright 2011-2015 Vicente J. Botet Escriba
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -15,49 +15,51 @@
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
#include <boost/core/scoped_enum.hpp>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <boost/thread/exceptional_ptr.hpp>
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
#include <boost/thread/detail/move.hpp>
|
||||
#include <boost/thread/detail/invoker.hpp>
|
||||
#include <boost/thread/detail/invoke.hpp>
|
||||
#include <boost/thread/thread_time.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
#include <boost/thread/detail/is_convertible.hpp>
|
||||
#include <boost/thread/exceptional_ptr.hpp>
|
||||
#include <boost/thread/futures/future_error.hpp>
|
||||
#include <boost/thread/futures/future_error_code.hpp>
|
||||
#include <boost/thread/futures/future_status.hpp>
|
||||
#include <boost/thread/futures/is_future_type.hpp>
|
||||
#include <boost/thread/futures/launch.hpp>
|
||||
#include <boost/thread/futures/wait_for_all.hpp>
|
||||
#include <boost/thread/futures/wait_for_any.hpp>
|
||||
#include <boost/thread/lock_algorithms.hpp>
|
||||
#include <boost/thread/lock_types.hpp>
|
||||
#include <boost/exception_ptr.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
#include <boost/thread/thread_time.hpp>
|
||||
|
||||
#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
|
||||
#include <boost/optional.hpp>
|
||||
#else
|
||||
#include <boost/thread/csbl/memory/unique_ptr.hpp>
|
||||
//#include <boost/move/make_unique.hpp>
|
||||
#endif
|
||||
#include <boost/type_traits/is_fundamental.hpp>
|
||||
#include <boost/thread/detail/is_convertible.hpp>
|
||||
#include <boost/type_traits/decay.hpp>
|
||||
#include <boost/type_traits/is_void.hpp>
|
||||
#include <boost/type_traits/conditional.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <algorithm>
|
||||
#include <boost/function.hpp>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/core/ref.hpp>
|
||||
#include <boost/scoped_array.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <boost/next_prior.hpp>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/thread/future_error_code.hpp>
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
#include <boost/chrono/system_clocks.hpp>
|
||||
#endif
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/core/ref.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/exception_ptr.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/next_prior.hpp>
|
||||
#include <boost/scoped_array.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type_traits/conditional.hpp>
|
||||
#include <boost/type_traits/decay.hpp>
|
||||
#include <boost/type_traits/is_copy_constructible.hpp>
|
||||
#include <boost/type_traits/is_fundamental.hpp>
|
||||
#include <boost/type_traits/is_void.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
|
||||
#include <boost/thread/detail/memory.hpp>
|
||||
@@ -67,14 +69,15 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
|
||||
#include <boost/thread/csbl/tuple.hpp>
|
||||
#include <boost/thread/csbl/vector.hpp>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_FUTURE
|
||||
#define BOOST_THREAD_FUTURE future
|
||||
#else
|
||||
@@ -83,111 +86,6 @@
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
//enum class launch
|
||||
BOOST_SCOPED_ENUM_DECLARE_BEGIN(launch)
|
||||
{
|
||||
none = 0,
|
||||
async = 1,
|
||||
deferred = 2,
|
||||
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
executor = 4,
|
||||
#endif
|
||||
any = async | deferred
|
||||
}
|
||||
BOOST_SCOPED_ENUM_DECLARE_END(launch)
|
||||
|
||||
//enum class future_status
|
||||
BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_status)
|
||||
{
|
||||
ready,
|
||||
timeout,
|
||||
deferred
|
||||
}
|
||||
BOOST_SCOPED_ENUM_DECLARE_END(future_status)
|
||||
|
||||
class BOOST_SYMBOL_VISIBLE future_error
|
||||
: public std::logic_error
|
||||
{
|
||||
system::error_code ec_;
|
||||
public:
|
||||
future_error(system::error_code ec)
|
||||
: logic_error(ec.message()),
|
||||
ec_(ec)
|
||||
{
|
||||
}
|
||||
|
||||
const system::error_code& code() const BOOST_NOEXCEPT
|
||||
{
|
||||
return ec_;
|
||||
}
|
||||
};
|
||||
|
||||
class BOOST_SYMBOL_VISIBLE future_uninitialized:
|
||||
public future_error
|
||||
{
|
||||
public:
|
||||
future_uninitialized() :
|
||||
future_error(system::make_error_code(future_errc::no_state))
|
||||
{}
|
||||
};
|
||||
class BOOST_SYMBOL_VISIBLE broken_promise:
|
||||
public future_error
|
||||
{
|
||||
public:
|
||||
broken_promise():
|
||||
future_error(system::make_error_code(future_errc::broken_promise))
|
||||
{}
|
||||
};
|
||||
class BOOST_SYMBOL_VISIBLE future_already_retrieved:
|
||||
public future_error
|
||||
{
|
||||
public:
|
||||
future_already_retrieved():
|
||||
future_error(system::make_error_code(future_errc::future_already_retrieved))
|
||||
{}
|
||||
};
|
||||
class BOOST_SYMBOL_VISIBLE promise_already_satisfied:
|
||||
public future_error
|
||||
{
|
||||
public:
|
||||
promise_already_satisfied():
|
||||
future_error(system::make_error_code(future_errc::promise_already_satisfied))
|
||||
{}
|
||||
};
|
||||
|
||||
class BOOST_SYMBOL_VISIBLE task_already_started:
|
||||
public future_error
|
||||
{
|
||||
public:
|
||||
task_already_started():
|
||||
future_error(system::make_error_code(future_errc::promise_already_satisfied))
|
||||
{}
|
||||
};
|
||||
|
||||
class BOOST_SYMBOL_VISIBLE task_moved:
|
||||
public future_error
|
||||
{
|
||||
public:
|
||||
task_moved():
|
||||
future_error(system::make_error_code(future_errc::no_state))
|
||||
{}
|
||||
};
|
||||
|
||||
class promise_moved:
|
||||
public future_error
|
||||
{
|
||||
public:
|
||||
promise_moved():
|
||||
future_error(system::make_error_code(future_errc::no_state))
|
||||
{}
|
||||
};
|
||||
|
||||
namespace future_state
|
||||
{
|
||||
enum state { uninitialized, waiting, ready, moved, deferred };
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct relocker
|
||||
@@ -220,6 +118,7 @@ namespace boost
|
||||
struct shared_state_base : enable_shared_from_this<shared_state_base>
|
||||
{
|
||||
typedef std::list<boost::condition_variable_any*> waiter_list;
|
||||
typedef waiter_list::iterator notify_when_ready_handle;
|
||||
// This type should be only included conditionally if interruptions are allowed, but is included to maintain the same layout.
|
||||
typedef shared_ptr<shared_state_base> continuation_ptr_type;
|
||||
|
||||
@@ -267,14 +166,14 @@ namespace boost
|
||||
policy_ = launch::executor;
|
||||
}
|
||||
#endif
|
||||
waiter_list::iterator register_external_waiter(boost::condition_variable_any& cv)
|
||||
notify_when_ready_handle notify_when_ready(boost::condition_variable_any& cv)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(this->mutex);
|
||||
do_callback(lock);
|
||||
return external_waiters.insert(external_waiters.end(),&cv);
|
||||
}
|
||||
|
||||
void remove_external_waiter(waiter_list::iterator it)
|
||||
void unnotify_when_ready(notify_when_ready_handle it)
|
||||
{
|
||||
boost::lock_guard<boost::mutex> lock(this->mutex);
|
||||
external_waiters.erase(it);
|
||||
@@ -431,27 +330,6 @@ namespace boost
|
||||
mark_exceptional_finish_internal(boost::current_exception(), lock);
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// void mark_interrupted_finish()
|
||||
// {
|
||||
// boost::unique_lock<boost::mutex> lock(this->mutex);
|
||||
// exception = boost::copy_exception(boost::thread_interrupted());
|
||||
// mark_finished_internal(lock);
|
||||
// }
|
||||
|
||||
// void set_interrupted_at_thread_exit()
|
||||
// {
|
||||
// unique_lock<boost::mutex> lk(this->mutex);
|
||||
// if (has_value(lk))
|
||||
// {
|
||||
// throw_exception(promise_already_satisfied());
|
||||
// }
|
||||
// exception = boost::copy_exception(boost::thread_interrupted());
|
||||
// this->is_constructed = true;
|
||||
// detail::make_ready_at_thread_exit(shared_from_this());
|
||||
// }
|
||||
#endif
|
||||
|
||||
void set_exception_at_thread_exit(exception_ptr e)
|
||||
{
|
||||
unique_lock<boost::mutex> lk(this->mutex);
|
||||
@@ -481,20 +359,22 @@ namespace boost
|
||||
return done && exception;
|
||||
}
|
||||
|
||||
// bool has_exception(unique_lock<boost::mutex>&) const
|
||||
// {
|
||||
// return done && exception;
|
||||
// }
|
||||
|
||||
// bool is_deferred(boost::lock_guard<boost::mutex>&) const {
|
||||
// return is_deferred_;
|
||||
// }
|
||||
|
||||
launch launch_policy(boost::unique_lock<boost::mutex>&) const
|
||||
{
|
||||
return policy_;
|
||||
}
|
||||
|
||||
future_state::state get_state(boost::unique_lock<boost::mutex>& lk) const
|
||||
{
|
||||
if(!done)
|
||||
{
|
||||
return future_state::waiting;
|
||||
}
|
||||
else
|
||||
{
|
||||
return future_state::ready;
|
||||
}
|
||||
}
|
||||
future_state::state get_state() const
|
||||
{
|
||||
boost::lock_guard<boost::mutex> guard(this->mutex);
|
||||
@@ -514,11 +394,6 @@ namespace boost
|
||||
wait_internal(lock, false);
|
||||
return exception;
|
||||
}
|
||||
// exception_ptr get_exception_ptr(boost::unique_lock<boost::mutex>& lock)
|
||||
// {
|
||||
// wait_internal(lock, false);
|
||||
// return exception;
|
||||
// }
|
||||
|
||||
template<typename F,typename U>
|
||||
void set_wait_callback(F f,U* u)
|
||||
@@ -982,13 +857,13 @@ namespace boost
|
||||
struct registered_waiter
|
||||
{
|
||||
boost::shared_ptr<detail::shared_state_base> future_;
|
||||
detail::shared_state_base::waiter_list::iterator wait_iterator;
|
||||
detail::shared_state_base::notify_when_ready_handle handle;
|
||||
count_type index;
|
||||
|
||||
registered_waiter(boost::shared_ptr<detail::shared_state_base> const& a_future,
|
||||
detail::shared_state_base::waiter_list::iterator wait_iterator_,
|
||||
detail::shared_state_base::notify_when_ready_handle handle_,
|
||||
count_type index_):
|
||||
future_(a_future),wait_iterator(wait_iterator_),index(index_)
|
||||
future_(a_future),handle(handle_),index(index_)
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -1039,11 +914,11 @@ namespace boost
|
||||
{
|
||||
if(f.future_)
|
||||
{
|
||||
registered_waiter waiter(f.future_,f.future_->register_external_waiter(cv),future_count);
|
||||
registered_waiter waiter(f.future_,f.future_->notify_when_ready(cv),future_count);
|
||||
try {
|
||||
futures.push_back(waiter);
|
||||
} catch(...) {
|
||||
f.future_->remove_external_waiter(waiter.wait_iterator);
|
||||
f.future_->unnotify_when_ready(waiter.handle);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
@@ -1078,7 +953,7 @@ namespace boost
|
||||
{
|
||||
for(count_type i=0;i<futures.size();++i)
|
||||
{
|
||||
futures[i].future_->remove_external_waiter(futures[i].wait_iterator);
|
||||
futures[i].future_->unnotify_when_ready(futures[i].handle);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1092,93 +967,28 @@ namespace boost
|
||||
class shared_future;
|
||||
|
||||
template<typename T>
|
||||
struct is_future_type
|
||||
struct is_future_type<BOOST_THREAD_FUTURE<T> > : true_type
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value=false);
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_future_type<BOOST_THREAD_FUTURE<T> >
|
||||
struct is_future_type<shared_future<T> > : true_type
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value=true);
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_future_type<shared_future<T> >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value=true);
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename Iterator>
|
||||
typename boost::disable_if<is_future_type<Iterator>,void>::type wait_for_all(Iterator begin,Iterator end)
|
||||
{
|
||||
for(Iterator current=begin;current!=end;++current)
|
||||
{
|
||||
current->wait();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
template<typename F1,typename F2>
|
||||
typename boost::enable_if<is_future_type<F1>,void>::type wait_for_all(F1& f1,F2& f2)
|
||||
{
|
||||
f1.wait();
|
||||
f2.wait();
|
||||
}
|
||||
|
||||
template<typename F1,typename F2,typename F3>
|
||||
void wait_for_all(F1& f1,F2& f2,F3& f3)
|
||||
{
|
||||
f1.wait();
|
||||
f2.wait();
|
||||
f3.wait();
|
||||
}
|
||||
|
||||
template<typename F1,typename F2,typename F3,typename F4>
|
||||
void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4)
|
||||
{
|
||||
f1.wait();
|
||||
f2.wait();
|
||||
f3.wait();
|
||||
f4.wait();
|
||||
}
|
||||
|
||||
template<typename F1,typename F2,typename F3,typename F4,typename F5>
|
||||
void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5)
|
||||
{
|
||||
f1.wait();
|
||||
f2.wait();
|
||||
f3.wait();
|
||||
f4.wait();
|
||||
f5.wait();
|
||||
}
|
||||
#else
|
||||
template<typename F1, typename... Fs>
|
||||
void wait_for_all(F1& f1, Fs&... fs)
|
||||
{
|
||||
bool dummy[] = { (f1.wait(), true), (fs.wait(), true)... };
|
||||
|
||||
// prevent unused parameter warning
|
||||
(void) dummy;
|
||||
}
|
||||
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template<typename Iterator>
|
||||
typename boost::disable_if<is_future_type<Iterator>,Iterator>::type wait_for_any(Iterator begin,Iterator end)
|
||||
{
|
||||
if(begin==end)
|
||||
return end;
|
||||
|
||||
detail::future_waiter waiter;
|
||||
for(Iterator current=begin;current!=end;++current)
|
||||
{
|
||||
waiter.add(*current);
|
||||
}
|
||||
return boost::next(begin,waiter.wait());
|
||||
}
|
||||
// template<typename Iterator>
|
||||
// typename boost::disable_if<is_future_type<Iterator>,Iterator>::type wait_for_any(Iterator begin,Iterator end)
|
||||
// {
|
||||
// if(begin==end)
|
||||
// return end;
|
||||
//
|
||||
// detail::future_waiter waiter;
|
||||
// for(Iterator current=begin;current!=end;++current)
|
||||
// {
|
||||
// waiter.add(*current);
|
||||
// }
|
||||
// return boost::next(begin,waiter.wait());
|
||||
// }
|
||||
|
||||
#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
template<typename F1,typename F2>
|
||||
@@ -1243,6 +1053,7 @@ namespace boost
|
||||
/// Common implementation for all the futures independently of the return type
|
||||
class base_future
|
||||
{
|
||||
public:
|
||||
};
|
||||
/// Common implementation for future and shared_future.
|
||||
template <typename R>
|
||||
@@ -1308,6 +1119,14 @@ namespace boost
|
||||
future_.swap(that.future_);
|
||||
}
|
||||
// functions to check state, and wait for ready
|
||||
state get_state(boost::unique_lock<boost::mutex>& lk) const
|
||||
{
|
||||
if(!future_)
|
||||
{
|
||||
return future_state::uninitialized;
|
||||
}
|
||||
return future_->get_state(lk);
|
||||
}
|
||||
state get_state() const
|
||||
{
|
||||
if(!future_)
|
||||
@@ -1322,6 +1141,10 @@ namespace boost
|
||||
return get_state()==future_state::ready;
|
||||
}
|
||||
|
||||
bool is_ready(boost::unique_lock<boost::mutex>& lk) const
|
||||
{
|
||||
return get_state(lk)==future_state::ready;
|
||||
}
|
||||
bool has_exception() const
|
||||
{
|
||||
return future_ && future_->has_exception();
|
||||
@@ -1359,6 +1182,34 @@ namespace boost
|
||||
future_->wait(false);
|
||||
}
|
||||
|
||||
typedef detail::shared_state_base::notify_when_ready_handle notify_when_ready_handle;
|
||||
|
||||
boost::mutex& mutex() {
|
||||
if(!future_)
|
||||
{
|
||||
boost::throw_exception(future_uninitialized());
|
||||
}
|
||||
return future_->mutex;
|
||||
};
|
||||
|
||||
notify_when_ready_handle notify_when_ready(boost::condition_variable_any& cv)
|
||||
{
|
||||
if(!future_)
|
||||
{
|
||||
boost::throw_exception(future_uninitialized());
|
||||
}
|
||||
return future_->notify_when_ready(cv);
|
||||
}
|
||||
|
||||
void unnotify_when_ready(notify_when_ready_handle h)
|
||||
{
|
||||
if(!future_)
|
||||
{
|
||||
boost::throw_exception(future_uninitialized());
|
||||
}
|
||||
return future_->unnotify_when_ready(h);
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
template<typename Duration>
|
||||
bool timed_wait(Duration const& rel_time) const
|
||||
@@ -2612,12 +2463,6 @@ namespace boost
|
||||
this->set_value_at_thread_exit(f());
|
||||
}
|
||||
#endif
|
||||
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// catch(thread_interrupted& )
|
||||
// {
|
||||
// this->set_interrupted_at_thread_exit();
|
||||
// }
|
||||
//#endif
|
||||
catch(...)
|
||||
{
|
||||
this->set_exception_at_thread_exit(current_exception());
|
||||
@@ -2693,12 +2538,6 @@ namespace boost
|
||||
this->set_value_at_thread_exit(f());
|
||||
}
|
||||
#endif
|
||||
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// catch(thread_interrupted& )
|
||||
// {
|
||||
// this->set_interrupted_at_thread_exit();
|
||||
// }
|
||||
//#endif
|
||||
catch(...)
|
||||
{
|
||||
this->set_exception_at_thread_exit(current_exception());
|
||||
@@ -2777,12 +2616,6 @@ namespace boost
|
||||
this->set_value_at_thread_exit(boost::move(r));
|
||||
}
|
||||
#endif
|
||||
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// catch(thread_interrupted& )
|
||||
// {
|
||||
// this->set_interrupted_at_thread_exit();
|
||||
// }
|
||||
//#endif
|
||||
catch(...)
|
||||
{
|
||||
this->set_exception_at_thread_exit(current_exception());
|
||||
@@ -2858,12 +2691,6 @@ namespace boost
|
||||
this->set_value_at_thread_exit(f());
|
||||
}
|
||||
#endif
|
||||
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// catch(thread_interrupted& )
|
||||
// {
|
||||
// this->set_interrupted_at_thread_exit();
|
||||
// }
|
||||
//#endif
|
||||
catch(...)
|
||||
{
|
||||
this->set_exception_at_thread_exit(current_exception());
|
||||
@@ -2935,12 +2762,6 @@ namespace boost
|
||||
#endif
|
||||
this->set_value_at_thread_exit();
|
||||
}
|
||||
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// catch(thread_interrupted& )
|
||||
// {
|
||||
// this->set_interrupted_at_thread_exit();
|
||||
// }
|
||||
//#endif
|
||||
catch(...)
|
||||
{
|
||||
this->set_exception_at_thread_exit(current_exception());
|
||||
@@ -3008,12 +2829,6 @@ namespace boost
|
||||
#endif
|
||||
this->set_value_at_thread_exit();
|
||||
}
|
||||
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// catch(thread_interrupted& )
|
||||
// {
|
||||
// this->set_interrupted_at_thread_exit();
|
||||
// }
|
||||
//#endif
|
||||
catch(...)
|
||||
{
|
||||
this->set_exception_at_thread_exit(current_exception());
|
||||
@@ -3936,11 +3751,11 @@ namespace detail {
|
||||
return BOOST_THREAD_MAKE_RV_REF(p.get_future());
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_USES_MOVE
|
||||
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined BOOST_THREAD_USES_MOVE
|
||||
inline BOOST_THREAD_FUTURE<void> make_ready_future() {
|
||||
promise<void> p;
|
||||
p.set_value();
|
||||
return BOOST_THREAD_MAKE_RV_REF(p.get_future());
|
||||
return p.get_future();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -3950,6 +3765,43 @@ namespace detail {
|
||||
p.set_exception(ex);
|
||||
return BOOST_THREAD_MAKE_RV_REF(p.get_future());
|
||||
}
|
||||
namespace detail {
|
||||
template <typename R, class T>
|
||||
struct make_ready_future_workaround {
|
||||
template <class F>
|
||||
BOOST_THREAD_FUTURE<R> operator()(BOOST_THREAD_FUTURE<T> fut, BOOST_THREAD_FWD_REF(F) fct) {
|
||||
return make_ready_future(fct(boost::move(fut)));
|
||||
}
|
||||
};
|
||||
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined BOOST_THREAD_USES_MOVE
|
||||
template <class T>
|
||||
struct make_ready_future_workaround<void, T> {
|
||||
template <class F>
|
||||
BOOST_THREAD_FUTURE<void> operator()(BOOST_THREAD_FUTURE<T> fut, BOOST_THREAD_FWD_REF(F) fct) {
|
||||
fct(boost::move(fut));
|
||||
return make_ready_future();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
template <typename R, class T>
|
||||
struct make_ready_shared_future_workaround {
|
||||
template <class F>
|
||||
BOOST_THREAD_FUTURE<R> operator()(shared_future<T> fut, BOOST_THREAD_FWD_REF(F) fct) {
|
||||
return make_ready_future(fct(boost::move(fut)));
|
||||
}
|
||||
};
|
||||
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined BOOST_THREAD_USES_MOVE
|
||||
template <class T>
|
||||
struct make_ready_shared_future_workaround<void, T> {
|
||||
template <class F>
|
||||
BOOST_THREAD_FUTURE<void> operator()(shared_future<T> fut, BOOST_THREAD_FWD_REF(F) fct) {
|
||||
fct(boost::move(fut));
|
||||
return make_ready_future();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
BOOST_THREAD_FUTURE<T> make_exceptional_future(exception_ptr ex) {
|
||||
@@ -4525,7 +4377,11 @@ namespace detail
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
|
||||
|
||||
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
|
||||
if (underlying_cast<int>(policy) & int(launch::async)) {
|
||||
if (this->is_ready(lock)) {
|
||||
lock.unlock();
|
||||
return boost::detail::make_ready_future_workaround<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type, R>()(
|
||||
boost::move(*this), boost::forward<F>(func));
|
||||
} else if (underlying_cast<int>(policy) & int(launch::async)) {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
|
||||
lock, boost::move(*this), boost::forward<F>(func)
|
||||
)));
|
||||
@@ -4548,9 +4404,15 @@ namespace detail
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
|
||||
|
||||
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type, F>(ex,
|
||||
if (this->is_ready(lock)) {
|
||||
lock.unlock();
|
||||
return boost::detail::make_ready_future_workaround<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type, R>()(
|
||||
boost::move(*this), boost::forward<F>(func));
|
||||
} else {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type, F>(ex,
|
||||
lock, boost::move(*this), boost::forward<F>(func)
|
||||
)));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
template <typename R>
|
||||
@@ -4561,7 +4423,11 @@ namespace detail
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
|
||||
|
||||
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
|
||||
if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::async)) {
|
||||
if (this->is_ready(lock)) {
|
||||
lock.unlock();
|
||||
return boost::detail::make_ready_future_workaround<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type, R>()(
|
||||
boost::move(*this), boost::forward<F>(func));
|
||||
} else if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::async)) {
|
||||
return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
|
||||
lock, boost::move(*this), boost::forward<F>(func)
|
||||
);
|
||||
@@ -4577,6 +4443,93 @@ namespace detail
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
// template<typename F>
|
||||
// auto future<future<R2>>::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
|
||||
////////////////////////////////
|
||||
|
||||
template <typename R2>
|
||||
template <typename F>
|
||||
inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
|
||||
BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(launch policy, BOOST_THREAD_FWD_REF(F) func) {
|
||||
typedef BOOST_THREAD_FUTURE<R2> R;
|
||||
typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
|
||||
|
||||
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
|
||||
if (this->is_ready(lock)) {
|
||||
lock.unlock();
|
||||
return boost::detail::make_ready_future_workaround<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type, R>()(
|
||||
boost::move(*this), boost::forward<F>(func));
|
||||
} else if (underlying_cast<int>(policy) & int(launch::async)) {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
|
||||
lock, boost::move(*this), boost::forward<F>(func)
|
||||
)));
|
||||
} else if (underlying_cast<int>(policy) & int(launch::deferred)) {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
|
||||
lock, boost::move(*this), boost::forward<F>(func)
|
||||
)));
|
||||
} else {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
|
||||
lock, boost::move(*this), boost::forward<F>(func)
|
||||
)));
|
||||
}
|
||||
}
|
||||
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
template <typename R2>
|
||||
template <typename Ex, typename F>
|
||||
inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
|
||||
BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) {
|
||||
typedef BOOST_THREAD_FUTURE<R2> R;
|
||||
typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
|
||||
|
||||
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
|
||||
if (this->is_ready(lock)) {
|
||||
lock.unlock();
|
||||
return boost::detail::make_ready_future_workaround<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type, R>()(
|
||||
boost::move(*this), boost::forward<F>(func));
|
||||
} else {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type, F>(ex,
|
||||
lock, boost::move(*this), boost::forward<F>(func)
|
||||
)));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
template <typename R2>
|
||||
template <typename F>
|
||||
inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
|
||||
BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(BOOST_THREAD_FWD_REF(F) func) {
|
||||
typedef BOOST_THREAD_FUTURE<R2> R;
|
||||
typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
|
||||
|
||||
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
|
||||
if (this->is_ready(lock)) {
|
||||
lock.unlock();
|
||||
return boost::detail::make_ready_future_workaround<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type, R>()(
|
||||
boost::move(*this), boost::forward<F>(func));
|
||||
} else if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::async)) {
|
||||
return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
|
||||
lock, boost::move(*this), boost::forward<F>(func)
|
||||
);
|
||||
} else if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::deferred)) {
|
||||
this->future_->wait_internal(lock);
|
||||
return boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
|
||||
lock, boost::move(*this), boost::forward<F>(func)
|
||||
);
|
||||
} else {
|
||||
return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
|
||||
lock, boost::move(*this), boost::forward<F>(func)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
// template<typename F>
|
||||
// auto shared_future<R>::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
|
||||
////////////////////////////////
|
||||
|
||||
template <typename R>
|
||||
template <typename F>
|
||||
inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
|
||||
@@ -4586,8 +4539,11 @@ namespace detail
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
|
||||
|
||||
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
|
||||
|
||||
if (underlying_cast<int>(policy) & int(launch::async)) {
|
||||
if (this->is_ready(lock)) {
|
||||
lock.unlock();
|
||||
return boost::detail::make_ready_shared_future_workaround<typename boost::result_of<F(shared_future<R>)>::type, R>()(
|
||||
boost::move(*this), boost::forward<F>(func));
|
||||
} else if (underlying_cast<int>(policy) & int(launch::async)) {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
|
||||
lock, *this, boost::forward<F>(func)
|
||||
)));
|
||||
@@ -4611,9 +4567,15 @@ namespace detail
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
|
||||
|
||||
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type, F>(ex,
|
||||
if (this->is_ready(lock)) {
|
||||
lock.unlock();
|
||||
return boost::detail::make_ready_shared_future_workaround<typename boost::result_of<F(shared_future<R>)>::type, R>()(
|
||||
boost::move(*this), boost::forward<F>(func));
|
||||
} else {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type, F>(ex,
|
||||
lock, *this, boost::forward<F>(func)
|
||||
)));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4626,7 +4588,11 @@ namespace detail
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
|
||||
|
||||
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
|
||||
if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::async)) {
|
||||
if (this->is_ready(lock)) {
|
||||
lock.unlock();
|
||||
return boost::detail::make_ready_shared_future_workaround<typename boost::result_of<F(shared_future<R>)>::type, R>()(
|
||||
boost::move(*this), boost::forward<F>(func));
|
||||
} else if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::async)) {
|
||||
return boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
|
||||
lock, *this, boost::forward<F>(func));
|
||||
} else if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::deferred)) {
|
||||
@@ -4663,7 +4629,7 @@ namespace detail
|
||||
: value_(v)
|
||||
{}
|
||||
|
||||
T operator()(BOOST_THREAD_FUTURE<T> fut) {
|
||||
T operator()(BOOST_THREAD_FUTURE<T> fut) const {
|
||||
return fut.get_or(value_);
|
||||
|
||||
}
|
||||
@@ -4740,6 +4706,18 @@ namespace detail
|
||||
{
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
|
||||
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
|
||||
if (this->is_ready(lock)) {
|
||||
lock.unlock();
|
||||
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
return boost::move(this->get());
|
||||
#elif defined BOOST_THREAD_USES_MOVE
|
||||
BOOST_THREAD_FUTURE<R2> res = this->get();
|
||||
return boost::move(res);
|
||||
#else
|
||||
BOOST_THREAD_FUTURE<R2> res = this->get();
|
||||
return boost::move(res);
|
||||
#endif
|
||||
}
|
||||
return boost::detail::make_future_unwrap_shared_state<BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >, R2>(lock, boost::move(*this));
|
||||
}
|
||||
#endif
|
||||
|
||||
98
include/boost/thread/futures/future_error.hpp
Normal file
98
include/boost/thread/futures/future_error.hpp
Normal file
@@ -0,0 +1,98 @@
|
||||
// (C) Copyright 2008-10 Anthony Williams
|
||||
// (C) Copyright 2011-2015 Vicente J. Botet Escriba
|
||||
//
|
||||
// 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)
|
||||
|
||||
#ifndef BOOST_THREAD_FUTURES_FUTURE_ERROR_HPP
|
||||
#define BOOST_THREAD_FUTURES_FUTURE_ERROR_HPP
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#include <boost/thread/futures/future_error_code.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
class BOOST_SYMBOL_VISIBLE future_error
|
||||
: public std::logic_error
|
||||
{
|
||||
system::error_code ec_;
|
||||
public:
|
||||
future_error(system::error_code ec)
|
||||
: logic_error(ec.message()),
|
||||
ec_(ec)
|
||||
{
|
||||
}
|
||||
|
||||
const system::error_code& code() const BOOST_NOEXCEPT
|
||||
{
|
||||
return ec_;
|
||||
}
|
||||
};
|
||||
|
||||
class BOOST_SYMBOL_VISIBLE future_uninitialized:
|
||||
public future_error
|
||||
{
|
||||
public:
|
||||
future_uninitialized() :
|
||||
future_error(system::make_error_code(future_errc::no_state))
|
||||
{}
|
||||
};
|
||||
class BOOST_SYMBOL_VISIBLE broken_promise:
|
||||
public future_error
|
||||
{
|
||||
public:
|
||||
broken_promise():
|
||||
future_error(system::make_error_code(future_errc::broken_promise))
|
||||
{}
|
||||
};
|
||||
class BOOST_SYMBOL_VISIBLE future_already_retrieved:
|
||||
public future_error
|
||||
{
|
||||
public:
|
||||
future_already_retrieved():
|
||||
future_error(system::make_error_code(future_errc::future_already_retrieved))
|
||||
{}
|
||||
};
|
||||
class BOOST_SYMBOL_VISIBLE promise_already_satisfied:
|
||||
public future_error
|
||||
{
|
||||
public:
|
||||
promise_already_satisfied():
|
||||
future_error(system::make_error_code(future_errc::promise_already_satisfied))
|
||||
{}
|
||||
};
|
||||
|
||||
class BOOST_SYMBOL_VISIBLE task_already_started:
|
||||
public future_error
|
||||
{
|
||||
public:
|
||||
task_already_started():
|
||||
future_error(system::make_error_code(future_errc::promise_already_satisfied))
|
||||
{}
|
||||
};
|
||||
|
||||
class BOOST_SYMBOL_VISIBLE task_moved:
|
||||
public future_error
|
||||
{
|
||||
public:
|
||||
task_moved():
|
||||
future_error(system::make_error_code(future_errc::no_state))
|
||||
{}
|
||||
};
|
||||
|
||||
class promise_moved:
|
||||
public future_error
|
||||
{
|
||||
public:
|
||||
promise_moved():
|
||||
future_error(system::make_error_code(future_errc::no_state))
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // header
|
||||
@@ -1,12 +1,12 @@
|
||||
// (C) Copyright 2008-10 Anthony Williams
|
||||
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
|
||||
// (C) Copyright 2011-2012,2015 Vicente J. Botet Escriba
|
||||
//
|
||||
// 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)
|
||||
|
||||
#ifndef BOOST_THREAD_FUTURE_ERROR_CODE_HPP
|
||||
#define BOOST_THREAD_FUTURE_ERROR_CODE_HPP
|
||||
#ifndef BOOST_THREAD_FUTURES_FUTURE_ERROR_CODE_HPP
|
||||
#define BOOST_THREAD_FUTURES_FUTURE_ERROR_CODE_HPP
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/core/scoped_enum.hpp>
|
||||
30
include/boost/thread/futures/future_status.hpp
Normal file
30
include/boost/thread/futures/future_status.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
// (C) Copyright 2008-10 Anthony Williams
|
||||
// (C) Copyright 2011-2015 Vicente J. Botet Escriba
|
||||
//
|
||||
// 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)
|
||||
|
||||
#ifndef BOOST_THREAD_FUTURES_FUTURE_STATUS_HPP
|
||||
#define BOOST_THREAD_FUTURES_FUTURE_STATUS_HPP
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/core/scoped_enum.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
//enum class future_status
|
||||
BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_status)
|
||||
{
|
||||
ready,
|
||||
timeout,
|
||||
deferred
|
||||
}
|
||||
BOOST_SCOPED_ENUM_DECLARE_END(future_status)
|
||||
namespace future_state
|
||||
{
|
||||
enum state { uninitialized, waiting, ready, moved, deferred };
|
||||
}
|
||||
}
|
||||
|
||||
#endif // header
|
||||
21
include/boost/thread/futures/is_future_type.hpp
Normal file
21
include/boost/thread/futures/is_future_type.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
// (C) Copyright 2008-10 Anthony Williams
|
||||
// (C) Copyright 2011-2015 Vicente J. Botet Escriba
|
||||
//
|
||||
// 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)
|
||||
|
||||
#ifndef BOOST_THREAD_FUTURES_IS_FUTURE_TYPE_HPP
|
||||
#define BOOST_THREAD_FUTURES_IS_FUTURE_TYPE_HPP
|
||||
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template<typename T>
|
||||
struct is_future_type : false_type
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
#endif // header
|
||||
30
include/boost/thread/futures/launch.hpp
Normal file
30
include/boost/thread/futures/launch.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
// (C) Copyright 2008-10 Anthony Williams
|
||||
// (C) Copyright 2011-2015 Vicente J. Botet Escriba
|
||||
//
|
||||
// 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)
|
||||
|
||||
#ifndef BOOST_THREAD_FUTURES_LAUNCH_HPP
|
||||
#define BOOST_THREAD_FUTURES_LAUNCH_HPP
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/core/scoped_enum.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
//enum class launch
|
||||
BOOST_SCOPED_ENUM_DECLARE_BEGIN(launch)
|
||||
{
|
||||
none = 0,
|
||||
async = 1,
|
||||
deferred = 2,
|
||||
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
executor = 4,
|
||||
#endif
|
||||
any = async | deferred
|
||||
}
|
||||
BOOST_SCOPED_ENUM_DECLARE_END(launch)
|
||||
}
|
||||
|
||||
#endif // header
|
||||
74
include/boost/thread/futures/wait_for_all.hpp
Normal file
74
include/boost/thread/futures/wait_for_all.hpp
Normal file
@@ -0,0 +1,74 @@
|
||||
// (C) Copyright 2008-10 Anthony Williams
|
||||
// (C) Copyright 2011-2015 Vicente J. Botet Escriba
|
||||
//
|
||||
// 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)
|
||||
|
||||
#ifndef BOOST_THREAD_FUTURES_WAIT_FOR_ALL_HPP
|
||||
#define BOOST_THREAD_FUTURES_WAIT_FOR_ALL_HPP
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/thread/futures/is_future_type.hpp>
|
||||
|
||||
#include <boost/core/enable_if.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template<typename Iterator>
|
||||
typename boost::disable_if<is_future_type<Iterator>,void>::type wait_for_all(Iterator begin,Iterator end)
|
||||
{
|
||||
for(Iterator current=begin;current!=end;++current)
|
||||
{
|
||||
current->wait();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
template<typename F1,typename F2>
|
||||
typename boost::enable_if<is_future_type<F1>,void>::type wait_for_all(F1& f1,F2& f2)
|
||||
{
|
||||
f1.wait();
|
||||
f2.wait();
|
||||
}
|
||||
|
||||
template<typename F1,typename F2,typename F3>
|
||||
void wait_for_all(F1& f1,F2& f2,F3& f3)
|
||||
{
|
||||
f1.wait();
|
||||
f2.wait();
|
||||
f3.wait();
|
||||
}
|
||||
|
||||
template<typename F1,typename F2,typename F3,typename F4>
|
||||
void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4)
|
||||
{
|
||||
f1.wait();
|
||||
f2.wait();
|
||||
f3.wait();
|
||||
f4.wait();
|
||||
}
|
||||
|
||||
template<typename F1,typename F2,typename F3,typename F4,typename F5>
|
||||
void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5)
|
||||
{
|
||||
f1.wait();
|
||||
f2.wait();
|
||||
f3.wait();
|
||||
f4.wait();
|
||||
f5.wait();
|
||||
}
|
||||
#else
|
||||
template<typename F1, typename... Fs>
|
||||
void wait_for_all(F1& f1, Fs&... fs)
|
||||
{
|
||||
bool dummy[] = { (f1.wait(), true), (fs.wait(), true)... };
|
||||
|
||||
// prevent unused parameter warning
|
||||
(void) dummy;
|
||||
}
|
||||
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)}
|
||||
|
||||
}
|
||||
|
||||
#endif // header
|
||||
161
include/boost/thread/futures/wait_for_any.hpp
Normal file
161
include/boost/thread/futures/wait_for_any.hpp
Normal file
@@ -0,0 +1,161 @@
|
||||
// (C) Copyright 2008-10 Anthony Williams
|
||||
// (C) Copyright 2011-2015 Vicente J. Botet Escriba
|
||||
//
|
||||
// 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)
|
||||
|
||||
#ifndef BOOST_THREAD_FUTURES_WAIT_FOR_ANY_HPP
|
||||
#define BOOST_THREAD_FUTURES_WAIT_FOR_ANY_HPP
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#include <boost/thread/detail/move.hpp>
|
||||
#include <boost/thread/futures/is_future_type.hpp>
|
||||
#include <boost/thread/lock_algorithms.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/next_prior.hpp>
|
||||
#include <boost/scoped_array.hpp>
|
||||
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template <class Future>
|
||||
class waiter_for_any_in_seq
|
||||
{
|
||||
struct registered_waiter;
|
||||
typedef std::vector<int>::size_type count_type;
|
||||
|
||||
struct registered_waiter
|
||||
{
|
||||
typedef Future future_type;
|
||||
future_type* future_;
|
||||
typedef typename Future::notify_when_ready_handle notify_when_ready_handle;
|
||||
notify_when_ready_handle handle;
|
||||
count_type index;
|
||||
|
||||
registered_waiter(future_type & a_future,
|
||||
notify_when_ready_handle handle_, count_type index_) :
|
||||
future_(&a_future), handle(handle_), index(index_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct all_futures_lock
|
||||
{
|
||||
#ifdef _MANAGED
|
||||
typedef std::ptrdiff_t count_type_portable;
|
||||
#else
|
||||
typedef count_type count_type_portable;
|
||||
#endif
|
||||
count_type_portable count;
|
||||
boost::scoped_array<boost::unique_lock<boost::mutex> > locks;
|
||||
|
||||
all_futures_lock(std::vector<registered_waiter>& waiters) :
|
||||
count(waiters.size()), locks(new boost::unique_lock<boost::mutex>[count])
|
||||
{
|
||||
for (count_type_portable i = 0; i < count; ++i)
|
||||
{
|
||||
locks[i] = BOOST_THREAD_MAKE_RV_REF(boost::unique_lock<boost::mutex>(waiters[i].future_->mutex()));
|
||||
}
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
boost::lock(locks.get(), locks.get() + count);
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
for (count_type_portable i = 0; i < count; ++i)
|
||||
{
|
||||
locks[i].unlock();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
boost::condition_variable_any cv;
|
||||
std::vector<registered_waiter> waiters;
|
||||
count_type future_count;
|
||||
|
||||
public:
|
||||
waiter_for_any_in_seq() :
|
||||
future_count(0)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void add(F& f)
|
||||
{
|
||||
if (f.valid())
|
||||
{
|
||||
registered_waiter waiter(f, f.notify_when_ready(cv), future_count);
|
||||
try
|
||||
{
|
||||
waiters.push_back(waiter);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
f.future_->unnotify_when_ready(waiter.handle);
|
||||
throw;
|
||||
}
|
||||
++future_count;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
template <typename F1, typename ... Fs>
|
||||
void add(F1& f1, Fs&... fs)
|
||||
{
|
||||
add(f1);
|
||||
add(fs...);
|
||||
}
|
||||
#endif
|
||||
|
||||
count_type wait()
|
||||
{
|
||||
all_futures_lock lk(waiters);
|
||||
for (;;)
|
||||
{
|
||||
for (count_type i = 0; i < waiters.size(); ++i)
|
||||
{
|
||||
if (waiters[i].future_->is_ready(lk.locks[i]))
|
||||
{
|
||||
return waiters[i].index;
|
||||
}
|
||||
}
|
||||
cv.wait(lk);
|
||||
}
|
||||
}
|
||||
|
||||
~waiter_for_any_in_seq()
|
||||
{
|
||||
for (count_type i = 0; i < waiters.size(); ++i)
|
||||
{
|
||||
waiters[i].future_->unnotify_when_ready(waiters[i].handle);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
typename boost::disable_if<is_future_type<Iterator> , Iterator>::type wait_for_any(Iterator begin, Iterator end)
|
||||
{
|
||||
if (begin == end) return end;
|
||||
|
||||
detail::waiter_for_any_in_seq<typename std::iterator_traits<Iterator>::value_type> waiter;
|
||||
for (Iterator current = begin; current != end; ++current)
|
||||
{
|
||||
waiter.add(*current);
|
||||
}
|
||||
return boost::next(begin, waiter.wait());
|
||||
}
|
||||
}
|
||||
|
||||
#endif // header
|
||||
@@ -25,7 +25,9 @@
|
||||
#include <utility>
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#include <asm/page.h> // http://code.google.com/p/android/issues/detail?id=39983
|
||||
# ifndef PAGE_SIZE
|
||||
# define PAGE_SIZE 4096
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/thread/detail/delete.hpp>
|
||||
#include <boost/thread/detail/move.hpp>
|
||||
#include <boost/thread/sync_queue.hpp>
|
||||
#include <boost/thread/concurrent_queues/sync_queue.hpp>
|
||||
#include <boost/thread/detail/work.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
@@ -39,7 +39,7 @@ namespace boost
|
||||
work task;
|
||||
try
|
||||
{
|
||||
if (work_queue.try_pull_front(task) == queue_op_status::success)
|
||||
if (work_queue.try_pull(task) == queue_op_status::success)
|
||||
{
|
||||
task();
|
||||
return true;
|
||||
@@ -144,23 +144,23 @@ namespace boost
|
||||
void submit(Closure & closure)
|
||||
{
|
||||
work w ((closure));
|
||||
work_queue.push_back(boost::move(w));
|
||||
work_queue.push(boost::move(w));
|
||||
//work_queue.push(work(closure)); // todo check why this doesn't work
|
||||
}
|
||||
#endif
|
||||
void submit(void (*closure)())
|
||||
{
|
||||
work w ((closure));
|
||||
work_queue.push_back(boost::move(w));
|
||||
//work_queue.push_back(work(closure)); // todo check why this doesn't work
|
||||
work_queue.push(boost::move(w));
|
||||
//work_queue.push(work(closure)); // todo check why this doesn't work
|
||||
}
|
||||
|
||||
template <typename Closure>
|
||||
void submit(BOOST_THREAD_RV_REF(Closure) closure)
|
||||
{
|
||||
work w =boost::move(closure);
|
||||
work_queue.push_back(boost::move(w));
|
||||
//work_queue.push_back(work(boost::move(closure))); // todo check why this doesn't work
|
||||
work_queue.push(boost::move(w));
|
||||
//work_queue.push(work(boost::move(closure))); // todo check why this doesn't work
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
|
||||
#include <boost/thread/future_error_code.hpp>
|
||||
#include <boost/thread/futures/future_error_code.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace boost
|
||||
|
||||
@@ -36,8 +36,6 @@
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "./timeconv.inl"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
// Copyright (C) 2001-2003
|
||||
// William E. Kempf
|
||||
// Copyright (C) 2009 Anthony Williams
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// boostinspect:nounnamed
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
namespace {
|
||||
const int MILLISECONDS_PER_SECOND = 1000;
|
||||
const int NANOSECONDS_PER_SECOND = 1000000000;
|
||||
const int NANOSECONDS_PER_MILLISECOND = 1000000;
|
||||
|
||||
const int MICROSECONDS_PER_SECOND = 1000000;
|
||||
const int NANOSECONDS_PER_MICROSECOND = 1000;
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
inline void to_time(int milliseconds, boost::xtime& xt)
|
||||
{
|
||||
int res = 0;
|
||||
res = boost::xtime_get(&xt, boost::TIME_UTC_);
|
||||
BOOST_ASSERT(res == boost::TIME_UTC_); (void)res;
|
||||
|
||||
xt.sec += (milliseconds / MILLISECONDS_PER_SECOND);
|
||||
xt.nsec += ((milliseconds % MILLISECONDS_PER_SECOND) *
|
||||
NANOSECONDS_PER_MILLISECOND);
|
||||
|
||||
if (xt.nsec >= NANOSECONDS_PER_SECOND)
|
||||
{
|
||||
++xt.sec;
|
||||
xt.nsec -= NANOSECONDS_PER_SECOND;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(BOOST_HAS_PTHREADS)
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
inline void to_timespec(const boost::xtime& xt, timespec& ts)
|
||||
{
|
||||
ts.tv_sec = static_cast<int>(xt.sec);
|
||||
ts.tv_nsec = static_cast<int>(xt.nsec);
|
||||
if(ts.tv_nsec >= NANOSECONDS_PER_SECOND)
|
||||
{
|
||||
ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
|
||||
ts.tv_nsec %= NANOSECONDS_PER_SECOND;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
inline void to_time(int milliseconds, timespec& ts)
|
||||
{
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
boost::xtime xt;
|
||||
to_time(milliseconds, xt);
|
||||
to_timespec(xt, ts);
|
||||
#else
|
||||
ts.tv_sec += (milliseconds / MILLISECONDS_PER_SECOND);
|
||||
ts.tv_nsec += ((milliseconds % MILLISECONDS_PER_SECOND) *
|
||||
NANOSECONDS_PER_MILLISECOND);
|
||||
|
||||
if (ts.tv_nsec >= NANOSECONDS_PER_SECOND)
|
||||
{
|
||||
++ts.tv_sec;
|
||||
ts.tv_nsec -= NANOSECONDS_PER_SECOND;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
inline void to_timespec_duration(const boost::xtime& xt, timespec& ts)
|
||||
{
|
||||
boost::xtime cur;
|
||||
int res = 0;
|
||||
res = boost::xtime_get(&cur, boost::TIME_UTC_);
|
||||
BOOST_ASSERT(res == boost::TIME_UTC_); (void)res;
|
||||
|
||||
if (boost::xtime_cmp(xt, cur) <= 0)
|
||||
{
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ts.tv_sec = xt.sec - cur.sec;
|
||||
ts.tv_nsec = xt.nsec - cur.nsec;
|
||||
|
||||
if( ts.tv_nsec < 0 )
|
||||
{
|
||||
ts.tv_sec -= 1;
|
||||
ts.tv_nsec += NANOSECONDS_PER_SECOND;
|
||||
}
|
||||
if(ts.tv_nsec >= NANOSECONDS_PER_SECOND)
|
||||
{
|
||||
ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
|
||||
ts.tv_nsec %= NANOSECONDS_PER_SECOND;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
inline void to_duration(boost::xtime xt, int& milliseconds)
|
||||
{
|
||||
boost::xtime cur;
|
||||
int res = 0;
|
||||
res = boost::xtime_get(&cur, boost::TIME_UTC_);
|
||||
BOOST_ASSERT(res == boost::TIME_UTC_); (void)res;
|
||||
|
||||
if (boost::xtime_cmp(xt, cur) <= 0)
|
||||
milliseconds = 0;
|
||||
else
|
||||
{
|
||||
if (cur.nsec > xt.nsec)
|
||||
{
|
||||
xt.nsec += NANOSECONDS_PER_SECOND;
|
||||
--xt.sec;
|
||||
}
|
||||
milliseconds = (int)((xt.sec - cur.sec) * MILLISECONDS_PER_SECOND) +
|
||||
(((xt.nsec - cur.nsec) + (NANOSECONDS_PER_MILLISECOND/2)) /
|
||||
NANOSECONDS_PER_MILLISECOND);
|
||||
}
|
||||
}
|
||||
|
||||
inline void to_microduration(boost::xtime xt, int& microseconds)
|
||||
{
|
||||
boost::xtime cur;
|
||||
int res = 0;
|
||||
res = boost::xtime_get(&cur, boost::TIME_UTC_);
|
||||
BOOST_ASSERT(res == boost::TIME_UTC_); (void)res;
|
||||
|
||||
if (boost::xtime_cmp(xt, cur) <= 0)
|
||||
microseconds = 0;
|
||||
else
|
||||
{
|
||||
if (cur.nsec > xt.nsec)
|
||||
{
|
||||
xt.nsec += NANOSECONDS_PER_SECOND;
|
||||
--xt.sec;
|
||||
}
|
||||
microseconds = (int)((xt.sec - cur.sec) * MICROSECONDS_PER_SECOND) +
|
||||
(((xt.nsec - cur.nsec) + (NANOSECONDS_PER_MICROSECOND/2)) /
|
||||
NANOSECONDS_PER_MICROSECOND);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Change Log:
|
||||
// 1 Jun 01 Initial creation.
|
||||
@@ -529,11 +529,13 @@ namespace boost
|
||||
|
||||
unsigned thread::physical_concurrency() BOOST_NOEXCEPT
|
||||
{
|
||||
#if BOOST_PLAT_WINDOWS_RUNTIME
|
||||
return hardware_concurrency();
|
||||
// a bit too strict: Windows XP with SP3 would be sufficient
|
||||
#if BOOST_PLAT_WINDOWS_RUNTIME \
|
||||
|| ( BOOST_USE_WINAPI_VERSION <= BOOST_WINAPI_VERSION_WINXP ) \
|
||||
|| ( defined(__MINGW32__) && !defined(__MINGW64__) )
|
||||
return 0;
|
||||
#else
|
||||
unsigned cores = 0;
|
||||
#if !(defined(__MINGW32__) || defined (__MINGW64__))
|
||||
DWORD size = 0;
|
||||
|
||||
GetLogicalProcessorInformation(NULL, &size);
|
||||
@@ -550,7 +552,6 @@ namespace boost
|
||||
if (buffer[i].Relationship == RelationProcessorCore)
|
||||
++cores;
|
||||
}
|
||||
#endif
|
||||
return cores;
|
||||
#endif
|
||||
}
|
||||
@@ -636,7 +637,7 @@ namespace boost
|
||||
|
||||
bool interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time)
|
||||
{
|
||||
detail::win32::handle handles[3]={0};
|
||||
detail::win32::handle handles[4]={0};
|
||||
unsigned handle_count=0;
|
||||
unsigned wait_handle_index=~0U;
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
// 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)
|
||||
|
||||
// boostinspect:nounnamed
|
||||
|
||||
namespace {
|
||||
const int MILLISECONDS_PER_SECOND = 1000;
|
||||
const int NANOSECONDS_PER_SECOND = 1000000000;
|
||||
const int NANOSECONDS_PER_MILLISECOND = 1000000;
|
||||
|
||||
const int MICROSECONDS_PER_SECOND = 1000000;
|
||||
const int NANOSECONDS_PER_MICROSECOND = 1000;
|
||||
|
||||
inline void to_time(int milliseconds, boost::xtime& xt)
|
||||
{
|
||||
int res = 0;
|
||||
res = boost::xtime_get(&xt, boost::TIME_UTC_);
|
||||
assert(res == boost::TIME_UTC_);
|
||||
|
||||
xt.sec += (milliseconds / MILLISECONDS_PER_SECOND);
|
||||
xt.nsec += ((milliseconds % MILLISECONDS_PER_SECOND) *
|
||||
NANOSECONDS_PER_MILLISECOND);
|
||||
|
||||
if (xt.nsec >= NANOSECONDS_PER_SECOND)
|
||||
{
|
||||
++xt.sec;
|
||||
xt.nsec -= NANOSECONDS_PER_SECOND;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BOOST_HAS_PTHREADS)
|
||||
inline void to_timespec(const boost::xtime& xt, timespec& ts)
|
||||
{
|
||||
ts.tv_sec = static_cast<int>(xt.sec);
|
||||
ts.tv_nsec = static_cast<int>(xt.nsec);
|
||||
if(ts.tv_nsec >= NANOSECONDS_PER_SECOND)
|
||||
{
|
||||
ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
|
||||
ts.tv_nsec %= NANOSECONDS_PER_SECOND;
|
||||
}
|
||||
}
|
||||
|
||||
inline void to_time(int milliseconds, timespec& ts)
|
||||
{
|
||||
boost::xtime xt;
|
||||
to_time(milliseconds, xt);
|
||||
to_timespec(xt, ts);
|
||||
}
|
||||
|
||||
inline void to_timespec_duration(const boost::xtime& xt, timespec& ts)
|
||||
{
|
||||
boost::xtime cur;
|
||||
int res = 0;
|
||||
res = boost::xtime_get(&cur, boost::TIME_UTC_);
|
||||
assert(res == boost::TIME_UTC_);
|
||||
|
||||
if (boost::xtime_cmp(xt, cur) <= 0)
|
||||
{
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ts.tv_sec = xt.sec - cur.sec;
|
||||
ts.tv_nsec = xt.nsec - cur.nsec;
|
||||
|
||||
if( ts.tv_nsec < 0 )
|
||||
{
|
||||
ts.tv_sec -= 1;
|
||||
ts.tv_nsec += NANOSECONDS_PER_SECOND;
|
||||
}
|
||||
if(ts.tv_nsec >= NANOSECONDS_PER_SECOND)
|
||||
{
|
||||
ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
|
||||
ts.tv_nsec %= NANOSECONDS_PER_SECOND;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void to_duration(boost::xtime xt, int& milliseconds)
|
||||
{
|
||||
boost::xtime cur;
|
||||
int res = 0;
|
||||
res = boost::xtime_get(&cur, boost::TIME_UTC_);
|
||||
assert(res == boost::TIME_UTC_);
|
||||
|
||||
if (boost::xtime_cmp(xt, cur) <= 0)
|
||||
milliseconds = 0;
|
||||
else
|
||||
{
|
||||
if (cur.nsec > xt.nsec)
|
||||
{
|
||||
xt.nsec += NANOSECONDS_PER_SECOND;
|
||||
--xt.sec;
|
||||
}
|
||||
milliseconds = (int)((xt.sec - cur.sec) * MILLISECONDS_PER_SECOND) +
|
||||
(((xt.nsec - cur.nsec) + (NANOSECONDS_PER_MILLISECOND/2)) /
|
||||
NANOSECONDS_PER_MILLISECOND);
|
||||
}
|
||||
}
|
||||
|
||||
inline void to_microduration(boost::xtime xt, int& microseconds)
|
||||
{
|
||||
boost::xtime cur;
|
||||
int res = 0;
|
||||
res = boost::xtime_get(&cur, boost::TIME_UTC_);
|
||||
assert(res == boost::TIME_UTC_);
|
||||
|
||||
if (boost::xtime_cmp(xt, cur) <= 0)
|
||||
microseconds = 0;
|
||||
else
|
||||
{
|
||||
if (cur.nsec > xt.nsec)
|
||||
{
|
||||
xt.nsec += NANOSECONDS_PER_SECOND;
|
||||
--xt.sec;
|
||||
}
|
||||
microseconds = (int)((xt.sec - cur.sec) * MICROSECONDS_PER_SECOND) +
|
||||
(((xt.nsec - cur.nsec) + (NANOSECONDS_PER_MICROSECOND/2)) /
|
||||
NANOSECONDS_PER_MICROSECOND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Change Log:
|
||||
// 1 Jun 01 Initial creation.
|
||||
@@ -73,5 +73,13 @@ namespace boost
|
||||
}
|
||||
}
|
||||
|
||||
#else //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_DLL)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// Prevent LNK4221 warning with link=static
|
||||
namespace boost { namespace link_static_warning_inhibit {
|
||||
extern __declspec(dllexport) void foo() { }
|
||||
} }
|
||||
#endif
|
||||
|
||||
#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_DLL)
|
||||
|
||||
@@ -34,6 +34,7 @@ project
|
||||
<toolset>gcc:<cxxflags>-Wno-variadic-macros
|
||||
#<toolset>gcc:<cxxflags>-Wunused-local-typedefs
|
||||
<toolset>gcc:<cxxflags>-Wunused-function
|
||||
<toolset>gcc:<cxxflags>-Wno-unused-parameter
|
||||
|
||||
<toolset>darwin:<cxxflags>-Wextra
|
||||
<toolset>darwin:<cxxflags>-pedantic
|
||||
@@ -43,18 +44,20 @@ project
|
||||
<toolset>darwin:<cxxflags>-Wno-variadic-macros
|
||||
#<toolset>darwin:<cxxflags>-Wunused-local-typedefs
|
||||
<toolset>darwin:<cxxflags>-Wunused-function
|
||||
<toolset>darwin:<cxxflags>-Wno-unused-parameter
|
||||
|
||||
#<toolset>pathscale:<cxxflags>-Wextra
|
||||
<toolset>pathscale:<cxxflags>-Wno-long-long
|
||||
<toolset>pathscale:<cxxflags>-pedantic
|
||||
|
||||
<toolset>clang:<warnings>on
|
||||
<toolset>clang:<cxxflags>-Wextra
|
||||
#<toolset>clang:<cxxflags>-pedantic
|
||||
<toolset>clang:<warnings>on
|
||||
<toolset>clang:<cxxflags>-Wno-long-long
|
||||
#<toolset>clang:<cxxflags>-ansi
|
||||
#<toolset>clang:<cxxflags>-fpermissive # doesn't work
|
||||
<toolset>clang:<cxxflags>-Wunused-function
|
||||
<toolset>clang:<cxxflags>-Wno-unused-parameter
|
||||
|
||||
#<toolset>gcc-mingw-4.4.0:<cxxflags>-fdiagnostics-show-option
|
||||
#<toolset>gcc-mingw-4.5.0:<cxxflags>-fdiagnostics-show-option
|
||||
@@ -97,6 +100,10 @@ project
|
||||
<toolset>intel:<cxxflags>-wd593,981
|
||||
<toolset>intel:<cxxflags>-wd1418
|
||||
<toolset>intel:<cxxflags>-wd2415
|
||||
|
||||
<toolset>msvc:<cxxflags>/wd4100
|
||||
<toolset>msvc:<cxxflags>/wd4512
|
||||
<toolset>msvc:<cxxflags>/wd6246
|
||||
;
|
||||
|
||||
rule thread-run ( sources )
|
||||
@@ -115,7 +122,7 @@ rule thread-test ( sources )
|
||||
sources = $(sources) winrt_init.cpp ;
|
||||
return
|
||||
[ run $(sources) ../build//boost_thread : : :
|
||||
<library>/boost/test//boost_unit_test_framework/<link>static
|
||||
<library>/boost/test//boost_unit_test_framework
|
||||
]
|
||||
[ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
|
||||
: : :
|
||||
@@ -286,8 +293,10 @@ rule thread-compile ( sources : reqs * : name )
|
||||
[ thread-run test_7328.cpp ]
|
||||
[ thread-run test_7571.cpp ]
|
||||
[ thread-run test_9319.cpp ]
|
||||
[ thread-run test_9711.cpp ]
|
||||
|
||||
#[ thread-run test_9711.cpp ] this test is invalid and should not work :(
|
||||
[ thread-run test_9856.cpp ]
|
||||
[ thread-compile test_10963.cpp : : test_10963_c ]
|
||||
[ thread-run test_10964.cpp ]
|
||||
;
|
||||
|
||||
|
||||
@@ -676,6 +685,12 @@ rule thread-compile ( sources : reqs * : name )
|
||||
[ thread-run2-noit ./sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp : sync_queue__multi_thread_p ]
|
||||
;
|
||||
|
||||
test-suite ts_sync_deque
|
||||
:
|
||||
[ thread-run2-noit ./sync/mutual_exclusion/sync_deque/single_thread_pass.cpp : sync_deque__single_thread_p ]
|
||||
[ thread-run2-noit ./sync/mutual_exclusion/sync_deque/multi_thread_pass.cpp : sync_deque__multi_thread_p ]
|
||||
;
|
||||
|
||||
test-suite ts_sync_bounded_queue
|
||||
:
|
||||
[ thread-run2-noit ./sync/mutual_exclusion/sync_bounded_queue/single_thread_pass.cpp : sync_bounded_q_single_thread_p ]
|
||||
@@ -707,6 +722,12 @@ rule thread-compile ( sources : reqs * : name )
|
||||
#[ thread-run2-noit ./sync/mutual_exclusion/queue_views/multi_thread_pass.cpp : queue_views__multi_thread_p ]
|
||||
;
|
||||
|
||||
test-suite ts_deque_views
|
||||
:
|
||||
[ thread-run2-noit ./sync/mutual_exclusion/deque_views/single_thread_pass.cpp : deque_views__single_thread_p ]
|
||||
#[ thread-run2-noit ./sync/mutual_exclusion/deque_views/multi_thread_pass.cpp : deque_views__multi_thread_p ]
|
||||
;
|
||||
|
||||
#explicit ts_this_thread ;
|
||||
test-suite ts_this_thread
|
||||
:
|
||||
@@ -791,7 +812,7 @@ rule thread-compile ( sources : reqs * : name )
|
||||
[ thread-run2 ../example/parallel_accumulate.cpp : ex_parallel_accumulate ]
|
||||
[ thread-run2 ../example/parallel_quick_sort.cpp : ex_parallel_quick_sort ]
|
||||
[ thread-run2 ../example/with_lock_guard.cpp : ex_with_lock_guard ]
|
||||
|
||||
[ thread-run2 ../example/fib_task_region.cpp : ex_fib_task_region ]
|
||||
;
|
||||
|
||||
#explicit ts_shared_upwards ;
|
||||
@@ -909,6 +930,19 @@ rule thread-compile ( sources : reqs * : name )
|
||||
#[ thread-run ../example/perf_condition_variable.cpp ]
|
||||
#[ thread-run ../example/perf_shared_mutex.cpp ]
|
||||
;
|
||||
|
||||
|
||||
#explicit ts_exception_list ;
|
||||
test-suite ts_exception_list
|
||||
:
|
||||
[ thread-run2-noit ./experimental/parallel/v1/exception_list_pass.cpp : exception_list_p ]
|
||||
;
|
||||
|
||||
#explicit ts_task_region ;
|
||||
test-suite ts_task_region
|
||||
:
|
||||
[ thread-run2-noit ./experimental/parallel/v2/task_region_pass.cpp : task_region_p ]
|
||||
;
|
||||
|
||||
explicit ts_ ;
|
||||
test-suite ts_
|
||||
|
||||
23
test/experimental/parallel/v1/exception_list_pass.cpp
Normal file
23
test/experimental/parallel/v1/exception_list_pass.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright (C) 2014 Vicente J. Botet Escriba
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// <boost/thread/experimental/parallel/v1/exception_list.hpp>
|
||||
|
||||
|
||||
#define BOOST_THREAD_VERSION 4
|
||||
#include <boost/config.hpp>
|
||||
#if ! defined BOOST_NO_CXX11_DECLTYPE
|
||||
#define BOOST_RESULT_OF_USE_DECLTYPE
|
||||
#endif
|
||||
|
||||
#include <boost/thread/experimental/parallel/v1/exception_list.hpp>
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
return boost::report_errors();
|
||||
}
|
||||
293
test/experimental/parallel/v2/task_region_pass.cpp
Normal file
293
test/experimental/parallel/v2/task_region_pass.cpp
Normal file
@@ -0,0 +1,293 @@
|
||||
// Copyright (C) 2014 Vicente J. Botet Escriba
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// <boost/thread/experimental/parallel/v1/exception_list.hpp>
|
||||
|
||||
|
||||
#define BOOST_THREAD_VERSION 4
|
||||
#define BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
#include <boost/config.hpp>
|
||||
#if ! defined BOOST_NO_CXX11_DECLTYPE
|
||||
#define BOOST_RESULT_OF_USE_DECLTYPE
|
||||
#endif
|
||||
|
||||
#include <boost/thread/experimental/parallel/v2/task_region.hpp>
|
||||
#include <string>
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#if ! defined BOOST_NO_CXX11_LAMBDAS && defined(BOOST_THREAD_PROVIDES_INVOKE)
|
||||
using boost::experimental::parallel::v2::task_region;
|
||||
using boost::experimental::parallel::v2::task_region_handle;
|
||||
using boost::experimental::parallel::v1::exception_list;
|
||||
|
||||
void run_no_exception()
|
||||
{
|
||||
std::string s("test");
|
||||
bool parent_flag = false;
|
||||
bool task1_flag = false;
|
||||
bool task2_flag = false;
|
||||
bool task21_flag = false;
|
||||
bool task3_flag = false;
|
||||
task_region([&](task_region_handle& trh)
|
||||
{
|
||||
parent_flag = true;
|
||||
trh.run([&]()
|
||||
{
|
||||
task1_flag = true;
|
||||
std::cout << "task1: " << s << std::endl;
|
||||
});
|
||||
trh.run([&]()
|
||||
{
|
||||
task2_flag = true;
|
||||
std::cout << "task2" << std::endl;
|
||||
task_region([&](task_region_handle& trh)
|
||||
{
|
||||
trh.run([&]()
|
||||
{
|
||||
task21_flag = true;
|
||||
std::cout << "task2.1" << std::endl;
|
||||
});
|
||||
});
|
||||
});
|
||||
int i = 0, j = 10, k = 20;
|
||||
trh.run([=, &task3_flag]()
|
||||
{
|
||||
task3_flag = true;
|
||||
std::cout << "task3: " << i << " " << j << " " << k << std::endl;
|
||||
});
|
||||
std::cout << "parent" << std::endl;
|
||||
});
|
||||
BOOST_TEST(parent_flag);
|
||||
BOOST_TEST(task1_flag);
|
||||
BOOST_TEST(task2_flag);
|
||||
BOOST_TEST(task21_flag);
|
||||
BOOST_TEST(task3_flag);
|
||||
}
|
||||
|
||||
void run_no_exception_wait()
|
||||
{
|
||||
std::string s("test");
|
||||
bool parent_flag = false;
|
||||
bool wait_flag = false;
|
||||
bool task1_flag = false;
|
||||
bool task2_flag = false;
|
||||
bool task21_flag = false;
|
||||
bool task3_flag = false;
|
||||
task_region([&](task_region_handle& trh)
|
||||
{
|
||||
parent_flag = true;
|
||||
trh.run([&]()
|
||||
{
|
||||
task1_flag = true;
|
||||
std::cout << "task1: " << s << std::endl;
|
||||
});
|
||||
trh.run([&]()
|
||||
{
|
||||
task2_flag = true;
|
||||
std::cout << "task2" << std::endl;
|
||||
task_region([&](task_region_handle& trh)
|
||||
{
|
||||
trh.run([&]()
|
||||
{
|
||||
task21_flag = true;
|
||||
std::cout << "task2.1" << std::endl;
|
||||
});
|
||||
});
|
||||
});
|
||||
int i = 0, j = 10, k = 20;
|
||||
trh.run([=, &task3_flag]()
|
||||
{
|
||||
task3_flag = true;
|
||||
std::cout << "task3: " << i << " " << j << " " << k << std::endl;
|
||||
});
|
||||
std::cout << "before" << std::endl;
|
||||
trh.wait();
|
||||
wait_flag = true;
|
||||
std::cout << "parent" << std::endl;
|
||||
});
|
||||
BOOST_TEST(parent_flag);
|
||||
BOOST_TEST(wait_flag);
|
||||
BOOST_TEST(task1_flag);
|
||||
BOOST_TEST(task2_flag);
|
||||
BOOST_TEST(task21_flag);
|
||||
BOOST_TEST(task3_flag);
|
||||
}
|
||||
|
||||
void run_exception_1()
|
||||
{
|
||||
try
|
||||
{
|
||||
task_region([](task_region_handle& trh)
|
||||
{
|
||||
trh.run([]()
|
||||
{
|
||||
std::cout << "task1" << std::endl;
|
||||
throw 1;
|
||||
});
|
||||
boost::this_thread::sleep_for(boost::chrono::seconds(1));
|
||||
trh.run([]()
|
||||
{
|
||||
std::cout << "task3" << std::endl;
|
||||
});
|
||||
BOOST_TEST(false);
|
||||
});
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
catch (exception_list const& e)
|
||||
{
|
||||
BOOST_TEST_EQ(e.size(), 1u);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
}
|
||||
|
||||
void run_exception()
|
||||
{
|
||||
try
|
||||
{
|
||||
task_region([](task_region_handle& trh)
|
||||
{
|
||||
trh.run([]()
|
||||
{
|
||||
std::cout << "task1" << std::endl;
|
||||
throw 1;
|
||||
});
|
||||
trh.run([]()
|
||||
{
|
||||
std::cout << "task2" << std::endl;
|
||||
throw 2;
|
||||
});
|
||||
boost::this_thread::sleep_for(boost::chrono::seconds(1));
|
||||
trh.run([]()
|
||||
{
|
||||
std::cout << "task3" << std::endl;
|
||||
throw 3;
|
||||
});
|
||||
std::cout << "parent" << std::endl;
|
||||
throw 100;
|
||||
});
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
catch (exception_list const& el)
|
||||
{
|
||||
BOOST_TEST(el.size() >= 1u);
|
||||
for (boost::exception_ptr const& e: el)
|
||||
{
|
||||
try {
|
||||
boost::rethrow_exception(e);
|
||||
}
|
||||
catch (boost::exception&)
|
||||
{
|
||||
BOOST_TEST(true);
|
||||
}
|
||||
catch (int i) // this doesn't works yet
|
||||
{
|
||||
BOOST_TEST((i == 1) || (i == 2) || (i == 3));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void run_nested_exception()
|
||||
{
|
||||
std::string s("test");
|
||||
bool parent_flag = false;
|
||||
bool task1_flag = false;
|
||||
bool task2_flag = false;
|
||||
bool task21_flag = false;
|
||||
bool task3_flag = false;
|
||||
try
|
||||
{
|
||||
task_region([&](task_region_handle& trh)
|
||||
{
|
||||
parent_flag = true;
|
||||
trh.run([&]()
|
||||
{
|
||||
task1_flag = true;
|
||||
std::cout << "task1: " << s << std::endl;
|
||||
});
|
||||
trh.run([&]()
|
||||
{
|
||||
task2_flag = true;
|
||||
std::cout << "task2" << std::endl;
|
||||
task_region([&](task_region_handle& trh)
|
||||
{
|
||||
trh.run([&]()
|
||||
{
|
||||
task21_flag = true;
|
||||
std::cout << "task2.1" << std::endl;
|
||||
throw 21;
|
||||
});
|
||||
});
|
||||
});
|
||||
int i = 0, j = 10, k = 20;
|
||||
trh.run([=, &task3_flag]()
|
||||
{
|
||||
task3_flag = true;
|
||||
std::cout << "task3: " << i << " " << j << " " << k << std::endl;
|
||||
});
|
||||
std::cout << "parent" << std::endl;
|
||||
});
|
||||
}
|
||||
catch (exception_list const& el)
|
||||
{
|
||||
BOOST_TEST(el.size() == 1u);
|
||||
for (boost::exception_ptr const& e: el)
|
||||
{
|
||||
try {
|
||||
boost::rethrow_exception(e);
|
||||
}
|
||||
catch (int i) // this doesn't works yet
|
||||
{
|
||||
BOOST_TEST_EQ(i, 21);
|
||||
}
|
||||
catch (boost::exception&)
|
||||
{
|
||||
BOOST_TEST(true);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
BOOST_TEST(parent_flag);
|
||||
BOOST_TEST(task1_flag);
|
||||
BOOST_TEST(task2_flag);
|
||||
BOOST_TEST(task21_flag);
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
run_no_exception();
|
||||
run_no_exception_wait();
|
||||
run_exception();
|
||||
run_exception_1();
|
||||
run_nested_exception();
|
||||
return boost::report_errors();
|
||||
}
|
||||
#else
|
||||
int main()
|
||||
{
|
||||
return boost::report_errors();
|
||||
}
|
||||
#endif
|
||||
455
test/sync/mutual_exclusion/deque_views/single_thread_pass.cpp
Normal file
455
test/sync/mutual_exclusion/deque_views/single_thread_pass.cpp
Normal file
@@ -0,0 +1,455 @@
|
||||
// Copyright (C) 2014 Vicente J. Botet Escriba
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// <boost/thread/sync_deque.hpp>
|
||||
|
||||
// class sync_deque<T>
|
||||
|
||||
// sync_deque();
|
||||
|
||||
#define BOOST_THREAD_VERSION 4
|
||||
//#define BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
|
||||
#include <boost/thread/concurrent_queues/sync_deque.hpp>
|
||||
#include <boost/thread/concurrent_queues/deque_adaptor.hpp>
|
||||
#include <boost/thread/concurrent_queues/deque_views.hpp>
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
class non_copyable
|
||||
{
|
||||
BOOST_THREAD_MOVABLE_ONLY(non_copyable)
|
||||
int val;
|
||||
public:
|
||||
non_copyable(int v) : val(v){}
|
||||
non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {}
|
||||
non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; }
|
||||
bool operator==(non_copyable const& x) const {return val==x.val;}
|
||||
template <typename OSTREAM>
|
||||
friend OSTREAM& operator <<(OSTREAM& os, non_copyable const&x )
|
||||
{
|
||||
os << x.val;
|
||||
return os;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
BOOST_STATIC_ASSERT( ! boost::is_copy_constructible<non_copyable>::value );
|
||||
BOOST_STATIC_ASSERT( boost::has_move_emulation_enabled<non_copyable>::value );
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
{
|
||||
// default queue invariants
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_back<int> q(sq);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// default queue invariants
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_front<int> q(sq);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
// empty queue try_pull fails
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_front<int> q(sq);
|
||||
int i;
|
||||
BOOST_TEST( boost::queue_op_status::empty == q.try_pull(i));
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue push rvalue/copyable succeeds
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_back<int> q(sq);
|
||||
q.push(1);
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue push lvalue/copyable succeeds
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_back<int> q(sq);
|
||||
int i;
|
||||
q.push(i);
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
{
|
||||
// empty queue push rvalue/non_copyable succeeds
|
||||
boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
|
||||
boost::deque_back<non_copyable> q(sq);
|
||||
q.push(non_copyable(1));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
#endif
|
||||
{
|
||||
// empty queue push rvalue/non_copyable succeeds
|
||||
boost::deque_adaptor<boost::sync_deque<non_copyable> > q;
|
||||
//boost::sync_deque<non_copyable> q;
|
||||
//boost::deque_back<non_copyable> q(sq);
|
||||
non_copyable nc(1);
|
||||
q.push_back(boost::move(nc));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
|
||||
{
|
||||
// empty queue push rvalue succeeds
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_back<int> q(sq);
|
||||
q.push(1);
|
||||
q.push(2);
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 2u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue push lvalue succeeds
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_back<int> q(sq);
|
||||
int i;
|
||||
q.push(i);
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue try_push rvalue/copyable succeeds
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_back<int> q(sq);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_push(1));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue try_push rvalue/copyable succeeds
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_back<int> q(sq);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_push(1));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
|
||||
#if 0
|
||||
{
|
||||
// empty queue try_push rvalue/non-copyable succeeds
|
||||
boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
|
||||
boost::deque_back<non_copyable> q(sq);
|
||||
non_copyable nc(1);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_push(boost::move(nc)));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
// empty queue try_push lvalue succeeds
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_back<int> q(sq);
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_push(i));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue try_push rvalue succeeds
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_back<int> q(sq);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(1));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
{
|
||||
// empty queue nonblocking_push_back rvalue/non-copyable succeeds
|
||||
boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
|
||||
boost::deque_back<non_copyable> q(sq);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(non_copyable(1)));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
#endif
|
||||
{
|
||||
// empty queue nonblocking_push_back rvalue/non-copyable succeeds
|
||||
boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
|
||||
boost::deque_back<non_copyable> q(sq);
|
||||
non_copyable nc(1);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(boost::move(nc)));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue pull_front succeed
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_front<int> q(sq);
|
||||
sq.push_back(1);
|
||||
int i;
|
||||
q.pull(i);
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue pull_front succeed
|
||||
boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
|
||||
boost::deque_front<non_copyable> q(sq);
|
||||
non_copyable nc1(1);
|
||||
sq.push_back(boost::move(nc1));
|
||||
non_copyable nc2(2);
|
||||
q.pull(nc2);
|
||||
BOOST_TEST_EQ(nc1, nc2);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue pull_front succeed
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_front<int> q(sq);
|
||||
sq.push_back(1);
|
||||
int i = q.pull();
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue pull_front succeed
|
||||
boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
|
||||
boost::deque_front<non_copyable> q(sq);
|
||||
non_copyable nc1(1);
|
||||
sq.push_back(boost::move(nc1));
|
||||
non_copyable nc = q.pull();
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue try_pull_front succeed
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_front<int> q(sq);
|
||||
sq.push_back(1);
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_pull(i));
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue try_pull_front succeed
|
||||
boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
|
||||
boost::deque_front<non_copyable> q(sq);
|
||||
non_copyable nc1(1);
|
||||
sq.push_back(boost::move(nc1));
|
||||
non_copyable nc(2);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_pull(nc));
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue nonblocking_pull_front succeed
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_front<int> q(sq);
|
||||
sq.push_back(1);
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(i));
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue nonblocking_pull_front succeed
|
||||
boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
|
||||
boost::deque_front<non_copyable> q(sq);
|
||||
non_copyable nc1(1);
|
||||
sq.push_back(boost::move(nc1));
|
||||
non_copyable nc(2);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(nc));
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue wait_pull_front succeed
|
||||
boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
|
||||
boost::deque_front<non_copyable> q(sq);
|
||||
non_copyable nc1(1);
|
||||
sq.push_back(boost::move(nc1));
|
||||
non_copyable nc(2);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc));
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue wait_pull_front succeed
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_front<int> q(sq);
|
||||
sq.push_back(1);
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i));
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue wait_pull_front succeed
|
||||
boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
|
||||
boost::deque_front<non_copyable> q(sq);
|
||||
non_copyable nc1(1);
|
||||
sq.push_back(boost::move(nc1));
|
||||
non_copyable nc(2);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc));
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
|
||||
{
|
||||
// closed invariants
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_back<int> q(sq);
|
||||
q.close();
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
{
|
||||
// closed invariants
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_front<int> q(sq);
|
||||
q.close();
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
{
|
||||
// closed queue push fails
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_back<int> q(sq);
|
||||
q.close();
|
||||
try {
|
||||
q.push(1);
|
||||
BOOST_TEST(false);
|
||||
} catch (...) {
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
}
|
||||
{
|
||||
// 1-element closed queue pull succeed
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_front<int> q(sq);
|
||||
sq.push_back(1);
|
||||
q.close();
|
||||
int i;
|
||||
q.pull(i);
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element closed queue wait_pull_front succeed
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_front<int> q(sq);
|
||||
sq.push_back(1);
|
||||
q.close();
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i));
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
{
|
||||
// closed empty queue wait_pull_front fails
|
||||
boost::deque_adaptor<boost::sync_deque<int> > sq;
|
||||
boost::deque_front<int> q(sq);
|
||||
q.close();
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(q.closed());
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::closed == q.wait_pull(i));
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#define BOOST_THREAD_VERSION 4
|
||||
//#define BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
|
||||
#include <boost/thread/sync_queue.hpp>
|
||||
#include <boost/thread/concurrent_queues/sync_queue.hpp>
|
||||
#include <boost/thread/concurrent_queues/queue_adaptor.hpp>
|
||||
#include <boost/thread/concurrent_queues/queue_views.hpp>
|
||||
|
||||
@@ -117,7 +117,7 @@ int main()
|
||||
//boost::sync_queue<non_copyable> q;
|
||||
//boost::queue_back<non_copyable> q(sq);
|
||||
non_copyable nc(1);
|
||||
q.push_back(boost::move(nc));
|
||||
q.push(boost::move(nc));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
@@ -206,7 +206,7 @@ int main()
|
||||
|
||||
#if 0
|
||||
{
|
||||
// empty queue nonblocking_push_back rvalue/non-copyable succeeds
|
||||
// empty queue nonblocking_push rvalue/non-copyable succeeds
|
||||
boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
|
||||
boost::queue_back<non_copyable> q(sq);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(non_copyable(1)));
|
||||
@@ -217,7 +217,7 @@ int main()
|
||||
}
|
||||
#endif
|
||||
{
|
||||
// empty queue nonblocking_push_back rvalue/non-copyable succeeds
|
||||
// empty queue nonblocking_push rvalue/non-copyable succeeds
|
||||
boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
|
||||
boost::queue_back<non_copyable> q(sq);
|
||||
non_copyable nc(1);
|
||||
@@ -228,10 +228,10 @@ int main()
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue pull_front succeed
|
||||
// 1-element queue pull succeed
|
||||
boost::queue_adaptor<boost::sync_queue<int> > sq;
|
||||
boost::queue_front<int> q(sq);
|
||||
sq.push_back(1);
|
||||
sq.push(1);
|
||||
int i;
|
||||
q.pull(i);
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
@@ -241,11 +241,11 @@ int main()
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue pull_front succeed
|
||||
// 1-element queue pull succeed
|
||||
boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
|
||||
boost::queue_front<non_copyable> q(sq);
|
||||
non_copyable nc1(1);
|
||||
sq.push_back(boost::move(nc1));
|
||||
sq.push(boost::move(nc1));
|
||||
non_copyable nc2(2);
|
||||
q.pull(nc2);
|
||||
BOOST_TEST_EQ(nc1, nc2);
|
||||
@@ -255,10 +255,10 @@ int main()
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue pull_front succeed
|
||||
// 1-element queue pull succeed
|
||||
boost::queue_adaptor<boost::sync_queue<int> > sq;
|
||||
boost::queue_front<int> q(sq);
|
||||
sq.push_back(1);
|
||||
sq.push(1);
|
||||
int i = q.pull();
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
@@ -267,11 +267,11 @@ int main()
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue pull_front succeed
|
||||
// 1-element queue pull succeed
|
||||
boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
|
||||
boost::queue_front<non_copyable> q(sq);
|
||||
non_copyable nc1(1);
|
||||
sq.push_back(boost::move(nc1));
|
||||
sq.push(boost::move(nc1));
|
||||
non_copyable nc = q.pull();
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
BOOST_TEST(q.empty());
|
||||
@@ -280,10 +280,10 @@ int main()
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue try_pull_front succeed
|
||||
// 1-element queue try_pull succeed
|
||||
boost::queue_adaptor<boost::sync_queue<int> > sq;
|
||||
boost::queue_front<int> q(sq);
|
||||
sq.push_back(1);
|
||||
sq.push(1);
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_pull(i));
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
@@ -293,11 +293,11 @@ int main()
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue try_pull_front succeed
|
||||
// 1-element queue try_pull succeed
|
||||
boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
|
||||
boost::queue_front<non_copyable> q(sq);
|
||||
non_copyable nc1(1);
|
||||
sq.push_back(boost::move(nc1));
|
||||
sq.push(boost::move(nc1));
|
||||
non_copyable nc(2);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_pull(nc));
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
@@ -307,10 +307,10 @@ int main()
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue nonblocking_pull_front succeed
|
||||
// 1-element queue nonblocking_pull succeed
|
||||
boost::queue_adaptor<boost::sync_queue<int> > sq;
|
||||
boost::queue_front<int> q(sq);
|
||||
sq.push_back(1);
|
||||
sq.push(1);
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(i));
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
@@ -320,11 +320,11 @@ int main()
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue nonblocking_pull_front succeed
|
||||
// 1-element queue nonblocking_pull succeed
|
||||
boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
|
||||
boost::queue_front<non_copyable> q(sq);
|
||||
non_copyable nc1(1);
|
||||
sq.push_back(boost::move(nc1));
|
||||
sq.push(boost::move(nc1));
|
||||
non_copyable nc(2);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(nc));
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
@@ -334,11 +334,11 @@ int main()
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue wait_pull_front succeed
|
||||
// 1-element queue wait_pull succeed
|
||||
boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
|
||||
boost::queue_front<non_copyable> q(sq);
|
||||
non_copyable nc1(1);
|
||||
sq.push_back(boost::move(nc1));
|
||||
sq.push(boost::move(nc1));
|
||||
non_copyable nc(2);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc));
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
@@ -348,10 +348,10 @@ int main()
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue wait_pull_front succeed
|
||||
// 1-element queue wait_pull succeed
|
||||
boost::queue_adaptor<boost::sync_queue<int> > sq;
|
||||
boost::queue_front<int> q(sq);
|
||||
sq.push_back(1);
|
||||
sq.push(1);
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i));
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
@@ -361,11 +361,11 @@ int main()
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue wait_pull_front succeed
|
||||
// 1-element queue wait_pull succeed
|
||||
boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
|
||||
boost::queue_front<non_copyable> q(sq);
|
||||
non_copyable nc1(1);
|
||||
sq.push_back(boost::move(nc1));
|
||||
sq.push(boost::move(nc1));
|
||||
non_copyable nc(2);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc));
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
@@ -414,7 +414,7 @@ int main()
|
||||
// 1-element closed queue pull succeed
|
||||
boost::queue_adaptor<boost::sync_queue<int> > sq;
|
||||
boost::queue_front<int> q(sq);
|
||||
sq.push_back(1);
|
||||
sq.push(1);
|
||||
q.close();
|
||||
int i;
|
||||
q.pull(i);
|
||||
@@ -425,10 +425,10 @@ int main()
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element closed queue wait_pull_front succeed
|
||||
// 1-element closed queue wait_pull succeed
|
||||
boost::queue_adaptor<boost::sync_queue<int> > sq;
|
||||
boost::queue_front<int> q(sq);
|
||||
sq.push_back(1);
|
||||
sq.push(1);
|
||||
q.close();
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i));
|
||||
@@ -439,7 +439,7 @@ int main()
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
{
|
||||
// closed empty queue wait_pull_front fails
|
||||
// closed empty queue wait_pull fails
|
||||
boost::queue_adaptor<boost::sync_queue<int> > sq;
|
||||
boost::queue_front<int> q(sq);
|
||||
q.close();
|
||||
|
||||
256
test/sync/mutual_exclusion/sync_deque/multi_thread_pass.cpp
Normal file
256
test/sync/mutual_exclusion/sync_deque/multi_thread_pass.cpp
Normal file
@@ -0,0 +1,256 @@
|
||||
// Copyright (C) 2013 Vicente J. Botet Escriba
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// <boost/thread/concurrent_queues/sync_deque.hpp>
|
||||
|
||||
// class sync_deque<T>
|
||||
|
||||
// push || pull;
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if ! defined BOOST_NO_CXX11_DECLTYPE
|
||||
#define BOOST_RESULT_OF_USE_DECLTYPE
|
||||
#endif
|
||||
|
||||
#define BOOST_THREAD_VERSION 4
|
||||
|
||||
#include <boost/thread/concurrent_queues/sync_deque.hpp>
|
||||
#include <boost/thread/future.hpp>
|
||||
#include <boost/thread/barrier.hpp>
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
template <typename ValueType>
|
||||
struct call_push_back
|
||||
{
|
||||
boost::sync_deque<ValueType> *q_;
|
||||
boost::barrier *go_;
|
||||
|
||||
call_push_back(boost::sync_deque<ValueType> *q, boost::barrier *go) :
|
||||
q_(q), go_(go)
|
||||
{
|
||||
}
|
||||
typedef void result_type;
|
||||
void operator()()
|
||||
{
|
||||
go_->count_down_and_wait();
|
||||
q_->push_back(42);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ValueType>
|
||||
struct call_pull_front
|
||||
{
|
||||
boost::sync_deque<ValueType> *q_;
|
||||
boost::barrier *go_;
|
||||
|
||||
call_pull_front(boost::sync_deque<ValueType> *q, boost::barrier *go) :
|
||||
q_(q), go_(go)
|
||||
{
|
||||
}
|
||||
typedef ValueType result_type;
|
||||
ValueType operator()()
|
||||
{
|
||||
go_->count_down_and_wait();
|
||||
return q_->pull_front();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ValueType>
|
||||
struct call_wait_pull_front
|
||||
{
|
||||
boost::sync_deque<ValueType> *q_;
|
||||
boost::barrier *go_;
|
||||
|
||||
call_wait_pull_front(boost::sync_deque<ValueType> *q, boost::barrier *go) :
|
||||
q_(q), go_(go)
|
||||
{
|
||||
}
|
||||
typedef boost::queue_op_status result_type;
|
||||
boost::queue_op_status operator()(ValueType& v)
|
||||
{
|
||||
go_->wait();
|
||||
return q_->wait_pull_front(v);
|
||||
}
|
||||
};
|
||||
|
||||
void test_concurrent_push_back_and_pull_front_on_empty_queue()
|
||||
{
|
||||
boost::sync_deque<int> q;
|
||||
|
||||
boost::barrier go(2);
|
||||
|
||||
boost::future<void> push_done;
|
||||
boost::future<int> pull_done;
|
||||
|
||||
try
|
||||
{
|
||||
push_done=boost::async(boost::launch::async,
|
||||
call_push_back<int>(&q,&go));
|
||||
pull_done=boost::async(boost::launch::async,
|
||||
call_pull_front<int>(&q,&go));
|
||||
|
||||
push_done.get();
|
||||
BOOST_TEST_EQ(pull_done.get(), 42);
|
||||
BOOST_TEST(q.empty());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
|
||||
void test_concurrent_push_back_and_wait_pull_front_on_empty_queue()
|
||||
{
|
||||
boost::sync_deque<int> q;
|
||||
const unsigned int n = 3;
|
||||
boost::barrier go(n);
|
||||
|
||||
boost::future<boost::queue_op_status> pull_done[n];
|
||||
int results[n];
|
||||
|
||||
try
|
||||
{
|
||||
for (unsigned int i =0; i< n; ++i)
|
||||
pull_done[i]=boost::async(boost::launch::async,
|
||||
call_wait_pull_front<int>(&q,&go),
|
||||
boost::ref(results[i]));
|
||||
|
||||
for (unsigned int i =0; i< n; ++i)
|
||||
q.push_back(42);
|
||||
|
||||
for (unsigned int i = 0; i < n; ++i) {
|
||||
BOOST_TEST(pull_done[i].get() == boost::queue_op_status::success);
|
||||
BOOST_TEST_EQ(results[i], 42);
|
||||
}
|
||||
BOOST_TEST(q.empty());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
}
|
||||
|
||||
void test_concurrent_wait_pull_front_and_close_on_empty_queue()
|
||||
{
|
||||
boost::sync_deque<int> q;
|
||||
const unsigned int n = 3;
|
||||
boost::barrier go(n);
|
||||
|
||||
boost::future<boost::queue_op_status> pull_done[n];
|
||||
int results[n];
|
||||
|
||||
try
|
||||
{
|
||||
for (unsigned int i =0; i< n; ++i)
|
||||
pull_done[i]=boost::async(boost::launch::async,
|
||||
call_wait_pull_front<int>(&q,&go),
|
||||
boost::ref(results[i]));
|
||||
|
||||
q.close();
|
||||
|
||||
for (unsigned int i = 0; i < n; ++i) {
|
||||
BOOST_TEST(pull_done[i].get() == boost::queue_op_status::closed);
|
||||
}
|
||||
BOOST_TEST(q.empty());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void test_concurrent_push_back_on_empty_queue()
|
||||
{
|
||||
boost::sync_deque<int> q;
|
||||
const unsigned int n = 3;
|
||||
boost::barrier go(n);
|
||||
boost::future<void> push_done[n];
|
||||
|
||||
try
|
||||
{
|
||||
for (unsigned int i =0; i< n; ++i)
|
||||
push_done[i]=boost::async(boost::launch::async,
|
||||
call_push_back<int>(&q,&go));
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
try
|
||||
{
|
||||
for (unsigned int i = 0; i < n; ++i)
|
||||
push_done[i].get();
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
try
|
||||
{
|
||||
BOOST_TEST(!q.empty());
|
||||
for (unsigned int i =0; i< n; ++i)
|
||||
BOOST_TEST_EQ(q.pull_front(), 42);
|
||||
BOOST_TEST(q.empty());
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
}
|
||||
|
||||
void test_concurrent_pull_front_on_queue()
|
||||
{
|
||||
boost::sync_deque<int> q;
|
||||
const unsigned int n = 3;
|
||||
boost::barrier go(n);
|
||||
|
||||
boost::future<int> pull_done[n];
|
||||
|
||||
try
|
||||
{
|
||||
for (unsigned int i =0; i< n; ++i)
|
||||
q.push_back(42);
|
||||
|
||||
for (unsigned int i =0; i< n; ++i)
|
||||
pull_done[i]=boost::async(boost::launch::async,
|
||||
#if ! defined BOOST_NO_CXX11_LAMBDAS
|
||||
[&q,&go]() -> int
|
||||
{
|
||||
go.wait();
|
||||
return q.pull_front();
|
||||
}
|
||||
#else
|
||||
call_pull_front<int>(&q,&go)
|
||||
#endif
|
||||
);
|
||||
|
||||
for (unsigned int i = 0; i < n; ++i)
|
||||
BOOST_TEST_EQ(pull_done[i].get(), 42);
|
||||
BOOST_TEST(q.empty());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_concurrent_push_back_and_pull_front_on_empty_queue();
|
||||
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
|
||||
test_concurrent_push_back_and_wait_pull_front_on_empty_queue();
|
||||
test_concurrent_wait_pull_front_and_close_on_empty_queue();
|
||||
#endif
|
||||
test_concurrent_push_back_on_empty_queue();
|
||||
test_concurrent_pull_front_on_queue();
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
404
test/sync/mutual_exclusion/sync_deque/single_thread_pass.cpp
Normal file
404
test/sync/mutual_exclusion/sync_deque/single_thread_pass.cpp
Normal file
@@ -0,0 +1,404 @@
|
||||
// Copyright (C) 2013 Vicente J. Botet Escriba
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// <boost/thread/concurrent_queues/sync_deque.hpp>
|
||||
|
||||
// class sync_deque<T>
|
||||
|
||||
// sync_deque();
|
||||
|
||||
#define BOOST_THREAD_VERSION 4
|
||||
|
||||
#include <boost/thread/concurrent_queues/sync_deque.hpp>
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
class non_copyable
|
||||
{
|
||||
BOOST_THREAD_MOVABLE_ONLY(non_copyable)
|
||||
int val;
|
||||
public:
|
||||
non_copyable(int v) : val(v){}
|
||||
non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {}
|
||||
non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; }
|
||||
bool operator==(non_copyable const& x) const {return val==x.val;}
|
||||
template <typename OSTREAM>
|
||||
friend OSTREAM& operator <<(OSTREAM& os, non_copyable const&x )
|
||||
{
|
||||
os << x.val;
|
||||
return os;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
{
|
||||
// default queue invariants
|
||||
boost::sync_deque<int> q;
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue try_pull fails
|
||||
boost::sync_deque<int> q;
|
||||
int i;
|
||||
BOOST_TEST( boost::queue_op_status::empty == q.try_pull_front(i));
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue push rvalue/copyable succeeds
|
||||
boost::sync_deque<int> q;
|
||||
q.push_back(1);
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue push lvalue/copyable succeeds
|
||||
boost::sync_deque<int> q;
|
||||
int i;
|
||||
q.push_back(i);
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
|
||||
#if 0
|
||||
{
|
||||
// empty queue push rvalue/non_copyable succeeds
|
||||
boost::sync_deque<non_copyable> q;
|
||||
q.push_back(non_copyable(1));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
#endif
|
||||
{
|
||||
// empty queue push rvalue/non_copyable succeeds
|
||||
boost::sync_deque<non_copyable> q;
|
||||
non_copyable nc(1);
|
||||
q.push_back(boost::move(nc));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
|
||||
{
|
||||
// empty queue push rvalue succeeds
|
||||
boost::sync_deque<int> q;
|
||||
q.push_back(1);
|
||||
q.push_back(2);
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 2u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue push lvalue succeeds
|
||||
boost::sync_deque<int> q;
|
||||
int i;
|
||||
q.push_back(i);
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue try_push rvalue/copyable succeeds
|
||||
boost::sync_deque<int> q;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_push_back(1));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue try_push rvalue/copyable succeeds
|
||||
boost::sync_deque<int> q;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_push_back(1));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
|
||||
#if 0
|
||||
{
|
||||
// empty queue try_push rvalue/non-copyable succeeds
|
||||
boost::sync_deque<non_copyable> q;
|
||||
BOOST_TEST(boost::queue_op_status::success ==q.try_push_back(non_copyable()));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
#endif
|
||||
{
|
||||
// empty queue try_push rvalue/non-copyable succeeds
|
||||
boost::sync_deque<non_copyable> q;
|
||||
non_copyable nc(1);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_push_back(boost::move(nc)));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
|
||||
{
|
||||
// empty queue try_push lvalue succeeds
|
||||
boost::sync_deque<int> q;
|
||||
int i=1;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_push_back(i));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue try_push rvalue succeeds
|
||||
boost::sync_deque<int> q;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(1));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
{
|
||||
// empty queue nonblocking_push_back rvalue/non-copyable succeeds
|
||||
boost::sync_deque<non_copyable> q;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(non_copyable(1)));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
#endif
|
||||
{
|
||||
// empty queue nonblocking_push_back rvalue/non-copyable succeeds
|
||||
boost::sync_deque<non_copyable> q;
|
||||
non_copyable nc(1);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(boost::move(nc)));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue pull_front succeed
|
||||
boost::sync_deque<int> q;
|
||||
q.push_back(1);
|
||||
int i;
|
||||
q.pull_front(i);
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue pull_front succeed
|
||||
boost::sync_deque<non_copyable> q;
|
||||
non_copyable nc1(1);
|
||||
q.push_back(boost::move(nc1));
|
||||
non_copyable nc2(2);
|
||||
q.pull_front(nc2);
|
||||
BOOST_TEST_EQ(nc1, nc2);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue pull_front succeed
|
||||
boost::sync_deque<int> q;
|
||||
q.push_back(1);
|
||||
int i = q.pull_front();
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue pull_front succeed
|
||||
boost::sync_deque<non_copyable> q;
|
||||
non_copyable nc1(1);
|
||||
q.push_back(boost::move(nc1));
|
||||
non_copyable nc = q.pull_front();
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue try_pull_front succeed
|
||||
boost::sync_deque<int> q;
|
||||
q.push_back(1);
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_pull_front(i));
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue try_pull_front succeed
|
||||
boost::sync_deque<non_copyable> q;
|
||||
non_copyable nc1(1);
|
||||
q.push_back(boost::move(nc1));
|
||||
non_copyable nc(2);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_pull_front(nc));
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue nonblocking_pull_front succeed
|
||||
boost::sync_deque<int> q;
|
||||
q.push_back(1);
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull_front(i));
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue nonblocking_pull_front succeed
|
||||
boost::sync_deque<non_copyable> q;
|
||||
non_copyable nc1(1);
|
||||
q.push_back(boost::move(nc1));
|
||||
non_copyable nc(2);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull_front(nc));
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue wait_pull_front succeed
|
||||
boost::sync_deque<non_copyable> q;
|
||||
non_copyable nc1(1);
|
||||
q.push_back(boost::move(nc1));
|
||||
non_copyable nc(2);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(nc));
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue wait_pull_front succeed
|
||||
boost::sync_deque<int> q;
|
||||
q.push_back(1);
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(i));
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue wait_pull_front succeed
|
||||
boost::sync_deque<non_copyable> q;
|
||||
non_copyable nc1(1);
|
||||
q.push_back(boost::move(nc1));
|
||||
non_copyable nc(2);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(nc));
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
|
||||
{
|
||||
// closed invariants
|
||||
boost::sync_deque<int> q;
|
||||
q.close();
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
{
|
||||
// closed queue push fails
|
||||
boost::sync_deque<int> q;
|
||||
q.close();
|
||||
try {
|
||||
q.push_back(1);
|
||||
BOOST_TEST(false);
|
||||
} catch (...) {
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
}
|
||||
{
|
||||
// 1-element closed queue pull succeed
|
||||
boost::sync_deque<int> q;
|
||||
q.push_back(1);
|
||||
q.close();
|
||||
int i;
|
||||
q.pull_front(i);
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element closed queue wait_pull_front succeed
|
||||
boost::sync_deque<int> q;
|
||||
q.push_back(1);
|
||||
q.close();
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(i));
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
{
|
||||
// closed empty queue wait_pull_front fails
|
||||
boost::sync_deque<int> q;
|
||||
q.close();
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(q.closed());
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::closed == q.wait_pull_front(i));
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ void test_pull(const int n)
|
||||
pq.push(i);
|
||||
}
|
||||
BOOST_TEST(!pq.empty());
|
||||
BOOST_TEST_EQ(pq.size(), n);
|
||||
BOOST_TEST_EQ(pq.size(), std::size_t(n));
|
||||
pq.close();
|
||||
BOOST_TEST(pq.closed());
|
||||
boost::barrier b(n);
|
||||
@@ -71,7 +71,7 @@ void test_push(const int n)
|
||||
}
|
||||
tg.join_all();
|
||||
BOOST_TEST(!pq.empty());
|
||||
BOOST_TEST_EQ(pq.size(), n);
|
||||
BOOST_TEST_EQ(pq.size(), std::size_t(n));
|
||||
}
|
||||
|
||||
void test_both(const int n)
|
||||
@@ -88,7 +88,7 @@ void test_both(const int n)
|
||||
}
|
||||
tg.join_all();
|
||||
BOOST_TEST(pq.empty());
|
||||
BOOST_TEST_EQ(pq.size(), 0);
|
||||
BOOST_TEST_EQ(pq.size(), std::size_t(0));
|
||||
}
|
||||
|
||||
void push_range(sync_pq* q, const int begin, const int end)
|
||||
|
||||
@@ -55,7 +55,7 @@ void test_pull_for()
|
||||
boost::queue_op_status st = pq.pull_for(milliseconds(500), val);
|
||||
steady_clock::duration diff = steady_clock::now() - start;
|
||||
BOOST_TEST(boost::queue_op_status::timeout == st);
|
||||
BOOST_TEST(diff < milliseconds(510) && diff > milliseconds(500));
|
||||
BOOST_TEST(diff < milliseconds(550) && diff > milliseconds(500));
|
||||
}
|
||||
|
||||
void test_pull_until()
|
||||
@@ -66,7 +66,7 @@ void test_pull_until()
|
||||
boost::queue_op_status st = pq.pull_until(start + milliseconds(500), val);
|
||||
steady_clock::duration diff = steady_clock::now() - start;
|
||||
BOOST_TEST(boost::queue_op_status::timeout == st);
|
||||
BOOST_TEST(diff < milliseconds(510) && diff > milliseconds(500));
|
||||
BOOST_TEST(diff < milliseconds(550) && diff > milliseconds(500));
|
||||
}
|
||||
|
||||
void test_nonblocking_pull()
|
||||
@@ -111,19 +111,19 @@ int main()
|
||||
sync_pq pq;
|
||||
BOOST_TEST(pq.empty());
|
||||
BOOST_TEST(!pq.closed());
|
||||
BOOST_TEST_EQ(pq.size(), 0);
|
||||
BOOST_TEST_EQ(pq.size(), std::size_t(0));
|
||||
|
||||
for(int i = 1; i <= 5; i++){
|
||||
pq.push(i);
|
||||
BOOST_TEST(!pq.empty());
|
||||
BOOST_TEST_EQ(pq.size(), i);
|
||||
BOOST_TEST_EQ(pq.size(), std::size_t(i));
|
||||
}
|
||||
|
||||
for(int i = 6; i <= 10; i++){
|
||||
boost::queue_op_status succ = pq.try_push(i);
|
||||
BOOST_TEST(succ == boost::queue_op_status::success );
|
||||
BOOST_TEST(!pq.empty());
|
||||
BOOST_TEST_EQ(pq.size(), i);
|
||||
BOOST_TEST_EQ(pq.size(), std::size_t(i));
|
||||
}
|
||||
|
||||
for(int i = 10; i > 5; i--){
|
||||
|
||||
@@ -30,18 +30,18 @@ void test_all()
|
||||
sync_tq pq;
|
||||
BOOST_TEST(pq.empty());
|
||||
BOOST_TEST(!pq.closed());
|
||||
BOOST_TEST_EQ(pq.size(), 0);
|
||||
BOOST_TEST_EQ(pq.size(), std::size_t(0));
|
||||
|
||||
for(int i = 1; i <= 5; i++){
|
||||
pq.push(i, milliseconds(i*100));
|
||||
BOOST_TEST(!pq.empty());
|
||||
BOOST_TEST_EQ(pq.size(), i);
|
||||
BOOST_TEST_EQ(pq.size(), std::size_t(i));
|
||||
}
|
||||
|
||||
for(int i = 6; i <= 10; i++){
|
||||
pq.push(i,steady_clock::now() + milliseconds(i*100));
|
||||
BOOST_TEST(!pq.empty());
|
||||
BOOST_TEST_EQ(pq.size(), i);
|
||||
BOOST_TEST_EQ(pq.size(), std::size_t(i));
|
||||
}
|
||||
|
||||
for(int i = 1; i <= 10; i++){
|
||||
@@ -63,20 +63,20 @@ void test_all_with_try()
|
||||
sync_tq pq;
|
||||
BOOST_TEST(pq.empty());
|
||||
BOOST_TEST(!pq.closed());
|
||||
BOOST_TEST_EQ(pq.size(), 0);
|
||||
BOOST_TEST_EQ(pq.size(), std::size_t(0));
|
||||
|
||||
for(int i = 1; i <= 5; i++){
|
||||
boost::queue_op_status st = pq.try_push(i, milliseconds(i*100));
|
||||
BOOST_TEST(st == boost::queue_op_status::success );
|
||||
BOOST_TEST(!pq.empty());
|
||||
BOOST_TEST_EQ(pq.size(), i);
|
||||
BOOST_TEST_EQ(pq.size(), std::size_t(i));
|
||||
}
|
||||
|
||||
for(int i = 6; i <= 10; i++){
|
||||
boost::queue_op_status st = pq.try_push(i,steady_clock::now() + milliseconds(i*100));
|
||||
BOOST_TEST(st == boost::queue_op_status::success );
|
||||
BOOST_TEST(!pq.empty());
|
||||
BOOST_TEST_EQ(pq.size(), i);
|
||||
BOOST_TEST_EQ(pq.size(), std::size_t(i));
|
||||
}
|
||||
|
||||
for(int i = 1; i <= 10; i++){
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#endif
|
||||
|
||||
#define BOOST_THREAD_VERSION 4
|
||||
//#define BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
|
||||
#include <boost/thread/sync_queue.hpp>
|
||||
#include <boost/thread/future.hpp>
|
||||
@@ -23,13 +22,13 @@
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
template <typename ValueType>
|
||||
struct call_push
|
||||
{
|
||||
boost::sync_queue<int> *q_;
|
||||
boost::sync_queue<ValueType> *q_;
|
||||
boost::barrier *go_;
|
||||
|
||||
call_push(boost::sync_queue<int> *q, boost::barrier *go) :
|
||||
call_push(boost::sync_queue<ValueType> *q, boost::barrier *go) :
|
||||
q_(q), go_(go)
|
||||
{
|
||||
}
|
||||
@@ -38,53 +37,16 @@ struct call_push
|
||||
{
|
||||
go_->count_down_and_wait();
|
||||
q_->push(42);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ValueType>
|
||||
struct call_pull
|
||||
{
|
||||
boost::sync_queue<int> *q_;
|
||||
boost::barrier *go_;
|
||||
|
||||
call_pull(boost::sync_queue<int> *q, boost::barrier *go) :
|
||||
q_(q), go_(go)
|
||||
{
|
||||
}
|
||||
typedef int result_type;
|
||||
int operator()()
|
||||
{
|
||||
go_->count_down_and_wait();
|
||||
return q_->pull();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
template <typename ValueType>
|
||||
struct call_push_back
|
||||
{
|
||||
boost::sync_queue<ValueType> *q_;
|
||||
boost::barrier *go_;
|
||||
|
||||
call_push_back(boost::sync_queue<ValueType> *q, boost::barrier *go) :
|
||||
q_(q), go_(go)
|
||||
{
|
||||
}
|
||||
typedef void result_type;
|
||||
void operator()()
|
||||
{
|
||||
go_->count_down_and_wait();
|
||||
q_->push_back(42);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ValueType>
|
||||
struct call_pull_front
|
||||
{
|
||||
boost::sync_queue<ValueType> *q_;
|
||||
boost::barrier *go_;
|
||||
|
||||
call_pull_front(boost::sync_queue<ValueType> *q, boost::barrier *go) :
|
||||
call_pull(boost::sync_queue<ValueType> *q, boost::barrier *go) :
|
||||
q_(q), go_(go)
|
||||
{
|
||||
}
|
||||
@@ -92,17 +54,17 @@ struct call_pull_front
|
||||
ValueType operator()()
|
||||
{
|
||||
go_->count_down_and_wait();
|
||||
return q_->pull_front();
|
||||
return q_->pull();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ValueType>
|
||||
struct call_wait_pull_front
|
||||
struct call_wait_pull
|
||||
{
|
||||
boost::sync_queue<ValueType> *q_;
|
||||
boost::barrier *go_;
|
||||
|
||||
call_wait_pull_front(boost::sync_queue<ValueType> *q, boost::barrier *go) :
|
||||
call_wait_pull(boost::sync_queue<ValueType> *q, boost::barrier *go) :
|
||||
q_(q), go_(go)
|
||||
{
|
||||
}
|
||||
@@ -110,11 +72,10 @@ struct call_wait_pull_front
|
||||
boost::queue_op_status operator()(ValueType& v)
|
||||
{
|
||||
go_->wait();
|
||||
return q_->wait_pull_front(v);
|
||||
return q_->wait_pull(v);
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
void test_concurrent_push_and_pull_on_empty_queue()
|
||||
{
|
||||
boost::sync_queue<int> q;
|
||||
@@ -127,27 +88,9 @@ void test_concurrent_push_and_pull_on_empty_queue()
|
||||
try
|
||||
{
|
||||
push_done=boost::async(boost::launch::async,
|
||||
#if ! defined BOOST_NO_CXX11_LAMBDAS
|
||||
[&q,&go]()
|
||||
{
|
||||
go.wait();
|
||||
q.push(42);
|
||||
}
|
||||
#else
|
||||
call_push(&q,&go)
|
||||
#endif
|
||||
);
|
||||
call_push<int>(&q,&go));
|
||||
pull_done=boost::async(boost::launch::async,
|
||||
#if ! defined BOOST_NO_CXX11_LAMBDAS
|
||||
[&q,&go]() -> int
|
||||
{
|
||||
go.wait();
|
||||
return q.pull();
|
||||
}
|
||||
#else
|
||||
call_pull(&q,&go)
|
||||
#endif
|
||||
);
|
||||
call_pull<int>(&q,&go));
|
||||
|
||||
push_done.get();
|
||||
BOOST_TEST_EQ(pull_done.get(), 42);
|
||||
@@ -159,6 +102,68 @@ void test_concurrent_push_and_pull_on_empty_queue()
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
|
||||
void test_concurrent_push_and_wait_pull_on_empty_queue()
|
||||
{
|
||||
boost::sync_queue<int> q;
|
||||
const unsigned int n = 3;
|
||||
boost::barrier go(n);
|
||||
|
||||
boost::future<boost::queue_op_status> pull_done[n];
|
||||
int results[n];
|
||||
|
||||
try
|
||||
{
|
||||
for (unsigned int i =0; i< n; ++i)
|
||||
pull_done[i]=boost::async(boost::launch::async,
|
||||
call_wait_pull<int>(&q,&go),
|
||||
boost::ref(results[i]));
|
||||
|
||||
for (unsigned int i =0; i< n; ++i)
|
||||
q.push(42);
|
||||
|
||||
for (unsigned int i = 0; i < n; ++i) {
|
||||
BOOST_TEST(pull_done[i].get() == boost::queue_op_status::success);
|
||||
BOOST_TEST_EQ(results[i], 42);
|
||||
}
|
||||
BOOST_TEST(q.empty());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
}
|
||||
|
||||
void test_concurrent_wait_pull_and_close_on_empty_queue()
|
||||
{
|
||||
boost::sync_queue<int> q;
|
||||
const unsigned int n = 3;
|
||||
boost::barrier go(n);
|
||||
|
||||
boost::future<boost::queue_op_status> pull_done[n];
|
||||
int results[n];
|
||||
|
||||
try
|
||||
{
|
||||
for (unsigned int i =0; i< n; ++i)
|
||||
pull_done[i]=boost::async(boost::launch::async,
|
||||
call_wait_pull<int>(&q,&go),
|
||||
boost::ref(results[i]));
|
||||
|
||||
q.close();
|
||||
|
||||
for (unsigned int i = 0; i < n; ++i) {
|
||||
BOOST_TEST(pull_done[i].get() == boost::queue_op_status::closed);
|
||||
}
|
||||
BOOST_TEST(q.empty());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void test_concurrent_push_on_empty_queue()
|
||||
{
|
||||
boost::sync_queue<int> q;
|
||||
@@ -170,20 +175,25 @@ void test_concurrent_push_on_empty_queue()
|
||||
{
|
||||
for (unsigned int i =0; i< n; ++i)
|
||||
push_done[i]=boost::async(boost::launch::async,
|
||||
#if ! defined BOOST_NO_CXX11_LAMBDAS
|
||||
[&q,&go]()
|
||||
{
|
||||
go.wait();
|
||||
q.push(42);
|
||||
}
|
||||
#else
|
||||
call_push(&q,&go)
|
||||
#endif
|
||||
);
|
||||
call_push<int>(&q,&go));
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
try
|
||||
{
|
||||
for (unsigned int i = 0; i < n; ++i)
|
||||
push_done[i].get();
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
try
|
||||
{
|
||||
BOOST_TEST(!q.empty());
|
||||
for (unsigned int i =0; i< n; ++i)
|
||||
BOOST_TEST_EQ(q.pull(), 42);
|
||||
@@ -218,174 +228,7 @@ void test_concurrent_pull_on_queue()
|
||||
return q.pull();
|
||||
}
|
||||
#else
|
||||
call_pull(&q,&go)
|
||||
#endif
|
||||
);
|
||||
|
||||
for (unsigned int i = 0; i < n; ++i)
|
||||
BOOST_TEST_EQ(pull_done[i].get(), 42);
|
||||
BOOST_TEST(q.empty());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void test_concurrent_push_back_and_pull_front_on_empty_queue()
|
||||
{
|
||||
boost::sync_queue<int> q;
|
||||
|
||||
boost::barrier go(2);
|
||||
|
||||
boost::future<void> push_done;
|
||||
boost::future<int> pull_done;
|
||||
|
||||
try
|
||||
{
|
||||
push_done=boost::async(boost::launch::async,
|
||||
call_push_back<int>(&q,&go));
|
||||
pull_done=boost::async(boost::launch::async,
|
||||
call_pull_front<int>(&q,&go));
|
||||
|
||||
push_done.get();
|
||||
BOOST_TEST_EQ(pull_done.get(), 42);
|
||||
BOOST_TEST(q.empty());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
|
||||
void test_concurrent_push_back_and_wait_pull_front_on_empty_queue()
|
||||
{
|
||||
boost::sync_queue<int> q;
|
||||
const unsigned int n = 3;
|
||||
boost::barrier go(n);
|
||||
|
||||
boost::future<boost::queue_op_status> pull_done[n];
|
||||
int results[n];
|
||||
|
||||
try
|
||||
{
|
||||
for (unsigned int i =0; i< n; ++i)
|
||||
pull_done[i]=boost::async(boost::launch::async,
|
||||
call_wait_pull_front<int>(&q,&go),
|
||||
boost::ref(results[i]));
|
||||
|
||||
for (unsigned int i =0; i< n; ++i)
|
||||
q.push_back(42);
|
||||
|
||||
for (unsigned int i = 0; i < n; ++i) {
|
||||
BOOST_TEST(pull_done[i].get() == boost::queue_op_status::success);
|
||||
BOOST_TEST_EQ(results[i], 42);
|
||||
}
|
||||
BOOST_TEST(q.empty());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
}
|
||||
|
||||
void test_concurrent_wait_pull_front_and_close_on_empty_queue()
|
||||
{
|
||||
boost::sync_queue<int> q;
|
||||
const unsigned int n = 3;
|
||||
boost::barrier go(n);
|
||||
|
||||
boost::future<boost::queue_op_status> pull_done[n];
|
||||
int results[n];
|
||||
|
||||
try
|
||||
{
|
||||
for (unsigned int i =0; i< n; ++i)
|
||||
pull_done[i]=boost::async(boost::launch::async,
|
||||
call_wait_pull_front<int>(&q,&go),
|
||||
boost::ref(results[i]));
|
||||
|
||||
q.close();
|
||||
|
||||
for (unsigned int i = 0; i < n; ++i) {
|
||||
BOOST_TEST(pull_done[i].get() == boost::queue_op_status::closed);
|
||||
}
|
||||
BOOST_TEST(q.empty());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void test_concurrent_push_back_on_empty_queue()
|
||||
{
|
||||
boost::sync_queue<int> q;
|
||||
const unsigned int n = 3;
|
||||
boost::barrier go(n);
|
||||
boost::future<void> push_done[n];
|
||||
|
||||
try
|
||||
{
|
||||
for (unsigned int i =0; i< n; ++i)
|
||||
push_done[i]=boost::async(boost::launch::async,
|
||||
call_push_back<int>(&q,&go));
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
try
|
||||
{
|
||||
for (unsigned int i = 0; i < n; ++i)
|
||||
push_done[i].get();
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
try
|
||||
{
|
||||
BOOST_TEST(!q.empty());
|
||||
for (unsigned int i =0; i< n; ++i)
|
||||
BOOST_TEST_EQ(q.pull_front(), 42);
|
||||
BOOST_TEST(q.empty());
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
}
|
||||
|
||||
void test_concurrent_pull_front_on_queue()
|
||||
{
|
||||
boost::sync_queue<int> q;
|
||||
const unsigned int n = 3;
|
||||
boost::barrier go(n);
|
||||
|
||||
boost::future<int> pull_done[n];
|
||||
|
||||
try
|
||||
{
|
||||
for (unsigned int i =0; i< n; ++i)
|
||||
q.push_back(42);
|
||||
|
||||
for (unsigned int i =0; i< n; ++i)
|
||||
pull_done[i]=boost::async(boost::launch::async,
|
||||
#if ! defined BOOST_NO_CXX11_LAMBDAS
|
||||
[&q,&go]() -> int
|
||||
{
|
||||
go.wait();
|
||||
return q.pull_front();
|
||||
}
|
||||
#else
|
||||
call_pull_front<int>(&q,&go)
|
||||
call_pull<int>(&q,&go)
|
||||
#endif
|
||||
);
|
||||
|
||||
@@ -401,18 +244,13 @@ void test_concurrent_pull_front_on_queue()
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
test_concurrent_push_and_pull_on_empty_queue();
|
||||
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
|
||||
test_concurrent_push_and_wait_pull_on_empty_queue();
|
||||
test_concurrent_wait_pull_and_close_on_empty_queue();
|
||||
#endif
|
||||
test_concurrent_push_on_empty_queue();
|
||||
test_concurrent_pull_on_queue();
|
||||
#endif
|
||||
test_concurrent_push_back_and_pull_front_on_empty_queue();
|
||||
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
|
||||
test_concurrent_push_back_and_wait_pull_front_on_empty_queue();
|
||||
test_concurrent_wait_pull_front_and_close_on_empty_queue();
|
||||
#endif
|
||||
test_concurrent_push_back_on_empty_queue();
|
||||
test_concurrent_pull_front_on_queue();
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
// sync_queue();
|
||||
|
||||
#define BOOST_THREAD_VERSION 4
|
||||
//#define BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
|
||||
#include <boost/thread/sync_queue.hpp>
|
||||
|
||||
@@ -47,78 +46,7 @@ int main()
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
{
|
||||
// empty queue try_pull fails
|
||||
boost::sync_queue<int> q;
|
||||
int i;
|
||||
BOOST_TEST(! q.try_pull(i));
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue try_pull fails
|
||||
boost::sync_queue<int> q;
|
||||
BOOST_TEST(! q.try_pull());
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue push rvalue/copyable succeeds
|
||||
boost::sync_queue<int> q;
|
||||
q.push(1);
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue push lvalue/copyable succeeds
|
||||
boost::sync_queue<int> q;
|
||||
int i;
|
||||
q.push(i);
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
// empty queue try_pull fails
|
||||
boost::sync_queue<int> q;
|
||||
int i;
|
||||
BOOST_TEST( boost::queue_op_status::empty == q.try_pull_front(i));
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue push rvalue/copyable succeeds
|
||||
boost::sync_queue<int> q;
|
||||
q.push_back(1);
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue push lvalue/copyable succeeds
|
||||
boost::sync_queue<int> q;
|
||||
int i;
|
||||
q.push_back(i);
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
#if 0
|
||||
{
|
||||
// empty queue push rvalue/non_copyable succeeds
|
||||
@@ -164,7 +92,7 @@ int main()
|
||||
{
|
||||
// empty queue try_push rvalue/copyable succeeds
|
||||
boost::sync_queue<int> q;
|
||||
BOOST_TEST(q.try_push(1));
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_push(1));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
@@ -173,79 +101,18 @@ int main()
|
||||
{
|
||||
// empty queue try_push rvalue/copyable succeeds
|
||||
boost::sync_queue<int> q;
|
||||
BOOST_TEST(q.try_push(1));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
{
|
||||
// empty queue push rvalue/non_copyable succeeds
|
||||
boost::sync_queue<non_copyable> q;
|
||||
q.push_back(non_copyable(1));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
#endif
|
||||
{
|
||||
// empty queue push rvalue/non_copyable succeeds
|
||||
boost::sync_queue<non_copyable> q;
|
||||
non_copyable nc(1);
|
||||
q.push_back(boost::move(nc));
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_push(1));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
|
||||
{
|
||||
// empty queue push rvalue succeeds
|
||||
boost::sync_queue<int> q;
|
||||
q.push_back(1);
|
||||
q.push_back(2);
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 2u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue push lvalue succeeds
|
||||
boost::sync_queue<int> q;
|
||||
int i;
|
||||
q.push_back(i);
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue try_push rvalue/copyable succeeds
|
||||
boost::sync_queue<int> q;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_push_back(1));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue try_push rvalue/copyable succeeds
|
||||
boost::sync_queue<int> q;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_push_back(1));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
#if 0
|
||||
{
|
||||
// empty queue try_push rvalue/non-copyable succeeds
|
||||
boost::sync_queue<non_copyable> q;
|
||||
BOOST_TEST(q.try_push(non_copyable()));
|
||||
BOOST_TEST(boost::queue_op_status::success ==q.try_push(non_copyable()));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
@@ -256,7 +123,7 @@ int main()
|
||||
// empty queue try_push rvalue/non-copyable succeeds
|
||||
boost::sync_queue<non_copyable> q;
|
||||
non_copyable nc(1);
|
||||
BOOST_TEST(q.try_push(boost::move(nc)));
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_push(boost::move(nc)));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
@@ -267,7 +134,7 @@ int main()
|
||||
// empty queue try_push lvalue succeeds
|
||||
boost::sync_queue<int> q;
|
||||
int i=1;
|
||||
BOOST_TEST(q.try_push(i));
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_push(i));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
@@ -276,61 +143,18 @@ int main()
|
||||
{
|
||||
// empty queue try_push rvalue succeeds
|
||||
boost::sync_queue<int> q;
|
||||
BOOST_TEST(q.try_push(boost::no_block, 1));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
{
|
||||
// empty queue try_push rvalue/non-copyable succeeds
|
||||
boost::sync_queue<non_copyable> q;
|
||||
BOOST_TEST(boost::queue_op_status::success ==q.try_push_back(non_copyable()));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
#endif
|
||||
{
|
||||
// empty queue try_push rvalue/non-copyable succeeds
|
||||
boost::sync_queue<non_copyable> q;
|
||||
non_copyable nc(1);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_push_back(boost::move(nc)));
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(1));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
|
||||
{
|
||||
// empty queue try_push lvalue succeeds
|
||||
boost::sync_queue<int> q;
|
||||
int i=1;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_push_back(i));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// empty queue try_push rvalue succeeds
|
||||
boost::sync_queue<int> q;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(1));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
|
||||
#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
|
||||
#if 0
|
||||
{
|
||||
// empty queue try_push rvalue/non-copyable succeeds
|
||||
// empty queue nonblocking_push rvalue/non-copyable succeeds
|
||||
boost::sync_queue<non_copyable> q;
|
||||
BOOST_TEST(q.try_push(boost::no_block, non_copyable(1)));
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(non_copyable(1)));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
@@ -338,10 +162,10 @@ int main()
|
||||
}
|
||||
#endif
|
||||
{
|
||||
// empty queue try_push rvalue/non-copyable succeeds
|
||||
// empty queue nonblocking_push rvalue/non-copyable succeeds
|
||||
boost::sync_queue<non_copyable> q;
|
||||
non_copyable nc(1);
|
||||
BOOST_TEST(q.try_push(boost::no_block, boost::move(nc)));
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(boost::move(nc)));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
@@ -400,7 +224,7 @@ int main()
|
||||
boost::sync_queue<int> q;
|
||||
q.push(1);
|
||||
int i;
|
||||
BOOST_TEST(q.try_pull(i));
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_pull(i));
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
@@ -413,7 +237,7 @@ int main()
|
||||
non_copyable nc1(1);
|
||||
q.push(boost::move(nc1));
|
||||
non_copyable nc(2);
|
||||
BOOST_TEST(q.try_pull(nc));
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_pull(nc));
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
@@ -421,11 +245,11 @@ int main()
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue try_pull succeed
|
||||
// 1-element queue nonblocking_pull succeed
|
||||
boost::sync_queue<int> q;
|
||||
q.push(1);
|
||||
int i;
|
||||
BOOST_TEST(q.try_pull(boost::no_block, i));
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(i));
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
@@ -433,12 +257,12 @@ int main()
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue try_pull succeed
|
||||
// 1-element queue nonblocking_pull succeed
|
||||
boost::sync_queue<non_copyable> q;
|
||||
non_copyable nc1(1);
|
||||
q.push(boost::move(nc1));
|
||||
non_copyable nc(2);
|
||||
BOOST_TEST(q.try_pull(boost::no_block, nc));
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(nc));
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
@@ -446,11 +270,38 @@ int main()
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue try_pull succeed
|
||||
// 1-element queue wait_pull succeed
|
||||
boost::sync_queue<non_copyable> q;
|
||||
non_copyable nc1(1);
|
||||
q.push(boost::move(nc1));
|
||||
non_copyable nc(2);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc));
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue wait_pull succeed
|
||||
boost::sync_queue<int> q;
|
||||
q.push(1);
|
||||
boost::shared_ptr<int> i = q.try_pull();
|
||||
BOOST_TEST_EQ(*i, 1);
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i));
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue wait_pull succeed
|
||||
boost::sync_queue<non_copyable> q;
|
||||
non_copyable nc1(1);
|
||||
q.push(boost::move(nc1));
|
||||
non_copyable nc(2);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc));
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
@@ -480,28 +331,6 @@ int main()
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
}
|
||||
{
|
||||
// closed empty queue try_pull_front closed
|
||||
boost::sync_queue<int> q;
|
||||
q.close();
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::closed == q.try_pull_front(i));
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
{
|
||||
// closed empty queue nonblocking_pull_front closed
|
||||
boost::sync_queue<int> q;
|
||||
q.close();
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::closed == q.nonblocking_pull_front(i));
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element closed queue pull succeed
|
||||
boost::sync_queue<int> q;
|
||||
@@ -515,195 +344,13 @@ int main()
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
{
|
||||
// empty queue nonblocking_push_back rvalue/non-copyable succeeds
|
||||
boost::sync_queue<non_copyable> q;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(non_copyable(1)));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
#endif
|
||||
{
|
||||
// empty queue nonblocking_push_back rvalue/non-copyable succeeds
|
||||
boost::sync_queue<non_copyable> q;
|
||||
non_copyable nc(1);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(boost::move(nc)));
|
||||
BOOST_TEST(! q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 1u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue pull_front succeed
|
||||
// 1-element closed queue wait_pull succeed
|
||||
boost::sync_queue<int> q;
|
||||
q.push_back(1);
|
||||
int i;
|
||||
q.pull_front(i);
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue pull_front succeed
|
||||
boost::sync_queue<non_copyable> q;
|
||||
non_copyable nc1(1);
|
||||
q.push_back(boost::move(nc1));
|
||||
non_copyable nc2(2);
|
||||
q.pull_front(nc2);
|
||||
BOOST_TEST_EQ(nc1, nc2);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue pull_front succeed
|
||||
boost::sync_queue<int> q;
|
||||
q.push_back(1);
|
||||
int i = q.pull_front();
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue pull_front succeed
|
||||
boost::sync_queue<non_copyable> q;
|
||||
non_copyable nc1(1);
|
||||
q.push_back(boost::move(nc1));
|
||||
non_copyable nc = q.pull_front();
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue try_pull_front succeed
|
||||
boost::sync_queue<int> q;
|
||||
q.push_back(1);
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_pull_front(i));
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue try_pull_front succeed
|
||||
boost::sync_queue<non_copyable> q;
|
||||
non_copyable nc1(1);
|
||||
q.push_back(boost::move(nc1));
|
||||
non_copyable nc(2);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.try_pull_front(nc));
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue nonblocking_pull_front succeed
|
||||
boost::sync_queue<int> q;
|
||||
q.push_back(1);
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull_front(i));
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue nonblocking_pull_front succeed
|
||||
boost::sync_queue<non_copyable> q;
|
||||
non_copyable nc1(1);
|
||||
q.push_back(boost::move(nc1));
|
||||
non_copyable nc(2);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull_front(nc));
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue wait_pull_front succeed
|
||||
boost::sync_queue<non_copyable> q;
|
||||
non_copyable nc1(1);
|
||||
q.push_back(boost::move(nc1));
|
||||
non_copyable nc(2);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(nc));
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue wait_pull_front succeed
|
||||
boost::sync_queue<int> q;
|
||||
q.push_back(1);
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(i));
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element queue wait_pull_front succeed
|
||||
boost::sync_queue<non_copyable> q;
|
||||
non_copyable nc1(1);
|
||||
q.push_back(boost::move(nc1));
|
||||
non_copyable nc(2);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(nc));
|
||||
BOOST_TEST_EQ(nc, nc1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(! q.closed());
|
||||
}
|
||||
|
||||
{
|
||||
// closed invariants
|
||||
boost::sync_queue<int> q;
|
||||
q.close();
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
{
|
||||
// closed queue push fails
|
||||
boost::sync_queue<int> q;
|
||||
q.close();
|
||||
try {
|
||||
q.push_back(1);
|
||||
BOOST_TEST(false);
|
||||
} catch (...) {
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
}
|
||||
{
|
||||
// 1-element closed queue pull succeed
|
||||
boost::sync_queue<int> q;
|
||||
q.push_back(1);
|
||||
q.push(1);
|
||||
q.close();
|
||||
int i;
|
||||
q.pull_front(i);
|
||||
BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i));
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
@@ -711,26 +358,13 @@ int main()
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
{
|
||||
// 1-element closed queue wait_pull_front succeed
|
||||
boost::sync_queue<int> q;
|
||||
q.push_back(1);
|
||||
q.close();
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(i));
|
||||
BOOST_TEST_EQ(i, 1);
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(! q.full());
|
||||
BOOST_TEST_EQ(q.size(), 0u);
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
{
|
||||
// closed empty queue wait_pull_front fails
|
||||
// closed empty queue wait_pull fails
|
||||
boost::sync_queue<int> q;
|
||||
q.close();
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(q.closed());
|
||||
int i;
|
||||
BOOST_TEST(boost::queue_op_status::closed == q.wait_pull_front(i));
|
||||
BOOST_TEST(boost::queue_op_status::closed == q.wait_pull(i));
|
||||
BOOST_TEST(q.empty());
|
||||
BOOST_TEST(q.closed());
|
||||
}
|
||||
|
||||
44
test/test_10963.cpp
Normal file
44
test/test_10963.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright (C) 2014 Vicente Botet
|
||||
//
|
||||
// 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)
|
||||
|
||||
#define BOOST_THREAD_VERSION 4
|
||||
#include <boost/config.hpp>
|
||||
#if ! defined BOOST_NO_CXX11_DECLTYPE
|
||||
#define BOOST_RESULT_OF_USE_DECLTYPE
|
||||
#endif
|
||||
|
||||
#include <boost/thread/future.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
|
||||
struct TestCallback
|
||||
{
|
||||
typedef boost::future<void> result_type;
|
||||
|
||||
result_type operator()(boost::future<void> future) const
|
||||
{
|
||||
future.get();
|
||||
return boost::make_ready_future();
|
||||
}
|
||||
|
||||
result_type operator()(boost::future<boost::future<void> > future) const
|
||||
{
|
||||
future.get();
|
||||
return boost::make_ready_future();
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
#if ! defined BOOST_NO_CXX11_DECLTYPE && ! defined BOOST_NO_CXX11_AUTO_DECLARATIONS
|
||||
boost::promise<void> test_promise;
|
||||
boost::future<void> test_future(test_promise.get_future());
|
||||
auto f1 = test_future.then(TestCallback());
|
||||
BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
|
||||
auto f2 = f1.then(TestCallback());
|
||||
BOOST_STATIC_ASSERT(std::is_same<decltype(f2), boost::future<boost::future<void> > >::value);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
67
test/test_10964.cpp
Normal file
67
test/test_10964.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright (C) 2015 Vicente Botet
|
||||
//
|
||||
// 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)
|
||||
|
||||
#define BOOST_THREAD_VERSION 4
|
||||
#include <boost/config.hpp>
|
||||
#if ! defined BOOST_NO_CXX11_DECLTYPE
|
||||
#define BOOST_RESULT_OF_USE_DECLTYPE
|
||||
#endif
|
||||
|
||||
#include <boost/thread/future.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
struct TestCallback
|
||||
{
|
||||
typedef boost::future<void> result_type;
|
||||
|
||||
result_type operator()(boost::future<void> future) const
|
||||
{
|
||||
future.get();
|
||||
return boost::make_ready_future();
|
||||
}
|
||||
|
||||
result_type operator()(boost::future<boost::future<void> > future) const
|
||||
{
|
||||
future.get();
|
||||
return boost::make_ready_future();
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
#if ! defined BOOST_NO_CXX11_DECLTYPE && ! defined BOOST_NO_CXX11_AUTO_DECLARATIONS
|
||||
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
|
||||
{
|
||||
auto f1 = boost::make_ready_future().then(TestCallback());
|
||||
BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
|
||||
f1.wait();
|
||||
}
|
||||
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
|
||||
{
|
||||
auto f1 = boost::make_ready_future().then(TestCallback());
|
||||
BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
|
||||
auto f2 = f1.unwrap();
|
||||
BOOST_STATIC_ASSERT(std::is_same<decltype(f2), boost::future<void> >::value);
|
||||
f2.wait();
|
||||
}
|
||||
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
|
||||
{
|
||||
auto f1 = boost::make_ready_future().then(TestCallback());
|
||||
BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
|
||||
auto f2 = f1.unwrap();
|
||||
BOOST_STATIC_ASSERT(std::is_same<decltype(f2), boost::future<void> >::value);
|
||||
auto f3 = f2.then(TestCallback());
|
||||
BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
|
||||
f3.wait();
|
||||
}
|
||||
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
|
||||
{
|
||||
boost::make_ready_future().then(
|
||||
TestCallback()).unwrap().then(TestCallback()).get();
|
||||
}
|
||||
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#define BOOST_THREAD_VERSION 2
|
||||
#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
|
||||
#define BOOST_TEST_MODULE Boost.Threads: 2309
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <iostream>
|
||||
@@ -40,7 +40,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
void test()
|
||||
BOOST_AUTO_TEST_CASE(test)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -61,14 +61,5 @@
|
||||
}
|
||||
}
|
||||
|
||||
boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test_framework::test_suite* tests =
|
||||
BOOST_TEST_SUITE("Boost.Threads: 2309");
|
||||
|
||||
tests->add(BOOST_TEST_CASE(&test));
|
||||
|
||||
return tests;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define BOOST_THREAD_VERSION 2
|
||||
|
||||
#define BOOST_TEST_MODULE Boost.Threads: thread attributes test suite
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
@@ -29,7 +29,7 @@ void simple_thread()
|
||||
test_value = 999;
|
||||
}
|
||||
|
||||
void test_native_handle()
|
||||
BOOST_AUTO_TEST_CASE(test_native_handle)
|
||||
{
|
||||
|
||||
boost::thread_attributes attrs;
|
||||
@@ -51,7 +51,7 @@ void test_native_handle()
|
||||
|
||||
}
|
||||
|
||||
void test_stack_size()
|
||||
BOOST_AUTO_TEST_CASE(test_stack_size)
|
||||
{
|
||||
boost::thread_attributes attrs;
|
||||
|
||||
@@ -70,18 +70,8 @@ void do_test_creation_with_attrs()
|
||||
BOOST_CHECK_EQUAL(test_value, 999);
|
||||
}
|
||||
|
||||
void test_creation_with_attrs()
|
||||
BOOST_AUTO_TEST_CASE(test_creation_with_attrs)
|
||||
{
|
||||
timed_test(&do_test_creation_with_attrs, 1);
|
||||
}
|
||||
|
||||
boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test_framework::test_suite* test = BOOST_TEST_SUITE("Boost.Threads: thread attributes test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(test_native_handle));
|
||||
test->add(BOOST_TEST_CASE(test_stack_size));
|
||||
test->add(BOOST_TEST_CASE(test_creation_with_attrs));
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
24
test/test_9856.cpp
Normal file
24
test/test_9856.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "boost/atomic.hpp"
|
||||
#include "boost/thread.hpp"
|
||||
#include <iostream>
|
||||
|
||||
using namespace boost;
|
||||
|
||||
int main() {
|
||||
atomic<size_t> total(0), failures(0);
|
||||
|
||||
#pragma omp parallel shared(total, failures) num_threads(1000)
|
||||
{
|
||||
mutex mtx;
|
||||
condition_variable cond;
|
||||
unique_lock<mutex> lk(mtx);
|
||||
for (int i = 0; i < 500; i++) {
|
||||
++total;
|
||||
if (cv_status::timeout != cond.wait_for(lk, chrono::milliseconds(10)))
|
||||
++failures;
|
||||
}
|
||||
}
|
||||
if(failures)
|
||||
std::cerr << "There were " << failures << " failures out of " << total << " timed waits." << std::endl;
|
||||
return failures!=0;
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#define BOOST_THREAD_VERSION 2
|
||||
#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
|
||||
#define BOOST_TEST_MODULE Boost.Threads: condition test suite
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#include <boost/thread/condition.hpp>
|
||||
@@ -156,7 +156,7 @@ void do_test_condition_waits()
|
||||
BOOST_CHECK_EQUAL(data.awoken, 5);
|
||||
}
|
||||
|
||||
void test_condition_waits()
|
||||
BOOST_AUTO_TEST_CASE(test_condition_waits)
|
||||
{
|
||||
// We should have already tested notify_one here, so
|
||||
// a timed test with the default execution_monitor::use_condition
|
||||
@@ -176,20 +176,8 @@ void do_test_condition_wait_is_a_interruption_point()
|
||||
}
|
||||
|
||||
|
||||
void test_condition_wait_is_a_interruption_point()
|
||||
BOOST_AUTO_TEST_CASE(test_condition_wait_is_a_interruption_point)
|
||||
{
|
||||
timed_test(&do_test_condition_wait_is_a_interruption_point, 1);
|
||||
}
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: condition test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(&test_condition_waits));
|
||||
test->add(BOOST_TEST_CASE(&test_condition_wait_is_a_interruption_point));
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define BOOST_THREAD_VERSION 2
|
||||
|
||||
#define BOOST_TEST_MODULE Boost.Threads: condition_variable notify_all test suite
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
@@ -202,7 +202,7 @@ void do_test_notify_all_following_notify_one_wakes_all_threads()
|
||||
thread3.join();
|
||||
}
|
||||
|
||||
void test_condition_notify_all()
|
||||
BOOST_AUTO_TEST_CASE(test_condition_notify_all)
|
||||
{
|
||||
timed_test(&do_test_condition_notify_all_wakes_from_wait, timeout_seconds);
|
||||
timed_test(&do_test_condition_notify_all_wakes_from_wait_with_predicate, timeout_seconds);
|
||||
@@ -213,14 +213,4 @@ void test_condition_notify_all()
|
||||
}
|
||||
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: condition test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(&test_condition_notify_all));
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#define BOOST_THREAD_VERSION 2
|
||||
|
||||
#define BOOST_TEST_MODULE Boost.Threads: condition_variable notify_one test suite
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
@@ -135,7 +137,7 @@ void do_test_multiple_notify_one_calls_wakes_multiple_threads()
|
||||
thread3.join();
|
||||
}
|
||||
|
||||
void test_condition_notify_one()
|
||||
BOOST_AUTO_TEST_CASE(test_condition_notify_one)
|
||||
{
|
||||
timed_test(&do_test_condition_notify_one_wakes_from_wait, timeout_seconds, execution_monitor::use_mutex);
|
||||
timed_test(&do_test_condition_notify_one_wakes_from_wait_with_predicate, timeout_seconds, execution_monitor::use_mutex);
|
||||
@@ -144,15 +146,3 @@ void test_condition_notify_one()
|
||||
timed_test(&do_test_condition_notify_one_wakes_from_relative_timed_wait_with_predicate, timeout_seconds, execution_monitor::use_mutex);
|
||||
timed_test(&do_test_multiple_notify_one_calls_wakes_multiple_threads, timeout_seconds, execution_monitor::use_mutex);
|
||||
}
|
||||
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: condition test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(&test_condition_notify_one));
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#define BOOST_THREAD_VERSION 2
|
||||
|
||||
#define BOOST_TEST_MODULE Boost.Threads: condition_variable test suite
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#include <boost/thread/condition.hpp>
|
||||
@@ -152,7 +154,7 @@ void do_test_cv_any_timed_wait_relative_times_out()
|
||||
}
|
||||
|
||||
|
||||
void test_timed_wait_times_out()
|
||||
BOOST_AUTO_TEST_CASE(test_timed_wait_times_out)
|
||||
{
|
||||
timed_test(&do_test_timed_wait_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex);
|
||||
timed_test(&do_test_timed_wait_with_predicate_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex);
|
||||
@@ -164,14 +166,4 @@ void test_timed_wait_times_out()
|
||||
timed_test(&do_test_cv_any_timed_wait_relative_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex);
|
||||
}
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: condition test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(&test_timed_wait_times_out));
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define BOOST_THREAD_VERSION 2
|
||||
#define BOOST_TEST_MODULE Boost.Threads: futures test suite
|
||||
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
@@ -93,7 +94,7 @@ void set_promise_exception_thread(boost::promise<int>* p)
|
||||
}
|
||||
|
||||
|
||||
void test_store_value_from_thread()
|
||||
BOOST_AUTO_TEST_CASE(test_store_value_from_thread)
|
||||
{
|
||||
LOG;
|
||||
try {
|
||||
@@ -122,8 +123,7 @@ void test_store_value_from_thread()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void test_store_exception()
|
||||
BOOST_AUTO_TEST_CASE(test_store_exception)
|
||||
{
|
||||
LOG;
|
||||
boost::promise<int> pi3;
|
||||
@@ -145,7 +145,7 @@ void test_store_exception()
|
||||
BOOST_CHECK(fi3.get_state()==boost::future_state::ready);
|
||||
}
|
||||
|
||||
void test_initial_state()
|
||||
BOOST_AUTO_TEST_CASE(test_initial_state)
|
||||
{
|
||||
LOG;
|
||||
boost::unique_future<int> fi;
|
||||
@@ -166,7 +166,7 @@ void test_initial_state()
|
||||
}
|
||||
}
|
||||
|
||||
void test_waiting_future()
|
||||
BOOST_AUTO_TEST_CASE(test_waiting_future)
|
||||
{
|
||||
LOG;
|
||||
boost::promise<int> pi;
|
||||
@@ -181,7 +181,7 @@ void test_waiting_future()
|
||||
BOOST_CHECK(i==0);
|
||||
}
|
||||
|
||||
void test_cannot_get_future_twice()
|
||||
BOOST_AUTO_TEST_CASE(test_cannot_get_future_twice)
|
||||
{
|
||||
LOG;
|
||||
boost::promise<int> pi;
|
||||
@@ -198,7 +198,7 @@ void test_cannot_get_future_twice()
|
||||
}
|
||||
}
|
||||
|
||||
void test_set_value_updates_future_state()
|
||||
BOOST_AUTO_TEST_CASE(test_set_value_updates_future_state)
|
||||
{
|
||||
LOG;
|
||||
boost::promise<int> pi;
|
||||
@@ -213,7 +213,7 @@ void test_set_value_updates_future_state()
|
||||
BOOST_CHECK(fi.get_state()==boost::future_state::ready);
|
||||
}
|
||||
|
||||
void test_set_value_can_be_retrieved()
|
||||
BOOST_AUTO_TEST_CASE(test_set_value_can_be_retrieved)
|
||||
{
|
||||
LOG;
|
||||
boost::promise<int> pi;
|
||||
@@ -231,7 +231,7 @@ void test_set_value_can_be_retrieved()
|
||||
BOOST_CHECK(fi.get_state()==boost::future_state::ready);
|
||||
}
|
||||
|
||||
void test_set_value_can_be_moved()
|
||||
BOOST_AUTO_TEST_CASE(test_set_value_can_be_moved)
|
||||
{
|
||||
LOG;
|
||||
// boost::promise<int> pi;
|
||||
@@ -249,7 +249,7 @@ void test_set_value_can_be_moved()
|
||||
// BOOST_CHECK(fi.get_state()==boost::future_state::ready);
|
||||
}
|
||||
|
||||
void test_future_from_packaged_task_is_waiting()
|
||||
BOOST_AUTO_TEST_CASE(test_future_from_packaged_task_is_waiting)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int);
|
||||
@@ -262,7 +262,7 @@ void test_future_from_packaged_task_is_waiting()
|
||||
BOOST_CHECK(i==0);
|
||||
}
|
||||
|
||||
void test_invoking_a_packaged_task_populates_future()
|
||||
BOOST_AUTO_TEST_CASE(test_invoking_a_packaged_task_populates_future)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int);
|
||||
@@ -279,7 +279,7 @@ void test_invoking_a_packaged_task_populates_future()
|
||||
BOOST_CHECK(i==42);
|
||||
}
|
||||
|
||||
void test_invoking_a_packaged_task_twice_throws()
|
||||
BOOST_AUTO_TEST_CASE(test_invoking_a_packaged_task_twice_throws)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int);
|
||||
@@ -297,7 +297,7 @@ void test_invoking_a_packaged_task_twice_throws()
|
||||
}
|
||||
|
||||
|
||||
void test_cannot_get_future_twice_from_task()
|
||||
BOOST_AUTO_TEST_CASE(test_cannot_get_future_twice_from_task)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int);
|
||||
@@ -313,7 +313,7 @@ void test_cannot_get_future_twice_from_task()
|
||||
}
|
||||
}
|
||||
|
||||
void test_task_stores_exception_if_function_throws()
|
||||
BOOST_AUTO_TEST_CASE(test_task_stores_exception_if_function_throws)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(throw_runtime_error);
|
||||
@@ -341,7 +341,7 @@ void test_task_stores_exception_if_function_throws()
|
||||
|
||||
}
|
||||
|
||||
void test_void_promise()
|
||||
BOOST_AUTO_TEST_CASE(test_void_promise)
|
||||
{
|
||||
LOG;
|
||||
boost::promise<void> p;
|
||||
@@ -354,7 +354,7 @@ void test_void_promise()
|
||||
f.get();
|
||||
}
|
||||
|
||||
void test_reference_promise()
|
||||
BOOST_AUTO_TEST_CASE(test_reference_promise)
|
||||
{
|
||||
LOG;
|
||||
boost::promise<int&> p;
|
||||
@@ -371,7 +371,7 @@ void test_reference_promise()
|
||||
void do_nothing()
|
||||
{}
|
||||
|
||||
void test_task_returning_void()
|
||||
BOOST_AUTO_TEST_CASE(test_task_returning_void)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<void> pt(do_nothing);
|
||||
@@ -392,7 +392,7 @@ int& return_ref()
|
||||
return global_ref_target;
|
||||
}
|
||||
|
||||
void test_task_returning_reference()
|
||||
BOOST_AUTO_TEST_CASE(test_task_returning_reference)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int&> pt(return_ref);
|
||||
@@ -408,7 +408,7 @@ void test_task_returning_reference()
|
||||
BOOST_CHECK(&i==&global_ref_target);
|
||||
}
|
||||
|
||||
void test_shared_future()
|
||||
BOOST_AUTO_TEST_CASE(test_shared_future)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int);
|
||||
@@ -428,7 +428,7 @@ void test_shared_future()
|
||||
BOOST_CHECK(i==42);
|
||||
}
|
||||
|
||||
void test_copies_of_shared_future_become_ready_together()
|
||||
BOOST_AUTO_TEST_CASE(test_copies_of_shared_future_become_ready_together)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int);
|
||||
@@ -467,7 +467,7 @@ void test_copies_of_shared_future_become_ready_together()
|
||||
BOOST_CHECK(i==42);
|
||||
}
|
||||
|
||||
void test_shared_future_can_be_move_assigned_from_unique_future()
|
||||
BOOST_AUTO_TEST_CASE(test_shared_future_can_be_move_assigned_from_unique_future)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int);
|
||||
@@ -483,7 +483,7 @@ void test_shared_future_can_be_move_assigned_from_unique_future()
|
||||
BOOST_CHECK(sf.get_state()==boost::future_state::waiting);
|
||||
}
|
||||
|
||||
void test_shared_future_void()
|
||||
BOOST_AUTO_TEST_CASE(test_shared_future_void)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<void> pt(do_nothing);
|
||||
@@ -501,7 +501,7 @@ void test_shared_future_void()
|
||||
sf.get();
|
||||
}
|
||||
|
||||
void test_shared_future_ref()
|
||||
BOOST_AUTO_TEST_CASE(test_shared_future_ref)
|
||||
{
|
||||
LOG;
|
||||
boost::promise<int&> p;
|
||||
@@ -515,7 +515,7 @@ void test_shared_future_ref()
|
||||
BOOST_CHECK(&f.get()==&i);
|
||||
}
|
||||
|
||||
void test_can_get_a_second_future_from_a_moved_promise()
|
||||
BOOST_AUTO_TEST_CASE(test_can_get_a_second_future_from_a_moved_promise)
|
||||
{
|
||||
LOG;
|
||||
boost::promise<int> pi;
|
||||
@@ -533,7 +533,7 @@ void test_can_get_a_second_future_from_a_moved_promise()
|
||||
BOOST_CHECK(fi2.get()==42);
|
||||
}
|
||||
|
||||
void test_can_get_a_second_future_from_a_moved_void_promise()
|
||||
BOOST_AUTO_TEST_CASE(test_can_get_a_second_future_from_a_moved_void_promise)
|
||||
{
|
||||
LOG;
|
||||
boost::promise<void> pi;
|
||||
@@ -549,7 +549,7 @@ void test_can_get_a_second_future_from_a_moved_void_promise()
|
||||
BOOST_CHECK(fi2.is_ready());
|
||||
}
|
||||
|
||||
void test_unique_future_for_move_only_udt()
|
||||
BOOST_AUTO_TEST_CASE(test_unique_future_for_move_only_udt)
|
||||
{
|
||||
LOG;
|
||||
boost::promise<X> pt;
|
||||
@@ -560,7 +560,7 @@ void test_unique_future_for_move_only_udt()
|
||||
BOOST_CHECK(res.i==42);
|
||||
}
|
||||
|
||||
void test_unique_future_for_string()
|
||||
BOOST_AUTO_TEST_CASE(test_unique_future_for_string)
|
||||
{
|
||||
LOG;
|
||||
boost::promise<std::string> pt;
|
||||
@@ -611,7 +611,7 @@ void do_nothing_callback(boost::promise<int>& /*pi*/)
|
||||
++callback_called;
|
||||
}
|
||||
|
||||
void test_wait_callback()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_callback)
|
||||
{
|
||||
LOG;
|
||||
callback_called=0;
|
||||
@@ -626,7 +626,7 @@ void test_wait_callback()
|
||||
BOOST_CHECK(callback_called==1);
|
||||
}
|
||||
|
||||
void test_wait_callback_with_timed_wait()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_callback_with_timed_wait)
|
||||
{
|
||||
LOG;
|
||||
callback_called=0;
|
||||
@@ -665,7 +665,7 @@ void wait_callback_for_task(boost::packaged_task<int>& pt)
|
||||
}
|
||||
|
||||
|
||||
void test_wait_callback_for_packaged_task()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_callback_for_packaged_task)
|
||||
{
|
||||
LOG;
|
||||
callback_called=0;
|
||||
@@ -680,7 +680,7 @@ void test_wait_callback_for_packaged_task()
|
||||
BOOST_CHECK(callback_called==1);
|
||||
}
|
||||
|
||||
void test_packaged_task_can_be_moved()
|
||||
BOOST_AUTO_TEST_CASE(test_packaged_task_can_be_moved)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int);
|
||||
@@ -708,7 +708,7 @@ void test_packaged_task_can_be_moved()
|
||||
BOOST_CHECK(fi.is_ready());
|
||||
}
|
||||
|
||||
void test_destroying_a_promise_stores_broken_promise()
|
||||
BOOST_AUTO_TEST_CASE(test_destroying_a_promise_stores_broken_promise)
|
||||
{
|
||||
LOG;
|
||||
boost::unique_future<int> f;
|
||||
@@ -728,7 +728,7 @@ void test_destroying_a_promise_stores_broken_promise()
|
||||
}
|
||||
}
|
||||
|
||||
void test_destroying_a_packaged_task_stores_broken_promise()
|
||||
BOOST_AUTO_TEST_CASE(test_destroying_a_packaged_task_stores_broken_promise)
|
||||
{
|
||||
LOG;
|
||||
boost::unique_future<int> f;
|
||||
@@ -754,7 +754,7 @@ int make_int_slowly()
|
||||
return 42;
|
||||
}
|
||||
|
||||
void test_wait_for_either_of_two_futures_1()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_two_futures_1)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int_slowly);
|
||||
@@ -772,7 +772,7 @@ void test_wait_for_either_of_two_futures_1()
|
||||
BOOST_CHECK(f1.get()==42);
|
||||
}
|
||||
|
||||
void test_wait_for_either_of_two_futures_2()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_two_futures_2)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int_slowly);
|
||||
@@ -790,7 +790,7 @@ void test_wait_for_either_of_two_futures_2()
|
||||
BOOST_CHECK(f2.get()==42);
|
||||
}
|
||||
|
||||
void test_wait_for_either_of_three_futures_1()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_1)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int_slowly);
|
||||
@@ -811,7 +811,7 @@ void test_wait_for_either_of_three_futures_1()
|
||||
BOOST_CHECK(f1.get()==42);
|
||||
}
|
||||
|
||||
void test_wait_for_either_of_three_futures_2()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_2)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int_slowly);
|
||||
@@ -832,7 +832,7 @@ void test_wait_for_either_of_three_futures_2()
|
||||
BOOST_CHECK(f2.get()==42);
|
||||
}
|
||||
|
||||
void test_wait_for_either_of_three_futures_3()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_3)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int_slowly);
|
||||
@@ -853,7 +853,7 @@ void test_wait_for_either_of_three_futures_3()
|
||||
BOOST_CHECK(f3.get()==42);
|
||||
}
|
||||
|
||||
void test_wait_for_either_of_four_futures_1()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_1)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int_slowly);
|
||||
@@ -877,7 +877,7 @@ void test_wait_for_either_of_four_futures_1()
|
||||
BOOST_CHECK(f1.get()==42);
|
||||
}
|
||||
|
||||
void test_wait_for_either_of_four_futures_2()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_2)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int_slowly);
|
||||
@@ -901,7 +901,7 @@ void test_wait_for_either_of_four_futures_2()
|
||||
BOOST_CHECK(f2.get()==42);
|
||||
}
|
||||
|
||||
void test_wait_for_either_of_four_futures_3()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_3)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int_slowly);
|
||||
@@ -925,7 +925,7 @@ void test_wait_for_either_of_four_futures_3()
|
||||
BOOST_CHECK(f3.get()==42);
|
||||
}
|
||||
|
||||
void test_wait_for_either_of_four_futures_4()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_4)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int_slowly);
|
||||
@@ -949,7 +949,7 @@ void test_wait_for_either_of_four_futures_4()
|
||||
BOOST_CHECK(f4.get()==42);
|
||||
}
|
||||
|
||||
void test_wait_for_either_of_five_futures_1()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_1)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int_slowly);
|
||||
@@ -976,7 +976,7 @@ void test_wait_for_either_of_five_futures_1()
|
||||
BOOST_CHECK(f1.get()==42);
|
||||
}
|
||||
|
||||
void test_wait_for_either_of_five_futures_2()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_2)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int_slowly);
|
||||
@@ -1002,7 +1002,7 @@ void test_wait_for_either_of_five_futures_2()
|
||||
BOOST_CHECK(!f5.is_ready());
|
||||
BOOST_CHECK(f2.get()==42);
|
||||
}
|
||||
void test_wait_for_either_of_five_futures_3()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_3)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int_slowly);
|
||||
@@ -1028,7 +1028,7 @@ void test_wait_for_either_of_five_futures_3()
|
||||
BOOST_CHECK(!f5.is_ready());
|
||||
BOOST_CHECK(f3.get()==42);
|
||||
}
|
||||
void test_wait_for_either_of_five_futures_4()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_4)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int_slowly);
|
||||
@@ -1054,7 +1054,7 @@ void test_wait_for_either_of_five_futures_4()
|
||||
BOOST_CHECK(!f5.is_ready());
|
||||
BOOST_CHECK(f4.get()==42);
|
||||
}
|
||||
void test_wait_for_either_of_five_futures_5()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_5)
|
||||
{
|
||||
LOG;
|
||||
boost::packaged_task<int> pt(make_int_slowly);
|
||||
@@ -1081,7 +1081,7 @@ void test_wait_for_either_of_five_futures_5()
|
||||
BOOST_CHECK(f5.get()==42);
|
||||
}
|
||||
|
||||
void test_wait_for_either_invokes_callbacks()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_either_invokes_callbacks)
|
||||
{
|
||||
LOG;
|
||||
callback_called=0;
|
||||
@@ -1098,7 +1098,7 @@ void test_wait_for_either_invokes_callbacks()
|
||||
BOOST_CHECK(fi.get()==42);
|
||||
}
|
||||
|
||||
void test_wait_for_any_from_range()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_any_from_range)
|
||||
{
|
||||
LOG;
|
||||
unsigned const count=10;
|
||||
@@ -1133,7 +1133,7 @@ void test_wait_for_any_from_range()
|
||||
}
|
||||
}
|
||||
|
||||
void test_wait_for_all_from_range()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_all_from_range)
|
||||
{
|
||||
LOG;
|
||||
unsigned const count=10;
|
||||
@@ -1153,7 +1153,7 @@ void test_wait_for_all_from_range()
|
||||
}
|
||||
}
|
||||
|
||||
void test_wait_for_all_two_futures()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_all_two_futures)
|
||||
{
|
||||
LOG;
|
||||
unsigned const count=2;
|
||||
@@ -1173,7 +1173,7 @@ void test_wait_for_all_two_futures()
|
||||
}
|
||||
}
|
||||
|
||||
void test_wait_for_all_three_futures()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_all_three_futures)
|
||||
{
|
||||
LOG;
|
||||
unsigned const count=3;
|
||||
@@ -1193,7 +1193,7 @@ void test_wait_for_all_three_futures()
|
||||
}
|
||||
}
|
||||
|
||||
void test_wait_for_all_four_futures()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_all_four_futures)
|
||||
{
|
||||
LOG;
|
||||
unsigned const count=4;
|
||||
@@ -1213,7 +1213,7 @@ void test_wait_for_all_four_futures()
|
||||
}
|
||||
}
|
||||
|
||||
void test_wait_for_all_five_futures()
|
||||
BOOST_AUTO_TEST_CASE(test_wait_for_all_five_futures)
|
||||
{
|
||||
LOG;
|
||||
unsigned const count=5;
|
||||
@@ -1232,68 +1232,3 @@ void test_wait_for_all_five_futures()
|
||||
BOOST_CHECK(futures[j].is_ready());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: futures test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(test_initial_state));
|
||||
test->add(BOOST_TEST_CASE(test_waiting_future));
|
||||
test->add(BOOST_TEST_CASE(test_cannot_get_future_twice));
|
||||
test->add(BOOST_TEST_CASE(test_set_value_updates_future_state));
|
||||
test->add(BOOST_TEST_CASE(test_set_value_can_be_retrieved));
|
||||
test->add(BOOST_TEST_CASE(test_set_value_can_be_moved));
|
||||
test->add(BOOST_TEST_CASE(test_store_value_from_thread));
|
||||
test->add(BOOST_TEST_CASE(test_store_exception));
|
||||
test->add(BOOST_TEST_CASE(test_future_from_packaged_task_is_waiting));
|
||||
test->add(BOOST_TEST_CASE(test_invoking_a_packaged_task_populates_future));
|
||||
test->add(BOOST_TEST_CASE(test_invoking_a_packaged_task_twice_throws));
|
||||
test->add(BOOST_TEST_CASE(test_cannot_get_future_twice_from_task));
|
||||
test->add(BOOST_TEST_CASE(test_task_stores_exception_if_function_throws));
|
||||
test->add(BOOST_TEST_CASE(test_void_promise));
|
||||
test->add(BOOST_TEST_CASE(test_reference_promise));
|
||||
test->add(BOOST_TEST_CASE(test_task_returning_void));
|
||||
test->add(BOOST_TEST_CASE(test_task_returning_reference));
|
||||
test->add(BOOST_TEST_CASE(test_shared_future));
|
||||
test->add(BOOST_TEST_CASE(test_copies_of_shared_future_become_ready_together));
|
||||
test->add(BOOST_TEST_CASE(test_shared_future_can_be_move_assigned_from_unique_future));
|
||||
test->add(BOOST_TEST_CASE(test_shared_future_void));
|
||||
test->add(BOOST_TEST_CASE(test_shared_future_ref));
|
||||
test->add(BOOST_TEST_CASE(test_can_get_a_second_future_from_a_moved_promise));
|
||||
test->add(BOOST_TEST_CASE(test_can_get_a_second_future_from_a_moved_void_promise));
|
||||
test->add(BOOST_TEST_CASE(test_unique_future_for_move_only_udt));
|
||||
test->add(BOOST_TEST_CASE(test_unique_future_for_string));
|
||||
test->add(BOOST_TEST_CASE(test_wait_callback));
|
||||
test->add(BOOST_TEST_CASE(test_wait_callback_with_timed_wait));
|
||||
test->add(BOOST_TEST_CASE(test_wait_callback_for_packaged_task));
|
||||
test->add(BOOST_TEST_CASE(test_packaged_task_can_be_moved));
|
||||
test->add(BOOST_TEST_CASE(test_destroying_a_promise_stores_broken_promise));
|
||||
test->add(BOOST_TEST_CASE(test_destroying_a_packaged_task_stores_broken_promise));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_either_of_two_futures_1));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_either_of_two_futures_2));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_either_of_three_futures_1));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_either_of_three_futures_2));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_either_of_three_futures_3));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_either_of_four_futures_1));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_either_of_four_futures_2));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_either_of_four_futures_3));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_either_of_four_futures_4));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_either_of_five_futures_1));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_either_of_five_futures_2));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_either_of_five_futures_3));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_either_of_five_futures_4));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_either_of_five_futures_5));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_either_invokes_callbacks));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_any_from_range));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_all_from_range));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_all_two_futures));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_all_three_futures));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_all_four_futures));
|
||||
test->add(BOOST_TEST_CASE(test_wait_for_all_five_futures));
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,13 +5,15 @@
|
||||
|
||||
#define BOOST_THREAD_VERSION 2
|
||||
|
||||
#define BOOST_TEST_MODULE Boost.Threads: generic locks test suite
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
#include <boost/thread/locks.hpp>
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
|
||||
void test_lock_two_uncontended()
|
||||
BOOST_AUTO_TEST_CASE(test_lock_two_uncontended)
|
||||
{
|
||||
boost::mutex m1,m2;
|
||||
|
||||
@@ -87,7 +89,7 @@ void lock_pair(boost::mutex* m1,boost::mutex* m2)
|
||||
l2(*m2,boost::adopt_lock);
|
||||
}
|
||||
|
||||
void test_lock_two_other_thread_locks_in_order()
|
||||
BOOST_AUTO_TEST_CASE(test_lock_two_other_thread_locks_in_order)
|
||||
{
|
||||
boost::mutex m1,m2;
|
||||
wait_data locked;
|
||||
@@ -106,7 +108,7 @@ void test_lock_two_other_thread_locks_in_order()
|
||||
t.join();
|
||||
}
|
||||
|
||||
void test_lock_two_other_thread_locks_in_opposite_order()
|
||||
BOOST_AUTO_TEST_CASE(test_lock_two_other_thread_locks_in_opposite_order)
|
||||
{
|
||||
boost::mutex m1,m2;
|
||||
wait_data locked;
|
||||
@@ -125,7 +127,7 @@ void test_lock_two_other_thread_locks_in_opposite_order()
|
||||
t.join();
|
||||
}
|
||||
|
||||
void test_lock_five_uncontended()
|
||||
BOOST_AUTO_TEST_CASE(test_lock_five_uncontended)
|
||||
{
|
||||
boost::mutex m1,m2,m3,m4,m5;
|
||||
|
||||
@@ -176,7 +178,7 @@ void lock_five(boost::mutex* m1,boost::mutex* m2,boost::mutex* m3,boost::mutex*
|
||||
m5->unlock();
|
||||
}
|
||||
|
||||
void test_lock_five_other_thread_locks_in_order()
|
||||
BOOST_AUTO_TEST_CASE(test_lock_five_other_thread_locks_in_order)
|
||||
{
|
||||
boost::mutex m1,m2,m3,m4,m5;
|
||||
wait_data locked;
|
||||
@@ -195,7 +197,7 @@ void test_lock_five_other_thread_locks_in_order()
|
||||
t.join();
|
||||
}
|
||||
|
||||
void test_lock_five_other_thread_locks_in_different_order()
|
||||
BOOST_AUTO_TEST_CASE(test_lock_five_other_thread_locks_in_different_order)
|
||||
{
|
||||
boost::mutex m1,m2,m3,m4,m5;
|
||||
wait_data locked;
|
||||
@@ -224,7 +226,7 @@ void lock_n(boost::mutex* mutexes,unsigned count)
|
||||
}
|
||||
|
||||
|
||||
void test_lock_ten_other_thread_locks_in_different_order()
|
||||
BOOST_AUTO_TEST_CASE(test_lock_ten_other_thread_locks_in_different_order)
|
||||
{
|
||||
unsigned const num_mutexes=10;
|
||||
|
||||
@@ -285,7 +287,7 @@ namespace boost
|
||||
|
||||
|
||||
|
||||
void test_lock_five_in_range()
|
||||
BOOST_AUTO_TEST_CASE(test_lock_five_in_range)
|
||||
{
|
||||
unsigned const num_mutexes=5;
|
||||
dummy_mutex mutexes[num_mutexes];
|
||||
@@ -350,7 +352,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
void test_lock_five_in_range_custom_iterator()
|
||||
BOOST_AUTO_TEST_CASE(test_lock_five_in_range_custom_iterator)
|
||||
{
|
||||
unsigned const num_mutexes=5;
|
||||
dummy_mutex mutexes[num_mutexes];
|
||||
@@ -368,7 +370,7 @@ class dummy_mutex2:
|
||||
{};
|
||||
|
||||
|
||||
void test_lock_ten_in_range_inherited_mutex()
|
||||
BOOST_AUTO_TEST_CASE(test_lock_ten_in_range_inherited_mutex)
|
||||
{
|
||||
unsigned const num_mutexes=10;
|
||||
dummy_mutex2 mutexes[num_mutexes];
|
||||
@@ -381,7 +383,7 @@ void test_lock_ten_in_range_inherited_mutex()
|
||||
}
|
||||
}
|
||||
|
||||
void test_try_lock_two_uncontended()
|
||||
BOOST_AUTO_TEST_CASE(test_try_lock_two_uncontended)
|
||||
{
|
||||
dummy_mutex m1,m2;
|
||||
|
||||
@@ -391,7 +393,7 @@ void test_try_lock_two_uncontended()
|
||||
BOOST_CHECK(m1.is_locked);
|
||||
BOOST_CHECK(m2.is_locked);
|
||||
}
|
||||
void test_try_lock_two_first_locked()
|
||||
BOOST_AUTO_TEST_CASE(test_try_lock_two_first_locked)
|
||||
{
|
||||
dummy_mutex m1,m2;
|
||||
m1.lock();
|
||||
@@ -407,7 +409,7 @@ void test_try_lock_two_first_locked()
|
||||
BOOST_CHECK(!l1.owns_lock());
|
||||
BOOST_CHECK(!l2.owns_lock());
|
||||
}
|
||||
void test_try_lock_two_second_locked()
|
||||
BOOST_AUTO_TEST_CASE(test_try_lock_two_second_locked)
|
||||
{
|
||||
dummy_mutex m1,m2;
|
||||
m2.lock();
|
||||
@@ -424,7 +426,7 @@ void test_try_lock_two_second_locked()
|
||||
BOOST_CHECK(!l2.owns_lock());
|
||||
}
|
||||
|
||||
void test_try_lock_three()
|
||||
BOOST_AUTO_TEST_CASE(test_try_lock_three)
|
||||
{
|
||||
int const num_mutexes=3;
|
||||
|
||||
@@ -469,7 +471,7 @@ void test_try_lock_three()
|
||||
}
|
||||
}
|
||||
|
||||
void test_try_lock_four()
|
||||
BOOST_AUTO_TEST_CASE(test_try_lock_four)
|
||||
{
|
||||
int const num_mutexes=4;
|
||||
|
||||
@@ -517,7 +519,7 @@ void test_try_lock_four()
|
||||
}
|
||||
}
|
||||
|
||||
void test_try_lock_five()
|
||||
BOOST_AUTO_TEST_CASE(test_try_lock_five)
|
||||
{
|
||||
int const num_mutexes=5;
|
||||
|
||||
@@ -568,31 +570,3 @@ void test_try_lock_five()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: generic locks test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(&test_lock_two_uncontended));
|
||||
test->add(BOOST_TEST_CASE(&test_lock_two_other_thread_locks_in_order));
|
||||
test->add(BOOST_TEST_CASE(&test_lock_two_other_thread_locks_in_opposite_order));
|
||||
test->add(BOOST_TEST_CASE(&test_lock_five_uncontended));
|
||||
test->add(BOOST_TEST_CASE(&test_lock_five_other_thread_locks_in_order));
|
||||
test->add(BOOST_TEST_CASE(&test_lock_five_other_thread_locks_in_different_order));
|
||||
test->add(BOOST_TEST_CASE(&test_lock_five_in_range));
|
||||
test->add(BOOST_TEST_CASE(&test_lock_five_in_range_custom_iterator));
|
||||
test->add(BOOST_TEST_CASE(&test_lock_ten_in_range_inherited_mutex));
|
||||
test->add(BOOST_TEST_CASE(&test_lock_ten_other_thread_locks_in_different_order));
|
||||
test->add(BOOST_TEST_CASE(&test_try_lock_two_uncontended));
|
||||
test->add(BOOST_TEST_CASE(&test_try_lock_two_first_locked));
|
||||
test->add(BOOST_TEST_CASE(&test_try_lock_two_second_locked));
|
||||
test->add(BOOST_TEST_CASE(&test_try_lock_three));
|
||||
test->add(BOOST_TEST_CASE(&test_try_lock_four));
|
||||
test->add(BOOST_TEST_CASE(&test_try_lock_five));
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,22 +2,16 @@
|
||||
//
|
||||
// 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)
|
||||
|
||||
#define BOOST_TEST_MODULE Boost.Threads: hardware_concurrency test suite
|
||||
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
void test_hardware_concurrency_is_non_zero()
|
||||
BOOST_AUTO_TEST_CASE(test_hardware_concurrency_is_non_zero)
|
||||
{
|
||||
BOOST_CHECK(boost::thread::hardware_concurrency()!=0);
|
||||
}
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: hardware concurrency test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(test_hardware_concurrency_is_non_zero));
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define BOOST_THREAD_VERSION 2
|
||||
#define BOOST_TEST_MODULE Boost.Threads: lock_concept test suite
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/test_case_template.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/lock_types.hpp>
|
||||
@@ -438,22 +440,30 @@ void test_lock_is_scoped_lock_concept_for_mutex()
|
||||
test_unlocked_after_try_lock_if_other_thread_has_lock<Mutex,Lock>()();
|
||||
}
|
||||
|
||||
typedef boost::mpl::vector<boost::mutex,boost::try_mutex,boost::timed_mutex,
|
||||
boost::recursive_mutex,boost::recursive_try_mutex,boost::recursive_timed_mutex> mutex_types_with_scoped_lock;
|
||||
|
||||
BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_scoped_lock_concept,Mutex)
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(test_scoped_lock_concept,Mutex,mutex_types_with_scoped_lock)
|
||||
{
|
||||
typedef typename Mutex::scoped_lock Lock;
|
||||
|
||||
test_lock_is_scoped_lock_concept_for_mutex<Mutex,Lock>();
|
||||
}
|
||||
|
||||
BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_unique_lock_is_scoped_lock,Mutex)
|
||||
typedef boost::mpl::vector<boost::mutex,boost::try_mutex,boost::timed_mutex,
|
||||
boost::recursive_mutex,boost::recursive_try_mutex,boost::recursive_timed_mutex,boost::shared_mutex> all_mutex_types;
|
||||
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(test_unique_lock_is_scoped_lock,Mutex,all_mutex_types)
|
||||
{
|
||||
typedef boost::unique_lock<Mutex> Lock;
|
||||
|
||||
test_lock_is_scoped_lock_concept_for_mutex<Mutex,Lock>();
|
||||
}
|
||||
|
||||
BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_scoped_try_lock_concept,Mutex)
|
||||
typedef boost::mpl::vector<boost::try_mutex,boost::timed_mutex,
|
||||
boost::recursive_try_mutex,boost::recursive_timed_mutex> mutex_types_with_scoped_try_lock;
|
||||
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(test_scoped_try_lock_concept,Mutex,mutex_types_with_scoped_try_lock)
|
||||
{
|
||||
typedef typename Mutex::scoped_try_lock Lock;
|
||||
|
||||
@@ -534,7 +544,7 @@ struct dummy_shared_mutex
|
||||
};
|
||||
|
||||
|
||||
void test_shared_lock()
|
||||
BOOST_AUTO_TEST_CASE(test_shared_lock)
|
||||
{
|
||||
typedef boost::shared_mutex Mutex;
|
||||
typedef boost::shared_lock<Mutex> Lock;
|
||||
@@ -564,27 +574,27 @@ void test_shared_lock()
|
||||
BOOST_CHECK(dummy.shared_timed_locked_absolute);
|
||||
}
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: lock concept test suite");
|
||||
|
||||
typedef boost::mpl::vector<boost::mutex,boost::try_mutex,boost::timed_mutex,
|
||||
boost::recursive_mutex,boost::recursive_try_mutex,boost::recursive_timed_mutex> mutex_types_with_scoped_lock;
|
||||
|
||||
test->add(BOOST_TEST_CASE_TEMPLATE(test_scoped_lock_concept,mutex_types_with_scoped_lock));
|
||||
|
||||
typedef boost::mpl::vector<boost::try_mutex,boost::timed_mutex,
|
||||
boost::recursive_try_mutex,boost::recursive_timed_mutex> mutex_types_with_scoped_try_lock;
|
||||
|
||||
test->add(BOOST_TEST_CASE_TEMPLATE(test_scoped_try_lock_concept,mutex_types_with_scoped_try_lock));
|
||||
|
||||
typedef boost::mpl::vector<boost::mutex,boost::try_mutex,boost::timed_mutex,
|
||||
boost::recursive_mutex,boost::recursive_try_mutex,boost::recursive_timed_mutex,boost::shared_mutex> all_mutex_types;
|
||||
|
||||
test->add(BOOST_TEST_CASE_TEMPLATE(test_unique_lock_is_scoped_lock,all_mutex_types));
|
||||
test->add(BOOST_TEST_CASE(&test_shared_lock));
|
||||
|
||||
return test;
|
||||
}
|
||||
//boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
//{
|
||||
// boost::unit_test::test_suite* test =
|
||||
// BOOST_TEST_SUITE("Boost.Threads: lock concept test suite");
|
||||
//
|
||||
// typedef boost::mpl::vector<boost::mutex,boost::try_mutex,boost::timed_mutex,
|
||||
// boost::recursive_mutex,boost::recursive_try_mutex,boost::recursive_timed_mutex> mutex_types_with_scoped_lock;
|
||||
//
|
||||
// test->add(BOOST_TEST_CASE_TEMPLATE(test_scoped_lock_concept,mutex_types_with_scoped_lock));
|
||||
//
|
||||
// typedef boost::mpl::vector<boost::try_mutex,boost::timed_mutex,
|
||||
// boost::recursive_try_mutex,boost::recursive_timed_mutex> mutex_types_with_scoped_try_lock;
|
||||
//
|
||||
// test->add(BOOST_TEST_CASE_TEMPLATE(test_scoped_try_lock_concept,mutex_types_with_scoped_try_lock));
|
||||
//
|
||||
// typedef boost::mpl::vector<boost::mutex,boost::try_mutex,boost::timed_mutex,
|
||||
// boost::recursive_mutex,boost::recursive_try_mutex,boost::recursive_timed_mutex,boost::shared_mutex> all_mutex_types;
|
||||
//
|
||||
// test->add(BOOST_TEST_CASE_TEMPLATE(test_unique_lock_is_scoped_lock,all_mutex_types));
|
||||
// test->add(BOOST_TEST_CASE(&test_shared_lock));
|
||||
//
|
||||
// return test;
|
||||
//}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define BOOST_THREAD_VERSION 2
|
||||
#define BOOST_TEST_MODULE Boost.Threads: move function test suite
|
||||
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
@@ -13,7 +14,7 @@
|
||||
void do_nothing()
|
||||
{}
|
||||
|
||||
void test_thread_move_from_lvalue_on_construction()
|
||||
BOOST_AUTO_TEST_CASE(test_thread_move_from_lvalue_on_construction)
|
||||
{
|
||||
boost::thread src(do_nothing);
|
||||
boost::thread::id src_id=src.get_id();
|
||||
@@ -24,7 +25,7 @@ void test_thread_move_from_lvalue_on_construction()
|
||||
dest.join();
|
||||
}
|
||||
|
||||
void test_thread_move_from_lvalue_on_assignment()
|
||||
BOOST_AUTO_TEST_CASE(test_thread_move_from_lvalue_on_assignment)
|
||||
{
|
||||
boost::thread src(do_nothing);
|
||||
boost::thread::id src_id=src.get_id();
|
||||
@@ -41,14 +42,14 @@ boost::thread start_thread()
|
||||
return boost::thread(do_nothing);
|
||||
}
|
||||
|
||||
void test_thread_move_from_rvalue_on_construction()
|
||||
BOOST_AUTO_TEST_CASE(test_thread_move_from_rvalue_on_construction)
|
||||
{
|
||||
boost::thread x(start_thread());
|
||||
BOOST_CHECK(x.get_id()!=boost::thread::id());
|
||||
x.join();
|
||||
}
|
||||
|
||||
void test_thread_move_from_rvalue_using_explicit_move()
|
||||
BOOST_AUTO_TEST_CASE(test_thread_move_from_rvalue_using_explicit_move)
|
||||
{
|
||||
//boost::thread x(boost::move(start_thread()));
|
||||
boost::thread x=start_thread();
|
||||
@@ -56,7 +57,7 @@ void test_thread_move_from_rvalue_using_explicit_move()
|
||||
x.join();
|
||||
}
|
||||
|
||||
void test_unique_lock_move_from_lvalue_on_construction()
|
||||
BOOST_AUTO_TEST_CASE(test_unique_lock_move_from_lvalue_on_construction)
|
||||
{
|
||||
boost::mutex m;
|
||||
boost::unique_lock<boost::mutex> l(m);
|
||||
@@ -76,7 +77,7 @@ boost::unique_lock<boost::mutex> get_lock(boost::mutex& m)
|
||||
}
|
||||
|
||||
|
||||
void test_unique_lock_move_from_rvalue_on_construction()
|
||||
BOOST_AUTO_TEST_CASE(test_unique_lock_move_from_rvalue_on_construction)
|
||||
{
|
||||
boost::mutex m;
|
||||
boost::unique_lock<boost::mutex> l(get_lock(m));
|
||||
@@ -117,7 +118,7 @@ namespace boost
|
||||
BOOST_THREAD_DCL_MOVABLE(user_test_ns::nc)
|
||||
}
|
||||
|
||||
void test_move_for_user_defined_type_unaffected()
|
||||
BOOST_AUTO_TEST_CASE(test_move_for_user_defined_type_unaffected)
|
||||
{
|
||||
user_test_ns::nc src;
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
@@ -128,19 +129,6 @@ void test_move_for_user_defined_type_unaffected()
|
||||
BOOST_CHECK(user_test_ns::move_called);
|
||||
}
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: thread move test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(test_thread_move_from_lvalue_on_construction));
|
||||
test->add(BOOST_TEST_CASE(test_thread_move_from_rvalue_on_construction));
|
||||
test->add(BOOST_TEST_CASE(test_thread_move_from_rvalue_using_explicit_move));
|
||||
test->add(BOOST_TEST_CASE(test_thread_move_from_lvalue_on_assignment));
|
||||
test->add(BOOST_TEST_CASE(test_unique_lock_move_from_lvalue_on_construction));
|
||||
test->add(BOOST_TEST_CASE(test_unique_lock_move_from_rvalue_on_construction));
|
||||
test->add(BOOST_TEST_CASE(test_move_for_user_defined_type_unaffected));
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define BOOST_THREAD_VERSION 2
|
||||
#define BOOST_TEST_MODULE Boost.Threads: mutex test suite
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
@@ -15,6 +16,8 @@
|
||||
#include <boost/thread/thread_time.hpp>
|
||||
#include <boost/thread/condition.hpp>
|
||||
|
||||
#define BOOST_TEST_MODULE Boost.Threads: mutex test suite
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_sleep_only
|
||||
@@ -270,7 +273,7 @@ void do_test_mutex()
|
||||
test_lock<boost::mutex>()();
|
||||
}
|
||||
|
||||
void test_mutex()
|
||||
BOOST_AUTO_TEST_CASE(test_mutex)
|
||||
{
|
||||
timed_test(&do_test_mutex, 3);
|
||||
}
|
||||
@@ -281,7 +284,7 @@ void do_test_try_mutex()
|
||||
test_trylock<boost::try_mutex>()();
|
||||
}
|
||||
|
||||
void test_try_mutex()
|
||||
BOOST_AUTO_TEST_CASE(test_try_mutex)
|
||||
{
|
||||
timed_test(&do_test_try_mutex, 3);
|
||||
}
|
||||
@@ -293,7 +296,7 @@ void do_test_timed_mutex()
|
||||
test_timedlock<boost::timed_mutex>()();
|
||||
}
|
||||
|
||||
void test_timed_mutex()
|
||||
BOOST_AUTO_TEST_CASE(test_timed_mutex)
|
||||
{
|
||||
timed_test(&do_test_timed_mutex, 3);
|
||||
}
|
||||
@@ -304,7 +307,7 @@ void do_test_recursive_mutex()
|
||||
test_recursive_lock<boost::recursive_mutex>()();
|
||||
}
|
||||
|
||||
void test_recursive_mutex()
|
||||
BOOST_AUTO_TEST_CASE(test_recursive_mutex)
|
||||
{
|
||||
timed_test(&do_test_recursive_mutex, 3);
|
||||
}
|
||||
@@ -316,7 +319,7 @@ void do_test_recursive_try_mutex()
|
||||
test_recursive_lock<boost::recursive_try_mutex>()();
|
||||
}
|
||||
|
||||
void test_recursive_try_mutex()
|
||||
BOOST_AUTO_TEST_CASE(test_recursive_try_mutex)
|
||||
{
|
||||
timed_test(&do_test_recursive_try_mutex, 3);
|
||||
}
|
||||
@@ -329,24 +332,10 @@ void do_test_recursive_timed_mutex()
|
||||
test_recursive_lock<boost::recursive_timed_mutex>()();
|
||||
}
|
||||
|
||||
void test_recursive_timed_mutex()
|
||||
BOOST_AUTO_TEST_CASE(test_recursive_timed_mutex)
|
||||
{
|
||||
timed_test(&do_test_recursive_timed_mutex, 3);
|
||||
}
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: mutex test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(&test_mutex));
|
||||
test->add(BOOST_TEST_CASE(&test_try_mutex));
|
||||
test->add(BOOST_TEST_CASE(&test_timed_mutex));
|
||||
test->add(BOOST_TEST_CASE(&test_recursive_mutex));
|
||||
test->add(BOOST_TEST_CASE(&test_recursive_try_mutex));
|
||||
test->add(BOOST_TEST_CASE(&test_recursive_timed_mutex));
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#define BOOST_THREAD_VERSION 2
|
||||
#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
#define BOOST_TEST_MODULE Boost.Threads: once test suite
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
@@ -43,7 +44,7 @@ void call_once_thread()
|
||||
BOOST_CHECK_EQUAL(my_once_value, 1);
|
||||
}
|
||||
|
||||
void test_call_once()
|
||||
BOOST_AUTO_TEST_CASE(test_call_once)
|
||||
{
|
||||
LOG;
|
||||
|
||||
@@ -102,7 +103,7 @@ void call_once_with_functor()
|
||||
BOOST_CHECK_EQUAL(my_once_value, 1);
|
||||
}
|
||||
|
||||
void test_call_once_arbitrary_functor()
|
||||
BOOST_AUTO_TEST_CASE(test_call_once_arbitrary_functor)
|
||||
{
|
||||
LOG;
|
||||
|
||||
@@ -163,7 +164,7 @@ void call_once_with_exception()
|
||||
}
|
||||
}
|
||||
|
||||
void test_call_once_retried_on_exception()
|
||||
BOOST_AUTO_TEST_CASE(test_call_once_retried_on_exception)
|
||||
{
|
||||
LOG;
|
||||
unsigned const num_threads=20;
|
||||
@@ -189,16 +190,3 @@ void test_call_once_retried_on_exception()
|
||||
}
|
||||
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: call_once test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(test_call_once));
|
||||
test->add(BOOST_TEST_CASE(test_call_once_arbitrary_functor));
|
||||
test->add(BOOST_TEST_CASE(test_call_once_retried_on_exception));
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,22 +3,18 @@
|
||||
//
|
||||
// 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)
|
||||
|
||||
#define BOOST_TEST_MODULE Boost.Threads: physical_concurrency test suite
|
||||
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
void test_physical_concurrency_is_non_zero()
|
||||
BOOST_AUTO_TEST_CASE(test_physical_concurrency_is_non_zero)
|
||||
{
|
||||
BOOST_CHECK(boost::thread::physical_concurrency()!=0);
|
||||
}
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: physical concurrency test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(test_physical_concurrency_is_non_zero));
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ void fn(int x)
|
||||
std::cout << x << std::endl;
|
||||
}
|
||||
|
||||
void test_scheduler(const int n, boost::scheduler& sch)
|
||||
void test_scheduler(const int n, boost::scheduler<>& sch)
|
||||
{
|
||||
for(int i = 1; i <= n; i++)
|
||||
{
|
||||
@@ -40,7 +40,7 @@ void test_scheduler(const int n, boost::scheduler& sch)
|
||||
}
|
||||
}
|
||||
|
||||
void test_after(const int n, boost::scheduler& sch)
|
||||
void test_after(const int n, boost::scheduler<>& sch)
|
||||
{
|
||||
for(int i = 1; i <= n; i++)
|
||||
{
|
||||
@@ -49,7 +49,7 @@ void test_after(const int n, boost::scheduler& sch)
|
||||
}
|
||||
}
|
||||
|
||||
void test_at(const int n, boost::scheduler& sch)
|
||||
void test_at(const int n, boost::scheduler<>& sch)
|
||||
{
|
||||
for(int i = 1; i <= n; i++)
|
||||
{
|
||||
@@ -58,7 +58,7 @@ void test_at(const int n, boost::scheduler& sch)
|
||||
}
|
||||
}
|
||||
|
||||
void test_on(const int n, boost::scheduler& sch, thread_pool& tp)
|
||||
void test_on(const int n, boost::scheduler<>& sch, thread_pool& tp)
|
||||
{
|
||||
for(int i = 1; i <= n; i++)
|
||||
{
|
||||
@@ -70,7 +70,7 @@ void test_on(const int n, boost::scheduler& sch, thread_pool& tp)
|
||||
int main()
|
||||
{
|
||||
thread_pool tp(4);
|
||||
boost::scheduler sch;
|
||||
boost::scheduler<> sch;
|
||||
test_scheduler(5, sch);
|
||||
test_after(5, sch);
|
||||
test_at(5, sch);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#define BOOST_THREAD_VERSION 2
|
||||
#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
#define BOOST_TEST_MODULE Boost.Threads: shared_mutex test suite
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
@@ -18,7 +19,7 @@
|
||||
BOOST_CHECK_EQUAL(value,expected_value); \
|
||||
}
|
||||
|
||||
void test_multiple_readers()
|
||||
BOOST_AUTO_TEST_CASE(test_multiple_readers)
|
||||
{
|
||||
std::cout << __LINE__ << std::endl;
|
||||
unsigned const number_of_threads=10;
|
||||
@@ -66,7 +67,7 @@ void test_multiple_readers()
|
||||
CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,number_of_threads);
|
||||
}
|
||||
|
||||
void test_only_one_writer_permitted()
|
||||
BOOST_AUTO_TEST_CASE(test_only_one_writer_permitted)
|
||||
{
|
||||
std::cout << __LINE__ << std::endl;
|
||||
unsigned const number_of_threads=10;
|
||||
@@ -109,7 +110,7 @@ void test_only_one_writer_permitted()
|
||||
CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,1u);
|
||||
}
|
||||
|
||||
void test_reader_blocks_writer()
|
||||
BOOST_AUTO_TEST_CASE(test_reader_blocks_writer)
|
||||
{
|
||||
std::cout << __LINE__ << std::endl;
|
||||
boost::thread_group pool;
|
||||
@@ -156,7 +157,7 @@ void test_reader_blocks_writer()
|
||||
CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,1u);
|
||||
}
|
||||
|
||||
void test_unlocking_writer_unblocks_all_readers()
|
||||
BOOST_AUTO_TEST_CASE(test_unlocking_writer_unblocks_all_readers)
|
||||
{
|
||||
std::cout << __LINE__ << std::endl;
|
||||
boost::thread_group pool;
|
||||
@@ -208,7 +209,7 @@ void test_unlocking_writer_unblocks_all_readers()
|
||||
CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,reader_count);
|
||||
}
|
||||
|
||||
void test_unlocking_last_reader_only_unblocks_one_writer()
|
||||
BOOST_AUTO_TEST_CASE(test_unlocking_last_reader_only_unblocks_one_writer)
|
||||
{
|
||||
std::cout << __LINE__ << std::endl;
|
||||
boost::thread_group pool;
|
||||
@@ -277,19 +278,3 @@ void test_unlocking_last_reader_only_unblocks_one_writer()
|
||||
CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_readers,reader_count);
|
||||
CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_writers,1u);
|
||||
}
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: shared_mutex test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(&test_multiple_readers));
|
||||
test->add(BOOST_TEST_CASE(&test_only_one_writer_permitted));
|
||||
test->add(BOOST_TEST_CASE(&test_reader_blocks_writer));
|
||||
test->add(BOOST_TEST_CASE(&test_unlocking_writer_unblocks_all_readers));
|
||||
test->add(BOOST_TEST_CASE(&test_unlocking_last_reader_only_unblocks_one_writer));
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define BOOST_THREAD_VERSION 2
|
||||
#define BOOST_TEST_MODULE Boost.Threads: shared_mutex_part2 test suite
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
@@ -49,7 +50,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
void test_only_one_upgrade_lock_permitted()
|
||||
BOOST_AUTO_TEST_CASE(test_only_one_upgrade_lock_permitted)
|
||||
{
|
||||
unsigned const number_of_threads=2;
|
||||
|
||||
@@ -91,7 +92,7 @@ void test_only_one_upgrade_lock_permitted()
|
||||
CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,1u);
|
||||
}
|
||||
|
||||
void test_can_lock_upgrade_if_currently_locked_shared()
|
||||
BOOST_AUTO_TEST_CASE(test_can_lock_upgrade_if_currently_locked_shared)
|
||||
{
|
||||
boost::thread_group pool;
|
||||
|
||||
@@ -140,7 +141,7 @@ void test_can_lock_upgrade_if_currently_locked_shared()
|
||||
CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,reader_count+1);
|
||||
}
|
||||
|
||||
void test_can_lock_upgrade_to_unique_if_currently_locked_upgrade()
|
||||
BOOST_AUTO_TEST_CASE(test_can_lock_upgrade_to_unique_if_currently_locked_upgrade)
|
||||
{
|
||||
boost::shared_mutex mtx;
|
||||
boost::upgrade_lock<boost::shared_mutex> l(mtx);
|
||||
@@ -148,7 +149,7 @@ void test_can_lock_upgrade_to_unique_if_currently_locked_upgrade()
|
||||
BOOST_CHECK(ul.owns_lock());
|
||||
}
|
||||
|
||||
void test_if_other_thread_has_write_lock_try_lock_shared_returns_false()
|
||||
BOOST_AUTO_TEST_CASE(test_if_other_thread_has_write_lock_try_lock_shared_returns_false)
|
||||
{
|
||||
|
||||
boost::shared_mutex rw_mutex;
|
||||
@@ -171,7 +172,7 @@ void test_if_other_thread_has_write_lock_try_lock_shared_returns_false()
|
||||
writer.join();
|
||||
}
|
||||
|
||||
void test_if_other_thread_has_write_lock_try_lock_upgrade_returns_false()
|
||||
BOOST_AUTO_TEST_CASE(test_if_other_thread_has_write_lock_try_lock_upgrade_returns_false)
|
||||
{
|
||||
|
||||
boost::shared_mutex rw_mutex;
|
||||
@@ -194,7 +195,7 @@ void test_if_other_thread_has_write_lock_try_lock_upgrade_returns_false()
|
||||
writer.join();
|
||||
}
|
||||
|
||||
void test_if_no_thread_has_lock_try_lock_shared_returns_true()
|
||||
BOOST_AUTO_TEST_CASE(test_if_no_thread_has_lock_try_lock_shared_returns_true)
|
||||
{
|
||||
boost::shared_mutex rw_mutex;
|
||||
bool const try_succeeded=rw_mutex.try_lock_shared();
|
||||
@@ -205,7 +206,7 @@ void test_if_no_thread_has_lock_try_lock_shared_returns_true()
|
||||
}
|
||||
}
|
||||
|
||||
void test_if_no_thread_has_lock_try_lock_upgrade_returns_true()
|
||||
BOOST_AUTO_TEST_CASE(test_if_no_thread_has_lock_try_lock_upgrade_returns_true)
|
||||
{
|
||||
boost::shared_mutex rw_mutex;
|
||||
bool const try_succeeded=rw_mutex.try_lock_upgrade();
|
||||
@@ -216,7 +217,7 @@ void test_if_no_thread_has_lock_try_lock_upgrade_returns_true()
|
||||
}
|
||||
}
|
||||
|
||||
void test_if_other_thread_has_shared_lock_try_lock_shared_returns_true()
|
||||
BOOST_AUTO_TEST_CASE(test_if_other_thread_has_shared_lock_try_lock_shared_returns_true)
|
||||
{
|
||||
|
||||
boost::shared_mutex rw_mutex;
|
||||
@@ -239,7 +240,7 @@ void test_if_other_thread_has_shared_lock_try_lock_shared_returns_true()
|
||||
writer.join();
|
||||
}
|
||||
|
||||
void test_if_other_thread_has_shared_lock_try_lock_upgrade_returns_true()
|
||||
BOOST_AUTO_TEST_CASE(test_if_other_thread_has_shared_lock_try_lock_upgrade_returns_true)
|
||||
{
|
||||
|
||||
boost::shared_mutex rw_mutex;
|
||||
@@ -262,7 +263,7 @@ void test_if_other_thread_has_shared_lock_try_lock_upgrade_returns_true()
|
||||
writer.join();
|
||||
}
|
||||
|
||||
void test_if_other_thread_has_upgrade_lock_try_lock_upgrade_returns_false()
|
||||
BOOST_AUTO_TEST_CASE(test_if_other_thread_has_upgrade_lock_try_lock_upgrade_returns_false)
|
||||
{
|
||||
|
||||
boost::shared_mutex rw_mutex;
|
||||
@@ -285,18 +286,4 @@ void test_if_other_thread_has_upgrade_lock_try_lock_upgrade_returns_false()
|
||||
writer.join();
|
||||
}
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: shared_mutex test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(&test_only_one_upgrade_lock_permitted));
|
||||
test->add(BOOST_TEST_CASE(&test_can_lock_upgrade_if_currently_locked_shared));
|
||||
test->add(BOOST_TEST_CASE(&test_can_lock_upgrade_to_unique_if_currently_locked_upgrade));
|
||||
test->add(BOOST_TEST_CASE(&test_if_other_thread_has_write_lock_try_lock_shared_returns_false));
|
||||
test->add(BOOST_TEST_CASE(&test_if_no_thread_has_lock_try_lock_shared_returns_true));
|
||||
test->add(BOOST_TEST_CASE(&test_if_other_thread_has_shared_lock_try_lock_shared_returns_true));
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define BOOST_THREAD_VERSION 2
|
||||
#define BOOST_TEST_MODULE Boost.Threads: shared_mutex_timed_locks test suite
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
@@ -18,7 +19,7 @@
|
||||
}
|
||||
|
||||
|
||||
void test_timed_lock_shared_times_out_if_write_lock_held()
|
||||
BOOST_AUTO_TEST_CASE(test_timed_lock_shared_times_out_if_write_lock_held)
|
||||
{
|
||||
boost::shared_mutex rw_mutex;
|
||||
boost::mutex finish_mutex;
|
||||
@@ -54,7 +55,7 @@ void test_timed_lock_shared_times_out_if_write_lock_held()
|
||||
writer.join();
|
||||
}
|
||||
|
||||
void test_timed_lock_shared_succeeds_if_no_lock_held()
|
||||
BOOST_AUTO_TEST_CASE(test_timed_lock_shared_succeeds_if_no_lock_held)
|
||||
{
|
||||
boost::shared_mutex rw_mutex;
|
||||
boost::mutex finish_mutex;
|
||||
@@ -83,7 +84,7 @@ void test_timed_lock_shared_succeeds_if_no_lock_held()
|
||||
|
||||
}
|
||||
|
||||
void test_timed_lock_shared_succeeds_if_read_lock_held()
|
||||
BOOST_AUTO_TEST_CASE(test_timed_lock_shared_succeeds_if_read_lock_held)
|
||||
{
|
||||
boost::shared_mutex rw_mutex;
|
||||
boost::mutex finish_mutex;
|
||||
@@ -119,7 +120,7 @@ void test_timed_lock_shared_succeeds_if_read_lock_held()
|
||||
reader.join();
|
||||
}
|
||||
|
||||
void test_timed_lock_times_out_if_write_lock_held()
|
||||
BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_if_write_lock_held)
|
||||
{
|
||||
boost::shared_mutex rw_mutex;
|
||||
boost::mutex finish_mutex;
|
||||
@@ -155,7 +156,7 @@ void test_timed_lock_times_out_if_write_lock_held()
|
||||
writer.join();
|
||||
}
|
||||
|
||||
void test_timed_lock_succeeds_if_no_lock_held()
|
||||
BOOST_AUTO_TEST_CASE(test_timed_lock_succeeds_if_no_lock_held)
|
||||
{
|
||||
boost::shared_mutex rw_mutex;
|
||||
boost::mutex finish_mutex;
|
||||
@@ -184,7 +185,7 @@ void test_timed_lock_succeeds_if_no_lock_held()
|
||||
|
||||
}
|
||||
|
||||
void test_timed_lock_times_out_if_read_lock_held()
|
||||
BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_if_read_lock_held)
|
||||
{
|
||||
boost::shared_mutex rw_mutex;
|
||||
boost::mutex finish_mutex;
|
||||
@@ -220,7 +221,7 @@ void test_timed_lock_times_out_if_read_lock_held()
|
||||
reader.join();
|
||||
}
|
||||
|
||||
void test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held()
|
||||
BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held)
|
||||
{
|
||||
boost::shared_mutex rw_mutex;
|
||||
boost::mutex finish_mutex;
|
||||
@@ -252,21 +253,3 @@ void test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held()
|
||||
reader.join();
|
||||
}
|
||||
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: shared_mutex test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(&test_timed_lock_shared_times_out_if_write_lock_held));
|
||||
test->add(BOOST_TEST_CASE(&test_timed_lock_shared_succeeds_if_no_lock_held));
|
||||
test->add(BOOST_TEST_CASE(&test_timed_lock_shared_succeeds_if_read_lock_held));
|
||||
test->add(BOOST_TEST_CASE(&test_timed_lock_times_out_if_write_lock_held));
|
||||
test->add(BOOST_TEST_CASE(&test_timed_lock_times_out_if_read_lock_held));
|
||||
test->add(BOOST_TEST_CASE(&test_timed_lock_succeeds_if_no_lock_held));
|
||||
test->add(BOOST_TEST_CASE(&test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held));
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define BOOST_THREAD_VERSION 2
|
||||
#define BOOST_TEST_MODULE Boost.Threads: shared_mutex_locks_chrono test suite
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
@@ -20,7 +21,7 @@
|
||||
}
|
||||
|
||||
|
||||
void test_timed_lock_shared_times_out_if_write_lock_held()
|
||||
BOOST_AUTO_TEST_CASE(test_timed_lock_shared_times_out_if_write_lock_held)
|
||||
{
|
||||
boost::shared_mutex rw_mutex;
|
||||
boost::mutex finish_mutex;
|
||||
@@ -56,7 +57,7 @@ void test_timed_lock_shared_times_out_if_write_lock_held()
|
||||
writer.join();
|
||||
}
|
||||
|
||||
void test_timed_lock_shared_succeeds_if_no_lock_held()
|
||||
BOOST_AUTO_TEST_CASE(test_timed_lock_shared_succeeds_if_no_lock_held)
|
||||
{
|
||||
boost::shared_mutex rw_mutex;
|
||||
boost::mutex finish_mutex;
|
||||
@@ -85,7 +86,7 @@ void test_timed_lock_shared_succeeds_if_no_lock_held()
|
||||
|
||||
}
|
||||
|
||||
void test_timed_lock_shared_succeeds_if_read_lock_held()
|
||||
BOOST_AUTO_TEST_CASE(test_timed_lock_shared_succeeds_if_read_lock_held)
|
||||
{
|
||||
boost::shared_mutex rw_mutex;
|
||||
boost::mutex finish_mutex;
|
||||
@@ -121,7 +122,7 @@ void test_timed_lock_shared_succeeds_if_read_lock_held()
|
||||
reader.join();
|
||||
}
|
||||
|
||||
void test_timed_lock_times_out_if_write_lock_held()
|
||||
BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_if_write_lock_held)
|
||||
{
|
||||
boost::shared_mutex rw_mutex;
|
||||
boost::mutex finish_mutex;
|
||||
@@ -157,7 +158,7 @@ void test_timed_lock_times_out_if_write_lock_held()
|
||||
writer.join();
|
||||
}
|
||||
|
||||
void test_timed_lock_succeeds_if_no_lock_held()
|
||||
BOOST_AUTO_TEST_CASE(test_timed_lock_succeeds_if_no_lock_held)
|
||||
{
|
||||
boost::shared_mutex rw_mutex;
|
||||
boost::mutex finish_mutex;
|
||||
@@ -186,7 +187,7 @@ void test_timed_lock_succeeds_if_no_lock_held()
|
||||
|
||||
}
|
||||
|
||||
void test_timed_lock_times_out_if_read_lock_held()
|
||||
BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_if_read_lock_held)
|
||||
{
|
||||
boost::shared_mutex rw_mutex;
|
||||
boost::mutex finish_mutex;
|
||||
@@ -222,7 +223,7 @@ void test_timed_lock_times_out_if_read_lock_held()
|
||||
reader.join();
|
||||
}
|
||||
|
||||
void test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held()
|
||||
BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held)
|
||||
{
|
||||
boost::shared_mutex rw_mutex;
|
||||
boost::mutex finish_mutex;
|
||||
@@ -254,23 +255,6 @@ void test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held()
|
||||
reader.join();
|
||||
}
|
||||
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: shared_mutex test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(&test_timed_lock_shared_times_out_if_write_lock_held));
|
||||
test->add(BOOST_TEST_CASE(&test_timed_lock_shared_succeeds_if_no_lock_held));
|
||||
test->add(BOOST_TEST_CASE(&test_timed_lock_shared_succeeds_if_read_lock_held));
|
||||
test->add(BOOST_TEST_CASE(&test_timed_lock_times_out_if_write_lock_held));
|
||||
test->add(BOOST_TEST_CASE(&test_timed_lock_times_out_if_read_lock_held));
|
||||
test->add(BOOST_TEST_CASE(&test_timed_lock_succeeds_if_no_lock_held));
|
||||
test->add(BOOST_TEST_CASE(&test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held));
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
#else
|
||||
#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
|
||||
#endif
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
#define BOOST_TEST_MODULE Boost.Threads: thread test suite
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_sleep_only
|
||||
@@ -40,7 +42,7 @@ void comparison_thread(boost::thread::id parent)
|
||||
BOOST_CHECK(my_id != no_thread_id);
|
||||
}
|
||||
|
||||
void test_sleep()
|
||||
BOOST_AUTO_TEST_CASE(test_sleep)
|
||||
{
|
||||
boost::xtime xt = delay(3);
|
||||
boost::thread::sleep(xt);
|
||||
@@ -58,7 +60,7 @@ void do_test_creation()
|
||||
BOOST_CHECK_EQUAL(test_value, 999);
|
||||
}
|
||||
|
||||
void test_creation()
|
||||
BOOST_AUTO_TEST_CASE(test_creation)
|
||||
{
|
||||
timed_test(&do_test_creation, 1);
|
||||
}
|
||||
@@ -70,7 +72,7 @@ void do_test_id_comparison()
|
||||
thrd.join();
|
||||
}
|
||||
|
||||
void test_id_comparison()
|
||||
BOOST_AUTO_TEST_CASE(test_id_comparison)
|
||||
{
|
||||
timed_test(&do_test_id_comparison, 1);
|
||||
}
|
||||
@@ -94,7 +96,7 @@ void do_test_thread_interrupts_at_interruption_point()
|
||||
BOOST_CHECK(!failed);
|
||||
}
|
||||
|
||||
void test_thread_interrupts_at_interruption_point()
|
||||
BOOST_AUTO_TEST_CASE(test_thread_interrupts_at_interruption_point)
|
||||
{
|
||||
timed_test(&do_test_thread_interrupts_at_interruption_point, 1);
|
||||
}
|
||||
@@ -119,7 +121,7 @@ void do_test_thread_no_interrupt_if_interrupts_disabled_at_interruption_point()
|
||||
BOOST_CHECK(!failed);
|
||||
}
|
||||
|
||||
void test_thread_no_interrupt_if_interrupts_disabled_at_interruption_point()
|
||||
BOOST_AUTO_TEST_CASE(test_thread_no_interrupt_if_interrupts_disabled_at_interruption_point)
|
||||
{
|
||||
timed_test(&do_test_thread_no_interrupt_if_interrupts_disabled_at_interruption_point, 1);
|
||||
}
|
||||
@@ -148,7 +150,7 @@ void do_test_creation_through_reference_wrapper()
|
||||
BOOST_CHECK_EQUAL(f.value, 999u);
|
||||
}
|
||||
|
||||
void test_creation_through_reference_wrapper()
|
||||
BOOST_AUTO_TEST_CASE(test_creation_through_reference_wrapper)
|
||||
{
|
||||
timed_test(&do_test_creation_through_reference_wrapper, 1);
|
||||
}
|
||||
@@ -197,12 +199,12 @@ void do_test_timed_join()
|
||||
BOOST_CHECK(!thrd.joinable());
|
||||
}
|
||||
|
||||
void test_timed_join()
|
||||
BOOST_AUTO_TEST_CASE(test_timed_join)
|
||||
{
|
||||
timed_test(&do_test_timed_join, 10);
|
||||
}
|
||||
|
||||
void test_swap()
|
||||
BOOST_AUTO_TEST_CASE(test_swap)
|
||||
{
|
||||
boost::thread t(simple_thread);
|
||||
boost::thread t2(simple_thread);
|
||||
@@ -218,21 +220,3 @@ void test_swap()
|
||||
BOOST_CHECK(t2.get_id()==id2);
|
||||
}
|
||||
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: thread test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(test_sleep));
|
||||
test->add(BOOST_TEST_CASE(test_creation));
|
||||
test->add(BOOST_TEST_CASE(test_id_comparison));
|
||||
test->add(BOOST_TEST_CASE(test_thread_interrupts_at_interruption_point));
|
||||
test->add(BOOST_TEST_CASE(test_thread_no_interrupt_if_interrupts_disabled_at_interruption_point));
|
||||
test->add(BOOST_TEST_CASE(test_creation_through_reference_wrapper));
|
||||
test->add(BOOST_TEST_CASE(test_timed_join));
|
||||
test->add(BOOST_TEST_CASE(test_swap));
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#define BOOST_TEST_MODULE Boost.Threads: thread exit test suite
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
boost::thread::id exit_func_thread_id;
|
||||
@@ -27,7 +29,7 @@ void tf1()
|
||||
BOOST_CHECK(exit_func_thread_id!=boost::this_thread::get_id());
|
||||
}
|
||||
|
||||
void test_thread_exit_func_runs_when_thread_exits()
|
||||
BOOST_AUTO_TEST_CASE(test_thread_exit_func_runs_when_thread_exits)
|
||||
{
|
||||
exit_func_thread_id=boost::thread::id();
|
||||
boost::thread t(tf1);
|
||||
@@ -51,7 +53,7 @@ void tf2()
|
||||
}
|
||||
|
||||
|
||||
void test_can_use_function_object_for_exit_func()
|
||||
BOOST_AUTO_TEST_CASE(test_can_use_function_object_for_exit_func)
|
||||
{
|
||||
exit_func_thread_id=boost::thread::id();
|
||||
boost::thread t(tf2);
|
||||
@@ -59,17 +61,3 @@ void test_can_use_function_object_for_exit_func()
|
||||
t.join();
|
||||
BOOST_CHECK(exit_func_thread_id==t_id);
|
||||
}
|
||||
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: futures test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(test_thread_exit_func_runs_when_thread_exits));
|
||||
test->add(BOOST_TEST_CASE(test_can_use_function_object_for_exit_func));
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
//
|
||||
// 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)
|
||||
|
||||
#define BOOST_TEST_MODULE Boost.Threads: thread::get_id test suite
|
||||
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
@@ -9,20 +12,20 @@
|
||||
void do_nothing()
|
||||
{}
|
||||
|
||||
void test_thread_id_for_default_constructed_thread_is_default_constructed_id()
|
||||
BOOST_AUTO_TEST_CASE(test_thread_id_for_default_constructed_thread_is_default_constructed_id)
|
||||
{
|
||||
boost::thread t;
|
||||
BOOST_CHECK(t.get_id()==boost::thread::id());
|
||||
}
|
||||
|
||||
void test_thread_id_for_running_thread_is_not_default_constructed_id()
|
||||
BOOST_AUTO_TEST_CASE(test_thread_id_for_running_thread_is_not_default_constructed_id)
|
||||
{
|
||||
boost::thread t(do_nothing);
|
||||
BOOST_CHECK(t.get_id()!=boost::thread::id());
|
||||
t.join();
|
||||
}
|
||||
|
||||
void test_different_threads_have_different_ids()
|
||||
BOOST_AUTO_TEST_CASE(test_different_threads_have_different_ids)
|
||||
{
|
||||
boost::thread t(do_nothing);
|
||||
boost::thread t2(do_nothing);
|
||||
@@ -31,7 +34,7 @@ void test_different_threads_have_different_ids()
|
||||
t2.join();
|
||||
}
|
||||
|
||||
void test_thread_ids_have_a_total_order()
|
||||
BOOST_AUTO_TEST_CASE(test_thread_ids_have_a_total_order)
|
||||
{
|
||||
boost::thread t(do_nothing);
|
||||
boost::thread t2(do_nothing);
|
||||
@@ -126,7 +129,7 @@ void get_thread_id(boost::thread::id* id)
|
||||
*id=boost::this_thread::get_id();
|
||||
}
|
||||
|
||||
void test_thread_id_of_running_thread_returned_by_this_thread_get_id()
|
||||
BOOST_AUTO_TEST_CASE(test_thread_id_of_running_thread_returned_by_this_thread_get_id)
|
||||
{
|
||||
boost::thread::id id;
|
||||
boost::thread t(boost::bind(get_thread_id,&id));
|
||||
@@ -134,18 +137,3 @@ void test_thread_id_of_running_thread_returned_by_this_thread_get_id()
|
||||
t.join();
|
||||
BOOST_CHECK(id==t_id);
|
||||
}
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: thread move test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(test_thread_id_for_default_constructed_thread_is_default_constructed_id));
|
||||
test->add(BOOST_TEST_CASE(test_thread_id_for_running_thread_is_not_default_constructed_id));
|
||||
test->add(BOOST_TEST_CASE(test_different_threads_have_different_ids));
|
||||
test->add(BOOST_TEST_CASE(test_thread_ids_have_a_total_order));
|
||||
test->add(BOOST_TEST_CASE(test_thread_id_of_running_thread_returned_by_this_thread_get_id));
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define BOOST_THREAD_VERSION 3
|
||||
#define BOOST_TEST_MODULE Boost.Threads: thread launching test suite
|
||||
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
@@ -19,7 +20,7 @@ void normal_function()
|
||||
normal_function_called=true;
|
||||
}
|
||||
|
||||
void test_thread_function_no_arguments()
|
||||
BOOST_AUTO_TEST_CASE(test_thread_function_no_arguments)
|
||||
{
|
||||
boost::thread function(normal_function);
|
||||
function.join();
|
||||
@@ -33,7 +34,7 @@ void normal_function_one_arg(int i)
|
||||
nfoa_res=i;
|
||||
}
|
||||
|
||||
void test_thread_function_one_argument()
|
||||
BOOST_AUTO_TEST_CASE(test_thread_function_one_argument)
|
||||
{
|
||||
boost::thread function(normal_function_one_arg,42);
|
||||
function.join();
|
||||
@@ -52,7 +53,7 @@ struct callable_no_args
|
||||
|
||||
bool callable_no_args::called=false;
|
||||
|
||||
void test_thread_callable_object_no_arguments()
|
||||
BOOST_AUTO_TEST_CASE(test_thread_callable_object_no_arguments)
|
||||
{
|
||||
callable_no_args func;
|
||||
boost::thread callable(func);
|
||||
@@ -74,7 +75,7 @@ struct callable_noncopyable_no_args:
|
||||
|
||||
bool callable_noncopyable_no_args::called=false;
|
||||
|
||||
void test_thread_callable_object_ref_no_arguments()
|
||||
BOOST_AUTO_TEST_CASE(test_thread_callable_object_ref_no_arguments)
|
||||
{
|
||||
callable_noncopyable_no_args func;
|
||||
|
||||
@@ -98,7 +99,7 @@ struct callable_one_arg
|
||||
bool callable_one_arg::called=false;
|
||||
int callable_one_arg::called_arg=0;
|
||||
|
||||
void test_thread_callable_object_one_argument()
|
||||
BOOST_AUTO_TEST_CASE(test_thread_callable_object_one_argument)
|
||||
{
|
||||
callable_one_arg func;
|
||||
boost::thread callable(func,42);
|
||||
@@ -140,7 +141,7 @@ std::string callable_multiple_arg::called_three_arg1;
|
||||
std::vector<int> callable_multiple_arg::called_three_arg2;
|
||||
int callable_multiple_arg::called_three_arg3;
|
||||
|
||||
void test_thread_callable_object_multiple_arguments()
|
||||
BOOST_AUTO_TEST_CASE(test_thread_callable_object_multiple_arguments)
|
||||
{
|
||||
std::vector<int> x;
|
||||
for(unsigned i=0;i<7;++i)
|
||||
@@ -196,7 +197,7 @@ struct X
|
||||
|
||||
};
|
||||
|
||||
void test_thread_member_function_no_arguments()
|
||||
BOOST_AUTO_TEST_CASE(test_thread_member_function_no_arguments)
|
||||
{
|
||||
X x;
|
||||
|
||||
@@ -206,29 +207,10 @@ void test_thread_member_function_no_arguments()
|
||||
}
|
||||
|
||||
|
||||
void test_thread_member_function_one_argument()
|
||||
BOOST_AUTO_TEST_CASE(test_thread_member_function_one_argument)
|
||||
{
|
||||
X x;
|
||||
boost::thread function(&X::f1,&x,42);
|
||||
function.join();
|
||||
BOOST_CHECK_EQUAL(42,x.arg_value);
|
||||
}
|
||||
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: thread launching test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(test_thread_function_no_arguments));
|
||||
test->add(BOOST_TEST_CASE(test_thread_function_one_argument));
|
||||
test->add(BOOST_TEST_CASE(test_thread_callable_object_no_arguments));
|
||||
test->add(BOOST_TEST_CASE(test_thread_callable_object_ref_no_arguments));
|
||||
test->add(BOOST_TEST_CASE(test_thread_callable_object_one_argument));
|
||||
test->add(BOOST_TEST_CASE(test_thread_callable_object_multiple_arguments));
|
||||
test->add(BOOST_TEST_CASE(test_thread_member_function_no_arguments));
|
||||
test->add(BOOST_TEST_CASE(test_thread_member_function_one_argument));
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
//
|
||||
// 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)
|
||||
|
||||
#define BOOST_TEST_MODULE Boost.Threads: thread move test suite
|
||||
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -10,7 +13,7 @@ void do_nothing(boost::thread::id* my_id)
|
||||
*my_id=boost::this_thread::get_id();
|
||||
}
|
||||
|
||||
void test_move_on_construction()
|
||||
BOOST_AUTO_TEST_CASE(test_move_on_construction)
|
||||
{
|
||||
boost::thread::id the_id;
|
||||
boost::thread x=boost::thread(do_nothing,&the_id);
|
||||
@@ -24,7 +27,7 @@ boost::thread make_thread(boost::thread::id* the_id)
|
||||
return boost::thread(do_nothing,the_id);
|
||||
}
|
||||
|
||||
void test_move_from_function_return()
|
||||
BOOST_AUTO_TEST_CASE(test_move_from_function_return)
|
||||
{
|
||||
boost::thread::id the_id;
|
||||
boost::thread x=make_thread(&the_id);
|
||||
@@ -33,7 +36,7 @@ void test_move_from_function_return()
|
||||
BOOST_CHECK_EQUAL(the_id,x_id);
|
||||
}
|
||||
|
||||
void test_move_assign()
|
||||
BOOST_AUTO_TEST_CASE(test_move_assign)
|
||||
{
|
||||
boost::thread::id the_id;
|
||||
boost::thread x(do_nothing,&the_id);
|
||||
@@ -44,15 +47,4 @@ void test_move_assign()
|
||||
BOOST_CHECK_EQUAL(the_id,y_id);
|
||||
}
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: thread move test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(test_move_on_construction));
|
||||
test->add(BOOST_TEST_CASE(test_move_from_function_return));
|
||||
test->add(BOOST_TEST_CASE(test_move_assign));
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define BOOST_THREAD_USES_MOVE
|
||||
#define BOOST_TEST_MODULE Boost.Threads: thread move return test suite
|
||||
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
@@ -19,7 +20,7 @@ boost::thread make_thread_move_return(boost::thread::id* the_id)
|
||||
return boost::move(t);
|
||||
}
|
||||
|
||||
void test_move_from_function_move_return()
|
||||
BOOST_AUTO_TEST_CASE(test_move_from_function_move_return)
|
||||
{
|
||||
boost::thread::id the_id;
|
||||
boost::thread x=make_thread_move_return(&the_id);
|
||||
@@ -28,13 +29,3 @@ void test_move_from_function_move_return()
|
||||
BOOST_CHECK_EQUAL(the_id,x_id);
|
||||
}
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: thread move test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(test_move_from_function_move_return));
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#define BOOST_THREAD_USES_MOVE
|
||||
|
||||
#define BOOST_TEST_MODULE Boost.Threads: thread return local test suite
|
||||
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -19,7 +21,7 @@ boost::thread make_thread_return_local(boost::thread::id* the_id)
|
||||
return boost::move(t);
|
||||
}
|
||||
|
||||
void test_move_from_function_return_local()
|
||||
BOOST_AUTO_TEST_CASE(test_move_from_function_return_local)
|
||||
{
|
||||
boost::thread::id the_id;
|
||||
boost::thread x=make_thread_return_local(&the_id);
|
||||
@@ -27,14 +29,3 @@ void test_move_from_function_return_local()
|
||||
x.join();
|
||||
BOOST_CHECK_EQUAL(the_id,x_id);
|
||||
}
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: thread move test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(test_move_from_function_return_local));
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#define BOOST_THREAD_VERSION 2
|
||||
#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
#define BOOST_TEST_MODULE Boost.Threads: tss test suite
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/predef/platform.h>
|
||||
@@ -73,7 +74,7 @@ void test_tss_thread()
|
||||
#if BOOST_PLAT_WINDOWS_RUNTIME
|
||||
typedef std::shared_ptr<std::thread> native_thread_t;
|
||||
|
||||
void test_tss_thread_native()
|
||||
BOOST_AUTO_TEST_CASE(test_tss_thread_native)
|
||||
{
|
||||
test_tss_thread();
|
||||
}
|
||||
@@ -208,7 +209,7 @@ void do_test_tss()
|
||||
BOOST_CHECK_EQUAL(tss_total, 5);
|
||||
}
|
||||
|
||||
void test_tss()
|
||||
BOOST_AUTO_TEST_CASE(test_tss)
|
||||
{
|
||||
timed_test(&do_test_tss, 2);
|
||||
}
|
||||
@@ -224,6 +225,7 @@ void tss_void_custom_cleanup(void* d)
|
||||
}
|
||||
|
||||
boost::thread_specific_ptr<void> tss_void(tss_void_custom_cleanup);
|
||||
|
||||
void test_tss_void_thread()
|
||||
{
|
||||
tss_void.reset(new tss_value_t());
|
||||
@@ -300,10 +302,10 @@ void do_test_tss_void()
|
||||
// BOOST_CHECK_EQUAL(tss_total, 5);
|
||||
}
|
||||
|
||||
void test_tss_void()
|
||||
{
|
||||
timed_test(&do_test_tss_void, 2);
|
||||
}
|
||||
//BOOST_AUTO_TEST_CASE(test_tss_void)
|
||||
//{
|
||||
// timed_test(&do_test_tss_void, 2);
|
||||
//}
|
||||
|
||||
|
||||
boost::thread_specific_ptr<void> tss_void_with_cleanup(tss_void_custom_cleanup);
|
||||
@@ -331,7 +333,7 @@ void do_test_tss_void_with_custom_cleanup()
|
||||
}
|
||||
|
||||
|
||||
void test_tss_void_with_custom_cleanup()
|
||||
BOOST_AUTO_TEST_CASE(test_tss_void_with_custom_cleanup)
|
||||
{
|
||||
timed_test(&do_test_tss_void_with_custom_cleanup, 2);
|
||||
}
|
||||
@@ -373,7 +375,7 @@ void do_test_tss_with_custom_cleanup()
|
||||
}
|
||||
|
||||
|
||||
void test_tss_with_custom_cleanup()
|
||||
BOOST_AUTO_TEST_CASE(test_tss_with_custom_cleanup)
|
||||
{
|
||||
timed_test(&do_test_tss_with_custom_cleanup, 2);
|
||||
}
|
||||
@@ -450,12 +452,12 @@ void do_test_tss_does_no_cleanup_with_null_cleanup_function()
|
||||
}
|
||||
}
|
||||
|
||||
void test_tss_does_no_cleanup_after_release()
|
||||
BOOST_AUTO_TEST_CASE(test_tss_does_no_cleanup_after_release)
|
||||
{
|
||||
timed_test(&do_test_tss_does_no_cleanup_after_release, 2);
|
||||
}
|
||||
|
||||
void test_tss_does_no_cleanup_with_null_cleanup_function()
|
||||
BOOST_AUTO_TEST_CASE(test_tss_does_no_cleanup_with_null_cleanup_function)
|
||||
{
|
||||
timed_test(&do_test_tss_does_no_cleanup_with_null_cleanup_function, 2);
|
||||
}
|
||||
@@ -472,14 +474,14 @@ void thread_with_local_tss_ptr()
|
||||
}
|
||||
|
||||
|
||||
void test_tss_does_not_call_cleanup_after_ptr_destroyed()
|
||||
BOOST_AUTO_TEST_CASE(test_tss_does_not_call_cleanup_after_ptr_destroyed)
|
||||
{
|
||||
boost::thread t(thread_with_local_tss_ptr);
|
||||
t.join();
|
||||
BOOST_CHECK(!tss_cleanup_called);
|
||||
}
|
||||
|
||||
void test_tss_cleanup_not_called_for_null_pointer()
|
||||
BOOST_AUTO_TEST_CASE(test_tss_cleanup_not_called_for_null_pointer)
|
||||
{
|
||||
boost::thread_specific_ptr<Dummy> local_tss(tss_custom_cleanup);
|
||||
local_tss.reset(new Dummy);
|
||||
@@ -491,34 +493,16 @@ void test_tss_cleanup_not_called_for_null_pointer()
|
||||
BOOST_CHECK(!tss_cleanup_called);
|
||||
}
|
||||
|
||||
void test_tss_at_the_same_adress()
|
||||
{
|
||||
for(int i=0; i<2; i++)
|
||||
{
|
||||
boost::thread_specific_ptr<Dummy> local_tss(tss_custom_cleanup);
|
||||
local_tss.reset(new Dummy);
|
||||
tss_cleanup_called=false;
|
||||
BOOST_CHECK(tss_cleanup_called);
|
||||
tss_cleanup_called=false;
|
||||
BOOST_CHECK(!tss_cleanup_called);
|
||||
}
|
||||
}
|
||||
//BOOST_AUTO_TEST_CASE(test_tss_at_the_same_adress)
|
||||
//{
|
||||
// for(int i=0; i<2; i++)
|
||||
// {
|
||||
// boost::thread_specific_ptr<Dummy> local_tss(tss_custom_cleanup);
|
||||
// local_tss.reset(new Dummy);
|
||||
// tss_cleanup_called=false;
|
||||
// BOOST_CHECK(tss_cleanup_called);
|
||||
// tss_cleanup_called=false;
|
||||
// BOOST_CHECK(!tss_cleanup_called);
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
boost::unit_test::test_suite* test =
|
||||
BOOST_TEST_SUITE("Boost.Threads: tss test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(test_tss));
|
||||
test->add(BOOST_TEST_CASE(test_tss_with_custom_cleanup));
|
||||
test->add(BOOST_TEST_CASE(test_tss_does_no_cleanup_after_release));
|
||||
test->add(BOOST_TEST_CASE(test_tss_does_no_cleanup_with_null_cleanup_function));
|
||||
test->add(BOOST_TEST_CASE(test_tss_does_not_call_cleanup_after_ptr_destroyed));
|
||||
test->add(BOOST_TEST_CASE(test_tss_cleanup_not_called_for_null_pointer));
|
||||
//test->add(BOOST_TEST_CASE(test_tss_void));
|
||||
test->add(BOOST_TEST_CASE(test_tss_void_with_custom_cleanup));
|
||||
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user