[Libreoffice-commits] core.git: comphelper/source

Luboš Luňák (via logerrit) logerrit at kemper.freedesktop.org
Thu Apr 11 10:21:44 UTC 2019


 comphelper/source/misc/threadpool.cxx |   55 ++++++++++++++++++++++++++++++++--
 1 file changed, 53 insertions(+), 2 deletions(-)

New commits:
commit e09bf8260e17e9ab8c4524c3b3d5d617d8d89bd5
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Mon Apr 8 18:31:42 2019 +0200
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Thu Apr 11 12:21:19 2019 +0200

    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 at collabora.com>

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


More information about the Libreoffice-commits mailing list