summaryrefslogtreecommitdiff
path: root/comphelper
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2019-04-08 18:31:42 +0200
committerLuboš Luňák <l.lunak@collabora.com>2019-04-11 12:21:19 +0200
commite09bf8260e17e9ab8c4524c3b3d5d617d8d89bd5 (patch)
tree02049debf4b33b6fbc984a0e7072857b90004f18 /comphelper
parent3d3826dae92a8bd4671717d92f497db57f6424d1 (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.cxx55
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