Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-22301

qt_safe_select is not safe on systems without a monotonic clock

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Not Evaluated
    • Resolution: Done
    • Affects Version/s: 4.7.4
    • Fix Version/s: None
    • Component/s: Core: Other
    • Labels:
      None
    • Environment:
      OS without realtime monotonic clock (solaris 9, hpux < 11.3 etc)
    • Commits:
      c64d602df3712c0d147b7b689d29f79c700e63bc 4afde6f85050cc3e9267947999dc55918b1bd36c

      Description

      We had problems on some systems with QProcess building kdelibs the build stopped with:
      qdbuscpp2xml: exit code 0 from moc. Aborting
      QProcess: Destroyed while process is still running.

      Investigation revealed that the problem occured with the parent process getting the SIGCLD in waitForFinished, if the SIGCLD happened earlier then QProcess worked as expected. waitForFinished waits using qt_safe_select with a timeout value. When the parent gets a SIGCLD, qt_safe_select attempts to update the timeout value, if the update fails, or the system lacks a monotonic clock, it returns 0 to fake a timeout. This means on systems without a monotonic clock qt_safe_select always returns 0 on EINTR.

      This patch means that qt_safe_select can wait longer than the original timeout value, but QProcess now works.

      Index: src/corelib/kernel/qcore_unix.cpp
      ===================================================================
      --- src/corelib/kernel/qcore_unix.cpp.orig      2011-09-12 06:49:29.000000000 +0000
      +++ src/corelib/kernel/qcore_unix.cpp   2011-10-24 15:25:55.581128176 +0000
      @@ -94,7 +94,11 @@
                   return ret;
       
               // recalculate the timeout
      -        if (!time_update(&timeout, start, *orig_timeout)) {
      +        // Do not recalculate the timeout if we do not have a
      +        // monotonic clock, because then the function is no longer
      +        // safe, it will return 0 for EINTR.
      +        // On those systems, use the original timeout again.
      +        if (QElapsedTimer::isMonotonic() && !time_update(&timeout, start, *orig_timeout)) {
                   // timeout during update
                   // or clock reset, fake timeout error
                   return 0;
      

        Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

            Assignee:
            thiago Thiago Macieira
            Reporter:
            bugs-qt@vendor.thewrittenword.com The Written Word
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:

                Gerrit Reviews

                There are no open Gerrit changes