mirror of
https://github.com/boostorg/thread.git
synced 2026-02-09 11:32:12 +00:00
Compare commits
162 Commits
boost-1.37
...
sandbox-br
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a848fee059 | ||
|
|
effd891a16 | ||
|
|
13db35cbf5 | ||
|
|
0f2d480e3c | ||
|
|
9edc61e37b | ||
|
|
f4dab6aac5 | ||
|
|
9e0550d140 | ||
|
|
0d1701c509 | ||
|
|
f2f62f93ea | ||
|
|
8a329f66fb | ||
|
|
05d4c52918 | ||
|
|
8fd0dd0cc0 | ||
|
|
8eea5811ba | ||
|
|
a154c2adab | ||
|
|
10bf4ed576 | ||
|
|
60d12dd395 | ||
|
|
b4e9be3c52 | ||
|
|
dcebae6d4a | ||
|
|
0d776bcd26 | ||
|
|
2d6ed47cf2 | ||
|
|
ea06434425 | ||
|
|
6508eff95e | ||
|
|
69930684a9 | ||
|
|
b1931a3eda | ||
|
|
63b44d4e32 | ||
|
|
f7cb8d8141 | ||
|
|
48c857e02c | ||
|
|
442dc58e0f | ||
|
|
25460c652c | ||
|
|
31a98f0a1e | ||
|
|
36c44b6f45 | ||
|
|
27426b18d1 | ||
|
|
3ea9ce1c8c | ||
|
|
4dfc636c84 | ||
|
|
5fe4312c6c | ||
|
|
63e675a6bb | ||
|
|
e92aeac7d7 | ||
|
|
f1f7eac1f2 | ||
|
|
eff0c84553 | ||
|
|
58c8ce61c7 | ||
|
|
6ac5e6953a | ||
|
|
5d9ad59af2 | ||
|
|
3c48a05437 | ||
|
|
4462124ff2 | ||
|
|
373f557ef7 | ||
|
|
495e561398 | ||
|
|
d24a579033 | ||
|
|
77130424b4 | ||
|
|
eb30688937 | ||
|
|
880bac0633 | ||
|
|
851d6a987f | ||
|
|
9bebd7b35f | ||
|
|
309acb9597 | ||
|
|
a56887167e | ||
|
|
e984dff4e4 | ||
|
|
685e4d446b | ||
|
|
8af680f307 | ||
|
|
6c60cce60d | ||
|
|
5882a675bb | ||
|
|
a5e95845b3 | ||
|
|
5b83d81e40 | ||
|
|
c8e5ad564d | ||
|
|
5edfa273ff | ||
|
|
4db57bcb10 | ||
|
|
3f13340903 | ||
|
|
6abb53c9d3 | ||
|
|
fdd20a519e | ||
|
|
67cc49f333 | ||
|
|
31a34cd0b5 | ||
|
|
ef8c08ba99 | ||
|
|
2991ca6c6f | ||
|
|
52bace18b2 | ||
|
|
767d14ae4f | ||
|
|
1a5c911e36 | ||
|
|
6e42a04e43 | ||
|
|
28be2cfeef | ||
|
|
8be168fd87 | ||
|
|
eee95fef57 | ||
|
|
9ea179b052 | ||
|
|
6868280409 | ||
|
|
e00b764454 | ||
|
|
999613c686 | ||
|
|
c2661d7eb5 | ||
|
|
4d21dd1f47 | ||
|
|
a0a0e57527 | ||
|
|
d8af0d0b4e | ||
|
|
113288e3b0 | ||
|
|
afecfd7c2d | ||
|
|
94d89aac5f | ||
|
|
8831b13efc | ||
|
|
01f99da03a | ||
|
|
080654e3ef | ||
|
|
2ac2eb2a61 | ||
|
|
61b940b705 | ||
|
|
4a4f87e017 | ||
|
|
6d5e7f63a7 | ||
|
|
f77285f375 | ||
|
|
dc5d03a6dc | ||
|
|
ea0961b7f6 | ||
|
|
33d9f9774c | ||
|
|
86097fa038 | ||
|
|
70d9dbc45a | ||
|
|
3926fd3a20 | ||
|
|
7861cf1146 | ||
|
|
0516b86a6e | ||
|
|
ec735d3e9b | ||
|
|
1c5c070983 | ||
|
|
a5c02b73dc | ||
|
|
918b920670 | ||
|
|
de67d2e27e | ||
|
|
bc89df04cb | ||
|
|
c26a4cf082 | ||
|
|
6e1a866b13 | ||
|
|
f91986ad0d | ||
|
|
795cc23f3e | ||
|
|
a3695bd4a0 | ||
|
|
08dc521daf | ||
|
|
8b916d21b1 | ||
|
|
c40f47a78a | ||
|
|
e9fb470b06 | ||
|
|
343d049772 | ||
|
|
86f9480da4 | ||
|
|
8696b610ca | ||
|
|
6f13227eda | ||
|
|
58d5110e61 | ||
|
|
76e53c7bc5 | ||
|
|
cfb08be1a8 | ||
|
|
b5bbb7fb1c | ||
|
|
a76c33f8cc | ||
|
|
810306b8f3 | ||
|
|
6c22bdb3bd | ||
|
|
6a0d3e98bc | ||
|
|
3809321037 | ||
|
|
eef695bdf0 | ||
|
|
ab01ab1e4d | ||
|
|
c8d8a108a7 | ||
|
|
7afd9efcc5 | ||
|
|
56ded87ad2 | ||
|
|
82e503339b | ||
|
|
713d0c7ace | ||
|
|
25ad6e3f8f | ||
|
|
df0197b617 | ||
|
|
a89c4f01ad | ||
|
|
ae67099633 | ||
|
|
57542d3a5c | ||
|
|
9a1da14116 | ||
|
|
ed050d753d | ||
|
|
8bec363710 | ||
|
|
7c68e190a9 | ||
|
|
7ebf5ea3d1 | ||
|
|
11e0435a4b | ||
|
|
d15ee57cd1 | ||
|
|
56d660b7fd | ||
|
|
792958e693 | ||
|
|
914e67dc04 | ||
|
|
b50a7ccb61 | ||
|
|
f827709d42 | ||
|
|
36abb42175 | ||
|
|
40f3b1b4c8 | ||
|
|
4f35e25688 | ||
|
|
270e88edd7 | ||
|
|
5ded171247 |
22
CMakeLists.txt
Normal file
22
CMakeLists.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# This file was automatically generated from the original CMakeLists.txt file
|
||||
# Add a variable to hold the headers for the library
|
||||
set (lib_headers
|
||||
thread.hpp
|
||||
thread
|
||||
)
|
||||
|
||||
# Add a library target to the build system
|
||||
boost_library_project(
|
||||
thread
|
||||
SRCDIRS src
|
||||
TESTDIRS test
|
||||
HEADERS ${lib_headers}
|
||||
# DOCDIRS
|
||||
# DESCRIPTION
|
||||
MODULARIZED
|
||||
# AUTHORS
|
||||
# MAINTAINERS
|
||||
)
|
||||
|
||||
|
||||
@@ -31,25 +31,6 @@ boostbook standalone
|
||||
# Use the main Boost stylesheet:
|
||||
<xsl:param>html.stylesheet=../../../../doc/html/boostbook.css
|
||||
|
||||
# PDF Options:
|
||||
# TOC Generation: this is needed for FOP-0.9 and later:
|
||||
#<xsl:param>fop1.extensions=1
|
||||
# Or enable this if you're using XEP:
|
||||
<xsl:param>xep.extensions=1
|
||||
# TOC generation: this is needed for FOP 0.2, but must not be set to zero for FOP-0.9!
|
||||
<xsl:param>fop.extensions=0
|
||||
# No indent on body text:
|
||||
<xsl:param>body.start.indent=0pt
|
||||
# Margin size:
|
||||
<xsl:param>page.margin.inner=0.5in
|
||||
# Margin size:
|
||||
<xsl:param>page.margin.outer=0.5in
|
||||
# Yes, we want graphics for admonishments:
|
||||
<xsl:param>admon.graphics=1
|
||||
# Set this one for PDF generation *only*:
|
||||
# default pnd graphics are awful in PDF form,
|
||||
# better use SVG's instead:
|
||||
<format>pdf:<xsl:param>admon.graphics.extension=".svg"
|
||||
<format>pdf:<xsl:param>admon.graphics.path=$(boost-images)/
|
||||
;
|
||||
|
||||
|
||||
|
||||
@@ -50,8 +50,9 @@ boost::mutex io_mutex;
|
||||
|
||||
void sender() {
|
||||
int n = 0;
|
||||
while (n < 100) {
|
||||
while (n < 1000000) {
|
||||
buf.send(n);
|
||||
if(!(n%10000))
|
||||
{
|
||||
boost::mutex::scoped_lock io_lock(io_mutex);
|
||||
std::cout << "sent: " << n << std::endl;
|
||||
@@ -65,18 +66,24 @@ void receiver() {
|
||||
int n;
|
||||
do {
|
||||
n = buf.receive();
|
||||
if(!(n%10000))
|
||||
{
|
||||
boost::mutex::scoped_lock io_lock(io_mutex);
|
||||
std::cout << "received: " << n << std::endl;
|
||||
}
|
||||
} while (n != -1); // -1 indicates end of buffer
|
||||
buf.send(-1);
|
||||
}
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
boost::thread thrd1(&sender);
|
||||
boost::thread thrd2(&receiver);
|
||||
boost::thread thrd3(&receiver);
|
||||
boost::thread thrd4(&receiver);
|
||||
thrd1.join();
|
||||
thrd2.join();
|
||||
thrd3.join();
|
||||
thrd4.join();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ int main(int argc, char* argv[])
|
||||
std::cout << "---Noise ON..." << std::endl;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1000000; ++i)
|
||||
for (int i = 0; i < 1000000000; ++i)
|
||||
cond.notify_all();
|
||||
|
||||
{
|
||||
|
||||
1
module.cmake
Normal file
1
module.cmake
Normal file
@@ -0,0 +1 @@
|
||||
boost_module(thread DEPENDS date_time bind optional range)
|
||||
15
src/CMakeLists.txt
Normal file
15
src/CMakeLists.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
if (WIN32)
|
||||
set(THREAD_SOURCES win32/thread.cpp win32/exceptions.cpp win32/tss_dll.cpp
|
||||
win32/tss_pe.cpp)
|
||||
else (WIN32)
|
||||
set(THREAD_SOURCES pthread/thread.cpp pthread/exceptions.cpp pthread/once.cpp)
|
||||
endif (WIN32)
|
||||
|
||||
boost_add_library(
|
||||
boost_thread
|
||||
${THREAD_SOURCES}
|
||||
SHARED_COMPILE_FLAGS "-DBOOST_THREAD_BUILD_DLL=1"
|
||||
STATIC_COMPILE_FLAGS "-DBOOST_THREAD_BUILD_LIB=1"
|
||||
NO_SINGLE_THREADED
|
||||
)
|
||||
|
||||
@@ -132,10 +132,12 @@ namespace boost
|
||||
catch(thread_interrupted const&)
|
||||
{
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::terminate();
|
||||
}
|
||||
// Removed as it stops the debugger identifying the cause of the exception
|
||||
// Unhandled exceptions still cause the application to terminate
|
||||
// catch(...)
|
||||
// {
|
||||
// std::terminate();
|
||||
// }
|
||||
|
||||
detail::tls_destructor(thread_info.get());
|
||||
detail::set_current_thread_data(0);
|
||||
|
||||
@@ -169,10 +169,12 @@ namespace boost
|
||||
catch(thread_interrupted const&)
|
||||
{
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::terminate();
|
||||
}
|
||||
// Removed as it stops the debugger identifying the cause of the exception
|
||||
// Unhandled exceptions still cause the application to terminate
|
||||
// catch(...)
|
||||
// {
|
||||
// std::terminate();
|
||||
// }
|
||||
run_thread_exit_callbacks();
|
||||
return 0;
|
||||
}
|
||||
|
||||
33
test/CMakeLists.txt
Normal file
33
test/CMakeLists.txt
Normal file
@@ -0,0 +1,33 @@
|
||||
boost_additional_test_dependencies(thread BOOST_DEPENDS test )
|
||||
|
||||
|
||||
|
||||
set(TESTS
|
||||
test_thread
|
||||
test_thread_id
|
||||
test_hardware_concurrency
|
||||
test_thread_move
|
||||
test_thread_launching
|
||||
test_thread_mf
|
||||
test_move_function
|
||||
test_mutex
|
||||
test_condition_notify_one
|
||||
test_condition_timed_wait_times_out
|
||||
test_condition_notify_all
|
||||
test_condition
|
||||
test_tss
|
||||
test_once
|
||||
test_xtime
|
||||
test_barrier
|
||||
test_shared_mutex
|
||||
test_shared_mutex_part_2
|
||||
test_shared_mutex_timed_locks
|
||||
test_lock_concept
|
||||
test_generic_locks)
|
||||
|
||||
foreach (TEST ${TESTS})
|
||||
boost_test_run(${TEST} MULTI_THREADED DEPENDS boost_thread boost_unit_test_framework)
|
||||
endforeach (TEST ${TESTS})
|
||||
|
||||
boost_test_compile_fail(no_implicit_move_from_lvalue_thread)
|
||||
boost_test_compile_fail(no_implicit_assign_from_lvalue_thread)
|
||||
366
test/util.inl
366
test/util.inl
@@ -1,183 +1,183 @@
|
||||
// Copyright (C) 2001-2003
|
||||
// William E. Kempf
|
||||
// Copyright (C) 2007-8 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)
|
||||
|
||||
#if !defined(UTIL_INL_WEK01242003)
|
||||
#define UTIL_INL_WEK01242003
|
||||
|
||||
#include <boost/thread/xtime.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/condition.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
#ifndef DEFAULT_EXECUTION_MONITOR_TYPE
|
||||
# define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_condition
|
||||
#endif
|
||||
|
||||
// boostinspect:nounnamed
|
||||
|
||||
namespace
|
||||
{
|
||||
inline boost::xtime delay(int secs, int msecs=0, int nsecs=0)
|
||||
{
|
||||
const int MILLISECONDS_PER_SECOND = 1000;
|
||||
const int NANOSECONDS_PER_SECOND = 1000000000;
|
||||
const int NANOSECONDS_PER_MILLISECOND = 1000000;
|
||||
|
||||
boost::xtime xt;
|
||||
if (boost::TIME_UTC != boost::xtime_get (&xt, boost::TIME_UTC))
|
||||
BOOST_ERROR ("boost::xtime_get != boost::TIME_UTC");
|
||||
|
||||
nsecs += xt.nsec;
|
||||
msecs += nsecs / NANOSECONDS_PER_MILLISECOND;
|
||||
secs += msecs / MILLISECONDS_PER_SECOND;
|
||||
nsecs += (msecs % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
|
||||
xt.nsec = nsecs % NANOSECONDS_PER_SECOND;
|
||||
xt.sec += secs + (nsecs / NANOSECONDS_PER_SECOND);
|
||||
|
||||
return xt;
|
||||
}
|
||||
|
||||
inline bool in_range(const boost::xtime& xt, int secs=1)
|
||||
{
|
||||
boost::xtime min = delay(-secs);
|
||||
boost::xtime max = delay(0);
|
||||
return (boost::xtime_cmp(xt, min) >= 0) &&
|
||||
(boost::xtime_cmp(xt, max) <= 0);
|
||||
}
|
||||
|
||||
class execution_monitor
|
||||
{
|
||||
public:
|
||||
enum wait_type { use_sleep_only, use_mutex, use_condition };
|
||||
|
||||
execution_monitor(wait_type type, int secs)
|
||||
: done(false), type(type), secs(secs) { }
|
||||
void start()
|
||||
{
|
||||
if (type != use_sleep_only) {
|
||||
boost::mutex::scoped_lock lock(mutex); done = false;
|
||||
} else {
|
||||
done = false;
|
||||
}
|
||||
}
|
||||
void finish()
|
||||
{
|
||||
if (type != use_sleep_only) {
|
||||
boost::mutex::scoped_lock lock(mutex);
|
||||
done = true;
|
||||
if (type == use_condition)
|
||||
cond.notify_one();
|
||||
} else {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
bool wait()
|
||||
{
|
||||
boost::xtime xt = delay(secs);
|
||||
if (type != use_condition)
|
||||
boost::thread::sleep(xt);
|
||||
if (type != use_sleep_only) {
|
||||
boost::mutex::scoped_lock lock(mutex);
|
||||
while (type == use_condition && !done) {
|
||||
if (!cond.timed_wait(lock, xt))
|
||||
break;
|
||||
}
|
||||
return done;
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
||||
private:
|
||||
boost::mutex mutex;
|
||||
boost::condition cond;
|
||||
bool done;
|
||||
wait_type type;
|
||||
int secs;
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
class indirect_adapter
|
||||
{
|
||||
public:
|
||||
indirect_adapter(F func, execution_monitor& monitor)
|
||||
: func(func), monitor(monitor) { }
|
||||
void operator()() const
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::thread thrd(func);
|
||||
thrd.join();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
monitor.finish();
|
||||
throw;
|
||||
}
|
||||
monitor.finish();
|
||||
}
|
||||
|
||||
private:
|
||||
F func;
|
||||
execution_monitor& monitor;
|
||||
void operator=(indirect_adapter&);
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
void timed_test(F func, int secs,
|
||||
execution_monitor::wait_type type=DEFAULT_EXECUTION_MONITOR_TYPE)
|
||||
{
|
||||
execution_monitor monitor(type, secs);
|
||||
indirect_adapter<F> ifunc(func, monitor);
|
||||
monitor.start();
|
||||
boost::thread thrd(ifunc);
|
||||
BOOST_REQUIRE_MESSAGE(monitor.wait(),
|
||||
"Timed test didn't complete in time, possible deadlock.");
|
||||
}
|
||||
|
||||
template <typename F, typename T>
|
||||
class thread_binder
|
||||
{
|
||||
public:
|
||||
thread_binder(const F& func, const T& param)
|
||||
: func(func), param(param) { }
|
||||
void operator()() const { func(param); }
|
||||
|
||||
private:
|
||||
F func;
|
||||
T param;
|
||||
};
|
||||
|
||||
template <typename F, typename T>
|
||||
thread_binder<F, T> bind(const F& func, const T& param)
|
||||
{
|
||||
return thread_binder<F, T>(func, param);
|
||||
}
|
||||
|
||||
template <typename R, typename T>
|
||||
class thread_member_binder
|
||||
{
|
||||
public:
|
||||
thread_member_binder(R (T::*func)(), T& param)
|
||||
: func(func), param(param) { }
|
||||
void operator()() const { (param.*func)(); }
|
||||
|
||||
private:
|
||||
void operator=(thread_member_binder&);
|
||||
|
||||
R (T::*func)();
|
||||
T& param;
|
||||
};
|
||||
|
||||
|
||||
template <typename R, typename T>
|
||||
thread_member_binder<R, T> bind(R (T::*func)(), T& param)
|
||||
{
|
||||
return thread_member_binder<R, T>(func, param);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
// Copyright (C) 2001-2003
|
||||
// William E. Kempf
|
||||
// Copyright (C) 2007-8 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)
|
||||
|
||||
#if !defined(UTIL_INL_WEK01242003)
|
||||
#define UTIL_INL_WEK01242003
|
||||
|
||||
#include <boost/thread/xtime.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/condition.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
#ifndef DEFAULT_EXECUTION_MONITOR_TYPE
|
||||
# define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_condition
|
||||
#endif
|
||||
|
||||
// boostinspect:nounnamed
|
||||
|
||||
namespace
|
||||
{
|
||||
inline boost::xtime delay(int secs, int msecs=0, int nsecs=0)
|
||||
{
|
||||
const int MILLISECONDS_PER_SECOND = 1000;
|
||||
const int NANOSECONDS_PER_SECOND = 1000000000;
|
||||
const int NANOSECONDS_PER_MILLISECOND = 1000000;
|
||||
|
||||
boost::xtime xt;
|
||||
if (boost::TIME_UTC != boost::xtime_get (&xt, boost::TIME_UTC))
|
||||
BOOST_ERROR ("boost::xtime_get != boost::TIME_UTC");
|
||||
|
||||
nsecs += xt.nsec;
|
||||
msecs += nsecs / NANOSECONDS_PER_MILLISECOND;
|
||||
secs += msecs / MILLISECONDS_PER_SECOND;
|
||||
nsecs += (msecs % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
|
||||
xt.nsec = nsecs % NANOSECONDS_PER_SECOND;
|
||||
xt.sec += secs + (nsecs / NANOSECONDS_PER_SECOND);
|
||||
|
||||
return xt;
|
||||
}
|
||||
|
||||
inline bool in_range(const boost::xtime& xt, int secs=1)
|
||||
{
|
||||
boost::xtime min = delay(-secs);
|
||||
boost::xtime max = delay(0);
|
||||
return (boost::xtime_cmp(xt, min) >= 0) &&
|
||||
(boost::xtime_cmp(xt, max) <= 0);
|
||||
}
|
||||
|
||||
class execution_monitor
|
||||
{
|
||||
public:
|
||||
enum wait_type { use_sleep_only, use_mutex, use_condition };
|
||||
|
||||
execution_monitor(wait_type type, int secs)
|
||||
: done(false), type(type), secs(secs) { }
|
||||
void start()
|
||||
{
|
||||
if (type != use_sleep_only) {
|
||||
boost::mutex::scoped_lock lock(mutex); done = false;
|
||||
} else {
|
||||
done = false;
|
||||
}
|
||||
}
|
||||
void finish()
|
||||
{
|
||||
if (type != use_sleep_only) {
|
||||
boost::mutex::scoped_lock lock(mutex);
|
||||
done = true;
|
||||
if (type == use_condition)
|
||||
cond.notify_one();
|
||||
} else {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
bool wait()
|
||||
{
|
||||
boost::xtime xt = delay(secs);
|
||||
if (type != use_condition)
|
||||
boost::thread::sleep(xt);
|
||||
if (type != use_sleep_only) {
|
||||
boost::mutex::scoped_lock lock(mutex);
|
||||
while (type == use_condition && !done) {
|
||||
if (!cond.timed_wait(lock, xt))
|
||||
break;
|
||||
}
|
||||
return done;
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
||||
private:
|
||||
boost::mutex mutex;
|
||||
boost::condition cond;
|
||||
bool done;
|
||||
wait_type type;
|
||||
int secs;
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
class indirect_adapter
|
||||
{
|
||||
public:
|
||||
indirect_adapter(F func, execution_monitor& monitor)
|
||||
: func(func), monitor(monitor) { }
|
||||
void operator()() const
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::thread thrd(func);
|
||||
thrd.join();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
monitor.finish();
|
||||
throw;
|
||||
}
|
||||
monitor.finish();
|
||||
}
|
||||
|
||||
private:
|
||||
F func;
|
||||
execution_monitor& monitor;
|
||||
void operator=(indirect_adapter&);
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
void timed_test(F func, int secs,
|
||||
execution_monitor::wait_type type=DEFAULT_EXECUTION_MONITOR_TYPE)
|
||||
{
|
||||
execution_monitor monitor(type, secs);
|
||||
indirect_adapter<F> ifunc(func, monitor);
|
||||
monitor.start();
|
||||
boost::thread thrd(ifunc);
|
||||
BOOST_REQUIRE_MESSAGE(monitor.wait(),
|
||||
"Timed test didn't complete in time, possible deadlock.");
|
||||
}
|
||||
|
||||
template <typename F, typename T>
|
||||
class thread_binder
|
||||
{
|
||||
public:
|
||||
thread_binder(const F& func, const T& param)
|
||||
: func(func), param(param) { }
|
||||
void operator()() const { func(param); }
|
||||
|
||||
private:
|
||||
F func;
|
||||
T param;
|
||||
};
|
||||
|
||||
template <typename F, typename T>
|
||||
thread_binder<F, T> bind(const F& func, const T& param)
|
||||
{
|
||||
return thread_binder<F, T>(func, param);
|
||||
}
|
||||
|
||||
template <typename R, typename T>
|
||||
class thread_member_binder
|
||||
{
|
||||
public:
|
||||
thread_member_binder(R (T::*func)(), T& param)
|
||||
: func(func), param(param) { }
|
||||
void operator()() const { (param.*func)(); }
|
||||
|
||||
private:
|
||||
void operator=(thread_member_binder&);
|
||||
|
||||
R (T::*func)();
|
||||
T& param;
|
||||
};
|
||||
|
||||
|
||||
template <typename R, typename T>
|
||||
thread_member_binder<R, T> bind(R (T::*func)(), T& param)
|
||||
{
|
||||
return thread_member_binder<R, T>(func, param);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user