Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Solved Do cross-thread slot invocations prolong sender's lifetime?

    General and Desktop
    5
    12
    232
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • I
      Igor Baidiuk last edited by

      Hello!

      Let's imagine we have 2 objects in 2 distinct threads. Object 2's slot is connected to Object 1's signal. Signal is emitted, and Object 2's slot is called. Then, someone invokes object1->deleteLater() in the middle of slot invocation. Will slot's sender() become dangling pointer? Or will slot prolong sender's life until it's finished? If the former, how would one guard against such case?

      Please note objects belong to independent event loops.

      I found topic https://forum.qt.io/topic/243/cross-thread-signals-disconnect-and-destructors but it discusses only about disconnection and not about mid-flight sender's deletion.

      Thanks,
      Igor

      jsulm kshegunov 2 Replies Last reply Reply Quote 0
      • jsulm
        jsulm Lifetime Qt Champion @Igor Baidiuk last edited by

        @Igor-Baidiuk Not direct answer: you should avoid using sender() anyway. With C++11 lambdas there is usually no need to use sender() and using sender() you invent tight coupling which is not good from architecture point of view.

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply Reply Quote 0
        • I
          Igor Baidiuk last edited by

          @jsulm Thanks but that's not the case. I have exactly 2 objects, one of them depends on the state of the other.
          To be more precise, they're two tree-like data structures. One presents data of certain hierarchical 3D model, other is the respective scene graph. They live in separate threads because of QML's rendering. I need scene nodes be notified of model nodes' changes directly, signal being the easiest way. Like when some assembly gets one of its children removed, or leaf body changes its geometry etc.

          JonB 1 Reply Last reply Reply Quote 0
          • JonB
            JonB @Igor Baidiuk last edited by

            @Igor-Baidiuk
            But that does not mean you have to use sender(). As @jsulm said, you can preferably use a lambda parameter instead.

            1 Reply Last reply Reply Quote 0
            • I
              Igor Baidiuk last edited by

              I still don't get what does lambda have with this. If I even add sender's address to lambda's capture list, it'll end just like sender().

              jsulm 1 Reply Last reply Reply Quote 0
              • jsulm
                jsulm Lifetime Qt Champion @Igor Baidiuk last edited by

                @Igor-Baidiuk Can you explain why you need sender() at all?
                Why does the slot need to know anything about signal emitter? What do you do with sender object in the slot?

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply Reply Quote 0
                • I
                  Igor Baidiuk last edited by

                  void onGeometryChanged() {
                      auto mesh = static_cast<Mesh*>(sender());
                      auto vBuffer = createVertexBuffer(mesh->vertices());
                      // (1) someone deletes sender in another thread
                      auto idxBuffer = createTrianglesBuffer(mesh->triangles()); // <-- kaboom due to (1)?
                      ...
                  }
                  
                  1 Reply Last reply Reply Quote 0
                  • Christian Ehrlicher
                    Christian Ehrlicher Lifetime Qt Champion last edited by

                    Then pass the mesh pointer to onGeometryChanged() slot as already said two times. Take a look at the new signal/slot syntax wiki page when you don't how to use a lambda for this.

                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                    Visit the Qt Academy at https://academy.qt.io/catalog

                    1 Reply Last reply Reply Quote 1
                    • I
                      Igor Baidiuk last edited by Igor Baidiuk

                      With all due respect, I asked specific question. And I know about new signal/slot binding. I know I can create proxy lambda. But, again, this was not my question. If you know answer, I'd appreciate if you share it. If you don't, why consistently telling me where's the fridge if I'm looking for bicycle?

                      EDIT: BTW connecting lambda does not allow tying its lifetime to receiver since there's no receiver. So if real receiver referenced in lambda gets deleted, hello segfault. Even if I use QPointer, it'll result in resource leak.

                      1 Reply Last reply Reply Quote 0
                      • Christian Ehrlicher
                        Christian Ehrlicher Lifetime Qt Champion last edited by

                        @Igor-Baidiuk said in Do cross-thread slot invocations prolong sender's lifetime?:

                        If you know answer, I'd appreciate if you share it.

                        We already told you the answer. Pass the pointer via lambda to your slot similar as explained in the wiki:

                        QString newValue = "blub";
                        connect(
                            sender, &Sender::valueChanged,
                            [=]( const QString &newValue ) { receiver->updateValue( "senderValue", newValue ); }
                        );
                        

                        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                        Visit the Qt Academy at https://academy.qt.io/catalog

                        1 Reply Last reply Reply Quote -1
                        • kshegunov
                          kshegunov Moderators @Igor Baidiuk last edited by

                          @Igor-Baidiuk said in Do cross-thread slot invocations prolong sender's lifetime?:

                          Will slot's sender() become dangling pointer?

                          It may. Taking the sender() of a queued invocation is UB.

                          Or will slot prolong sender's life until it's finished?

                          It will not.

                          If the former, how would one guard against such case?

                          You yourself must guarantee that the object is alive until that time; usual MT considerations apply. Best advice - define clear lifetimes of your objects. If you need said object at some point to be alive, then make sure nobody is deleting it in the meantime. Furthermore operating on an object in a different thread without serialization is a race. You can keep a QPointer to some QObject if you need an non-owning signaled pointer.

                          Read and abide by the Qt Code of Conduct

                          1 Reply Last reply Reply Quote 5
                          • I
                            Igor Baidiuk last edited by

                            @kshegunov

                            It may. Taking the sender() of a queued invocation is UB.

                            It will not.

                            Thank you very much. This fully answers my question.

                            1 Reply Last reply Reply Quote 0
                            • First post
                              Last post