diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2019-04-08 18:31:42 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2019-04-11 12:21:19 +0200 |
commit | e09bf8260e17e9ab8c4524c3b3d5d617d8d89bd5 (patch) | |
tree | 02049debf4b33b6fbc984a0e7072857b90004f18 /comphelper | |
parent | 3d3826dae92a8bd4671717d92f497db57f6424d1 (diff) |
don't kill threads after 3 minutes while debugging
It makes sense to kill threads after 3 minutes in dbgutils mode for unittests,
but this also meant that e.g. threaded Calc calculations in a gdb session
or when ran in Valgrind sometimes asserted halfway through the calculation.
Change-Id: I4fdd82549909feda9d4461b64eba0fcdca8be9be
Reviewed-on: https://gerrit.libreoffice.org/70422
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'comphelper')
-rw-r--r-- | comphelper/source/misc/threadpool.cxx | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/comphelper/source/misc/threadpool.cxx b/comphelper/source/misc/threadpool.cxx index 89d80298432b..f075c0600968 100644 --- a/comphelper/source/misc/threadpool.cxx +++ b/comphelper/source/misc/threadpool.cxx @@ -20,6 +20,18 @@ #include <thread> #include <chrono> +#if defined HAVE_VALGRIND_HEADERS +#include <valgrind/memcheck.h> +#endif + +#if defined(_WIN32) +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#elif defined UNX +#include <unistd.h> +#include <fcntl.h> +#endif + namespace comphelper { /** prevent waiting for a task from inside a task */ @@ -304,15 +316,54 @@ bool ThreadTaskTag::isDone() return mnTasksWorking == 0; } +#if defined DBG_UTIL && !defined NDEBUG +static bool isDebuggerAttached() +{ +#if defined(_WIN32) + return IsDebuggerPresent(); +#elif defined LINUX + char buf[ 4096 ]; + int fd = open( "/proc/self/status", O_RDONLY ); + if( fd < 0 ) + return false; + int size = read( fd, buf, sizeof( buf ) - 1 ); + close( fd ); + if( size < 0 ) + return false; + assert( size < int( sizeof( buf )) - 1 ); + buf[ sizeof( buf ) - 1 ] = '\0'; + // "TracerPid: <pid>" for pid != 0 means something is attached + const char* pos = strstr( buf, "TracerPid:" ); + if( pos == nullptr ) + return false; + pos += strlen( "TracerPid:" ); + while( *pos != '\n' && isspace( *pos )) + ++pos; + return *pos != '\n' && *pos != '0'; +#else + return false; // feel free to add your platform +#endif +} +#endif + void ThreadTaskTag::waitUntilDone() { std::unique_lock< std::mutex > aGuard( maMutex ); while( mnTasksWorking > 0 ) { #if defined DBG_UTIL && !defined NDEBUG - // 3 minute timeout in debug mode so our tests fail sooner rather than later + // 3 minute timeout in debug mode so our tests fail sooner rather than later, + // unless the code is debugged in valgrind or gdb, in which case the threads + // should not time out in the middle of a debugging session + int maxTimeout = 3 * 60; +#if defined HAVE_VALGRIND_HEADERS + if( RUNNING_ON_VALGRIND ) + maxTimeout = 30 * 60; +#endif + if( isDebuggerAttached()) + maxTimeout = 300 * 60; std::cv_status result = maTasksComplete.wait_for( - aGuard, std::chrono::seconds( 3 * 60 )); + aGuard, std::chrono::seconds( maxTimeout )); assert(result != std::cv_status::timeout); #else // 10 minute timeout in production so the app eventually throws some kind of error |