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

QDBusAbstractInterface::asyncCall() not really async when service runs in the same process

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 5.15.2
    • D-Bus
    • None

    Description

      When using QDBusAbstractInterface::asyncCall() to call a method on a service that is registered in a different thread of the same process, the call is not truly asynchronous and blocks instead until the remote method returns. The call is asynchronous (returns immediately) if the remote service is running in another process.

       

      This is counter-intuitive, since the name of the method - asyncCall() - suggests the call is performed asynchronously, but the implementation instead decides to do QDBusConnectionPrivate::sendWithReplyLocal if the DBus service runs in another thread of the same process.

       

      If the thread that runs the remote service is currently blocked, or the remote method takes time to respond, this will block the caller thread, which is unexpected when using asyncCall().

       

      Either this optimization should not be used when doing asyncCall(), or the behavior should be documented.

       

      Attached is a minimal reproducer.

       

      Thread 2 (Thread 0x7ffff4bee640 (LWP 890021) "dbustest"):
      
      #0  0x00007ffff7577a81 in clock_nanosleep@GLIBC_2.2.5 () from /usr/lib64/libc.so.6
      #1  0x00007ffff757cfa7 in nanosleep () from /usr/lib64/libc.so.6
      #2  0x00000000002090f0 in std::this_thread::sleep_for<long, std::ratio<1l, 1l> > (__rtime=...) at /usr/lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/thread:401
      #3  0x0000000000207ffb in Server::blockingPing (this=0x7ffff4bedcb8, seconds=1) at /home/dvratil/qtbug/main.cpp:40
      #4  0x0000000000206f4f in Server::qt_static_metacall (_o=0x7ffff4bedcb8, _c=QMetaObject::InvokeMetaMethod, _id=0, _a=0x7ffff4bed660) at dbustest_autogen/include/main.moc:72
      #5  0x000000000020710d in Server::qt_metacall (this=0x7ffff4bedcb8, _c=QMetaObject::InvokeMetaMethod, _id=0, _a=0x7ffff4bed660) at dbustest_autogen/include/main.moc:109
      #6  0x00007ffff7f62fd9 in QDBusConnectionPrivate::deliverCall (this=<optimized out>, object=<optimized out>, msg=..., metaTypes=..., slotIdx=<optimized out>) at ../../include/QtCore/../../src/corelib/tools/qvarlengtharray.h:201
      #7  0x00007ffff7f66504 in QDBusConnectionPrivate::activateCall (this=this@entry=0x7fffe8003c00, object=<optimized out>, flags=272, msg=...) at qdbusintegrator.cpp:904
      #8  0x00007ffff7f66c84 in QDBusConnectionPrivate::activateCall (msg=..., flags=<optimized out>, object=<optimized out>, this=0x7fffe8003c00) at qdbusintegrator.cpp:853
      #9  QDBusConnectionPrivate::activateObject (this=0x7fffe8003c00, node=..., msg=..., pathStartPos=<optimized out>) at qdbusintegrator.cpp:1521
      #10 0x00007ffff7f6920c in QDBusActivateObjectEvent::placeMetaCall (this=0x231d20) at qdbusintegrator.cpp:1617
      #11 0x00007ffff7c6ed1e in QObject::event (this=0x7ffff4bedcb8, e=0x231d20) at kernel/qobject.cpp:1314
      #12 0x00007ffff7c46bad in doNotify (event=0x231d20, receiver=0x7ffff4bedcb8) at kernel/qcoreapplication.cpp:1153
      #13 QCoreApplication::notify (event=<optimized out>, receiver=<optimized out>, this=<optimized out>) at kernel/qcoreapplication.cpp:1139
      #14 QCoreApplication::notifyInternal2 (receiver=0x7ffff4bedcb8, event=0x231d20) at kernel/qcoreapplication.cpp:1063
      #15 0x00007ffff7c498c7 in QCoreApplicationPrivate::sendPostedEvents (receiver=0x0, event_type=0, data=0x7ffff0000bc0) at kernel/qcoreapplication.cpp:1817
      #16 0x00007ffff7c93c27 in postEventSourceDispatch (s=0x7ffff0003410) at kernel/qeventdispatcher_glib.cpp:277
      #17 0x00007ffff6d1ea9f in g_main_context_dispatch () from /usr/lib64/libglib-2.0.so.0
      #18 0x00007ffff6d70a98 in g_main_context_iterate.constprop () from /usr/lib64/libglib-2.0.so.0
      #19 0x00007ffff6d1be73 in g_main_context_iteration () from /usr/lib64/libglib-2.0.so.0
      #20 0x00007ffff7c936f3 in QEventDispatcherGlib::processEvents (this=0x7ffff0003b00, flags=...) at kernel/qeventdispatcher_glib.cpp:423
      #21 0x00007ffff7c4557b in QEventLoop::exec (this=0x7ffff4bedc40, flags=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:69
      #22 0x000000000020b302 in Server::run (this=0x7ffff4bedcb8) at /home/dvratil/qtbug/main.cpp:34
      #23 0x00000000002076c5 in main::$_3::operator() (this=0x22f718) at /home/dvratil/qtbug/main.cpp:83
      #24 0x000000000020768d in std::__invoke_impl<void, main::$_3> (__f=...) at /usr/lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/bits/invoke.h:60
      #25 0x000000000020761d in std::__invoke<main::$_3> (__fn=...) at /usr/lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/bits/invoke.h:95
      #26 0x00000000002075f5 in std::thread::_Invoker<std::tuple<main::$_3> >::_M_invoke<0ul> (this=0x22f718) at /usr/lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/thread:264
      #27 0x00000000002075c5 in std::thread::_Invoker<std::tuple<main::$_3> >::operator() (this=0x22f718) at /usr/lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/thread:271
      #28 0x000000000020753e in std::thread::_State_impl<std::thread::_Invoker<std::tuple<main::$_3> > >::_M_run (this=0x22f710) at /usr/lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/thread:215
      #29 0x00007ffff78b35f4 in std::execute_native_thread_routine (__p=0x22f710) at ../../../../../libstdc++-v3/src/c++11/thread.cc:80
      #30 0x00007ffff7f233f9 in start_thread () from /usr/lib64/libpthread.so.0
      #31 0x00007ffff75b0b53 in clone () from /usr/lib64/libc.so.6
      
      
      #0  0x00007ffff75ab55d in syscall () from /usr/lib64/libc.so.6
      #1  0x00007ffff7aadd51 in QtLinuxFutex::_q_futex (val3=0, addr2=0x0, val2=0, val=<optimized out>, op=0, addr=<optimized out>) at thread/qfutex_p.h:116
      #2  QtLinuxFutex::futexWait<QBasicAtomicInteger<unsigned int> > (expectedValue=<optimized out>, futex=...) at thread/qfutex_p.h:135
      #3  futexSemaphoreTryAcquire_loop<false> (timeout=-1, nn=8589934593, curValue=<optimized out>, u=...) at thread/qsemaphore.cpp:219
      #4  futexSemaphoreTryAcquire<false> (timeout=-1, n=1, u=...) at thread/qsemaphore.cpp:262
      #5  QSemaphore::acquire (this=this@entry=0x7fffffffbe70, n=n@entry=1) at thread/qsemaphore.cpp:326
      #6  0x00007ffff7f67333 in QDBusConnectionPrivate::handleObjectCall (this=this@entry=0x7fffe8003c00, msg=...) at qdbusintegrator.cpp:1594
      #7  0x00007ffff7f67772 in QDBusConnectionPrivate::handleMessage (this=this@entry=0x7fffe8003c00, amsg=...) at qdbusintegrator.cpp:579
      #8  0x00007ffff7f6846b in QDBusConnectionPrivate::handleMessage (amsg=..., this=0x7fffe8003c00) at qdbusintegrator.cpp:2125
      #9  QDBusConnectionPrivate::sendWithReplyLocal (this=this@entry=0x7fffe8003c00, message=...) at qdbusintegrator.cpp:2099
      #10 0x00007ffff7f68be6 in QDBusConnectionPrivate::sendWithReplyAsync (this=0x7fffe8003c00, message=..., receiver=receiver@entry=0x0, returnMethod=returnMethod@entry=0x0, errorMethod=errorMethod@entry=0x0, timeout=-1) at qdbusintegrator.cpp:2135
      #11 0x00007ffff7f5841a in QDBusConnection::asyncCall (this=this@entry=0x22db98, message=..., timeout=<optimized out>) at qdbusconnection.cpp:711
      #12 0x00007ffff7f72d55 in QDBusAbstractInterface::asyncCallWithArgumentList (this=0x7fffffffc2b8, this@entry=0x7fffffffc4f0, method="blockingPing", args=QList<QVariant> = {...}) at qdbusabstractinterface.cpp:527
      #13 0x00007ffff7f7474b in QDBusAbstractInterface::doAsyncCall (this=0x7fffffffc4f0, method="blockingPing", args=<optimized out>, numArgs=1) at qdbusabstractinterface.cpp:930
      #14 0x0000000000209681 in QDBusAbstractInterface::asyncCall<int> (this=0x7fffffffc4f0, method="blockingPing", args=@0x7fffffffc494: 1) at /usr/include/qt5/QtDBus/qdbusabstractinterface.h:169
      #15 0x0000000000208251 in Client::sendPing (this=0x7fffffffcb58) at /home/dvratil/qtbug/main.cpp:59
      #16 0x0000000000208cf4 in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (Client::*)()>::call(void (Client::*)(), Client*, void**) (f=(void (Client::*)(Client * const)) 0x208130 <Client::sendPing()>, o=0x7fffffffcb58, arg=0x7fffffffc730) at /usr/include/qt5/QtCore/qobjectdefs_impl.h:152
      #17 0x0000000000208c58 in QtPrivate::FunctionPointer<void (Client::*)()>::call<QtPrivate::List<>, void>(void (Client::*)(), Client*, void**) (f=(void (Client::*)(Client * const)) 0x208130 <Client::sendPing()>, o=0x7fffffffcb58, arg=0x7fffffffc730) at /usr/include/qt5/QtCore/qobjectdefs_impl.h:185
      #18 0x0000000000208b45 in QtPrivate::QSlotObject<void (Client::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (which=1, this_=0x22f8e0, r=0x7fffffffcb58, a=0x7fffffffc730, ret=0x0) at /usr/include/qt5/QtCore/qobjectdefs_impl.h:418
      #19 0x00007ffff7c76386 in QtPrivate::QSlotObjectBase::call (a=0x7fffffffc730, r=0x7fffffffcb58, this=0x22f8e0) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:398
      #20 doActivate<false> (sender=0x7fffffffcb68, signal_index=3, argv=argv@entry=0x7fffffffc730) at kernel/qobject.cpp:3886
      #21 0x00007ffff7c709a8 in QMetaObject::activate (sender=<optimized out>, m=m@entry=0x7ffff7f0c560 <QTimer::staticMetaObject>, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7fffffffc730) at kernel/qobject.cpp:3946
      #22 0x00007ffff7c7a1fe in QTimer::timeout (this=<optimized out>, _t1=...) at .moc/moc_qtimer.cpp:205
      #23 0x00007ffff7c6ec7f in QObject::event (this=0x7fffffffcb68, e=0x7fffffffc850) at kernel/qobject.cpp:1336
      #24 0x00007ffff7c46bad in doNotify (event=0x7fffffffc850, receiver=0x7fffffffcb68) at kernel/qcoreapplication.cpp:1153
      #25 QCoreApplication::notify (event=<optimized out>, receiver=<optimized out>, this=<optimized out>) at kernel/qcoreapplication.cpp:1139
      #26 QCoreApplication::notifyInternal2 (receiver=0x7fffffffcb68, event=0x7fffffffc850) at kernel/qcoreapplication.cpp:1063
      #27 0x00007ffff7c92a03 in QTimerInfoList::activateTimers (this=0x22f620) at kernel/qtimerinfo_unix.cpp:643
      #28 0x00007ffff7c93344 in timerSourceDispatch (source=<optimized out>) at kernel/qeventdispatcher_glib.cpp:183
      #29 idleTimerSourceDispatch (source=<optimized out>) at kernel/qeventdispatcher_glib.cpp:230
      #30 0x00007ffff6d1ea9f in g_main_context_dispatch () from /usr/lib64/libglib-2.0.so.0
      #31 0x00007ffff6d70a98 in g_main_context_iterate.constprop () from /usr/lib64/libglib-2.0.so.0
      #32 0x00007ffff6d1be73 in g_main_context_iteration () from /usr/lib64/libglib-2.0.so.0
      #33 0x00007ffff7c936f3 in QEventDispatcherGlib::processEvents (this=0x22c840, flags=...) at kernel/qeventdispatcher_glib.cpp:423
      #34 0x00007ffff7c4557b in QEventLoop::exec (this=this@entry=0x7fffffffca90, flags=..., flags@entry=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:69
      #35 0x00007ffff7c4d1b4 in QCoreApplication::exec () at ../../include/QtCore/../../src/corelib/global/qflags.h:121
      #36 0x0000000000206d29 in main (argc=1, argv=0x7fffffffccc8) at /home/dvratil/qtbug/main.cpp:95
      

       

       

      Attachments

        Activity

          People

            Unassigned Unassigned
            dvratil Daniel Vrátil
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated: