LoopForever and ThreadTrace helpers
This commit is contained in:
parent
1b43bf0d3a
commit
72f14d26ec
|
@ -323,4 +323,62 @@ BOOST_AUTO_TEST_CASE(util_seed_insecure_rand)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nCounter = 0;
|
||||||
|
|
||||||
|
static void Count()
|
||||||
|
{
|
||||||
|
++nCounter;
|
||||||
|
MilliSleep(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CountWithArg(int arg)
|
||||||
|
{
|
||||||
|
nCounter += arg;
|
||||||
|
MilliSleep(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(util_loop_forever1)
|
||||||
|
{
|
||||||
|
boost::thread_group threadGroup;
|
||||||
|
|
||||||
|
threadGroup.create_thread(boost::bind(&LoopForever<void (*)()>, "count", &Count, 1));
|
||||||
|
MilliSleep(1);
|
||||||
|
threadGroup.interrupt_all();
|
||||||
|
BOOST_CHECK_EQUAL(nCounter, 1);
|
||||||
|
nCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(util_loop_forever2)
|
||||||
|
{
|
||||||
|
boost::thread_group threadGroup;
|
||||||
|
|
||||||
|
boost::function<void()> f = boost::bind(&CountWithArg, 11);
|
||||||
|
threadGroup.create_thread(boost::bind(&LoopForever<boost::function<void()> >, "count11", f, 11));
|
||||||
|
MilliSleep(1);
|
||||||
|
threadGroup.interrupt_all();
|
||||||
|
BOOST_CHECK_EQUAL(nCounter, 11);
|
||||||
|
nCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(util_threadtrace1)
|
||||||
|
{
|
||||||
|
boost::thread_group threadGroup;
|
||||||
|
|
||||||
|
threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "count11", &Count));
|
||||||
|
threadGroup.join_all();
|
||||||
|
BOOST_CHECK_EQUAL(nCounter, 1);
|
||||||
|
nCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(util_threadtrace2)
|
||||||
|
{
|
||||||
|
boost::thread_group threadGroup;
|
||||||
|
|
||||||
|
boost::function<void()> f = boost::bind(&CountWithArg, 11);
|
||||||
|
threadGroup.create_thread(boost::bind(&TraceThread<boost::function<void()> >, "count11", f));
|
||||||
|
threadGroup.join_all();
|
||||||
|
BOOST_CHECK_EQUAL(nCounter, 11);
|
||||||
|
nCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
56
src/util.h
56
src/util.h
|
@ -527,4 +527,60 @@ inline uint32_t ByteReverse(uint32_t value)
|
||||||
return (value<<16) | (value>>16);
|
return (value<<16) | (value>>16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Standard wrapper for do-something-forever thread functions.
|
||||||
|
// "Forever" really means until the thread is interrupted.
|
||||||
|
// Use it like:
|
||||||
|
// new boost::thread(boost::bind(&LoopForever<void (*)()>, "dumpaddr", &DumpAddresses, 10000));
|
||||||
|
// or maybe:
|
||||||
|
// boost::function<void()> f = boost::bind(&FunctionWithArg, argument);
|
||||||
|
// threadGroup.create_thread(boost::bind(&LoopForever<boost::function<void()> >, "nothing", f, milliseconds));
|
||||||
|
template <typename Callable> void LoopForever(const char* name, Callable func, int64 msecs)
|
||||||
|
{
|
||||||
|
std::string s = strprintf("bitcoin-%s", name);
|
||||||
|
RenameThread(s.c_str());
|
||||||
|
printf("%s thread start\n", name);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
func();
|
||||||
|
MilliSleep(msecs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (boost::thread_interrupted)
|
||||||
|
{
|
||||||
|
printf("%s thread stop\n", name);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (std::exception& e) {
|
||||||
|
PrintException(&e, name);
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
PrintException(NULL, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// .. and a wrapper that just calls func once
|
||||||
|
template <typename Callable> void TraceThread(const char* name, Callable func)
|
||||||
|
{
|
||||||
|
std::string s = strprintf("bitcoin-%s", name);
|
||||||
|
RenameThread(s.c_str());
|
||||||
|
try
|
||||||
|
{
|
||||||
|
printf("%s thread start\n", name);
|
||||||
|
func();
|
||||||
|
printf("%s thread exit\n", name);
|
||||||
|
}
|
||||||
|
catch (boost::thread_interrupted)
|
||||||
|
{
|
||||||
|
printf("%s thread interrupt\n", name);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (std::exception& e) {
|
||||||
|
PrintException(&e, name);
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
PrintException(NULL, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue