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

QDBusPendingReply::waitForFinished() can block 25 seconds (the default dbus timeout) even if the reply arrived immediately

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: Not Evaluated Not Evaluated
    • None
    • 4.7.3
    • D-Bus
    • None
    • Windows

      This can and does happen in the following scenario:
      1. QDBusPendingReply::waitForFinished() is called from a different thread than the one on which the QDBusConnection lives (the one on which QDBusConnection::connectToBus was called)
      2. The thread calling QDBusPendingReply::waitForFinished() acquires QDBusDispatchLocker locker(PendingCallBlockAction, this); but it does not yet reach the select in _dbus_poll
      3. A signal is received on the connection
      4. QDBusConnectionPrivate::socketRead is called since data is available on the connection's thread which, in turn calls q_dbus_watch_handle which consumes the data from the connection (including the received response for which the other thread will be waiting shortly)
      5. The thread calling select (through q_dbus_pending_call_block) will hang for the whole timeout even though the data has arrived after calling q_dbus_pending_call_block

      I've managed to reproduce this by continuously making calls with QDBusPendingReply::waitForFinished() from a thread while also handling a signal from the bus on a different thread.

      This seems like the same issue as this one which was fixed for a different code path in dbus http://cgit.freedesktop.org/dbus/dbus/diff/?id=da4182fb2976608bea64d676677681fdf2cd910b

      If you think that this is a bug it dbus let me know, then I'll open the bug there but I could fix this with the attached patch which acquires the dispatch lock before calling q_dbus_watch_handle. It's a quick fix by copying the contents of QDBusConnectionPrivate::doDispatch() in QDBusConnectionPrivate::socketRead(int fd) so I only recommend it as a fix that proves that the problem lies in dispatching trough q_dbus_watch_handle without locking the dispatch lock.

        1. qt.patch.timeout.do.dispatch.diff
          0.8 kB
          Cristian Oneț
        2. QTBUG-34698.zip
          3 kB
          Cristian Oneț
        3. stack_traces.txt
          5 kB
          Cristian Oneț
        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

            thiago Thiago Macieira
            cristian.onet Cristian Oneț
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved:

                There are no open Gerrit changes