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, 6.5.0
    • D-Bus
    • None
    • 13
    • c4d598b35 (dev)
    • Foundation PM Staging, Foundation Sprint 85, Foundation Sprint 86, Foundation Sprint 87, Foundation Sprint 88, Foundation Sprint 89, Foundation Sprint 90, Foundation Sprint 91, Foundation Sprint 92, Foundation Sprint 93, Foundations Sprint 94, Foundations Sprint 95, Foundations Sprint 96

    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

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

        Activity

          People

            cnn Qt Core & Network
            dvratil Daniel Vrátil
            Vladimir Minenko Vladimir Minenko
            Alex Blasche Alex Blasche
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes