Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Do cross-thread slot invocations prolong sender's lifetime?
Forum Updated to NodeBB v4.3 + New Features

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

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 5 Posters 831 Views 1 Watching
  • 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 Offline
    I Offline
    Igor Baidiuk
    wrote on last edited by
    #1

    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

    jsulmJ kshegunovK 2 Replies Last reply
    0
    • I Igor Baidiuk

      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

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @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
      0
      • I Offline
        I Offline
        Igor Baidiuk
        wrote on last edited by
        #3

        @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.

        JonBJ 1 Reply Last reply
        0
        • I Igor Baidiuk

          @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.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @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
          0
          • I Offline
            I Offline
            Igor Baidiuk
            wrote on last edited by
            #5

            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().

            jsulmJ 1 Reply Last reply
            0
            • I Igor Baidiuk

              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().

              jsulmJ Offline
              jsulmJ Offline
              jsulm
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @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
              0
              • I Offline
                I Offline
                Igor Baidiuk
                wrote on last edited by
                #7
                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
                0
                • Christian EhrlicherC Online
                  Christian EhrlicherC Online
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  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
                  1
                  • I Offline
                    I Offline
                    Igor Baidiuk
                    wrote on last edited by Igor Baidiuk
                    #9

                    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
                    0
                    • Christian EhrlicherC Online
                      Christian EhrlicherC Online
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @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
                      -1
                      • I Igor Baidiuk

                        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

                        kshegunovK Offline
                        kshegunovK Offline
                        kshegunov
                        Moderators
                        wrote on last edited by
                        #11

                        @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
                        5
                        • I Offline
                          I Offline
                          Igor Baidiuk
                          wrote on last edited by
                          #12

                          @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
                          0

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved