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. Thread safety of QMetaObject::invokeMethod e.g. slot invoking from random threads
Qt 6.11 is out! See what's new in the release blog

Thread safety of QMetaObject::invokeMethod e.g. slot invoking from random threads

Scheduled Pinned Locked Moved Unsolved General and Desktop
15 Posts 4 Posters 7.7k 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.
  • Christian EhrlicherC Christian Ehrlicher

    Since I don't know the exact internals the only way I see is to create a bug report report and ask directly.

    S Offline
    S Offline
    Superlokkus
    wrote on last edited by Superlokkus
    #5

    @Christian-Ehrlicher said in Thread safety of QMetaObject::invokeMethod e.g. slot invoking from random threads:

    Since I don't know the exact internals the only way I see is to create a bug report report and ask directly.

    Just opened
    https://bugreports.qt.io/browse/QTBUG-72599

    kshegunovK 1 Reply Last reply
    0
    • dheerendraD Offline
      dheerendraD Offline
      dheerendra
      Moderators Qt Champions 2024 Qt Champions 2022 Qt Champions 2017
      wrote on last edited by
      #6

      I don't think this will be thread safe. This will get instance of metaobject and is single instance for all the subclasses of qobject. QObject itself is not thread safe. Invoke method access many internal pointers which are not protected. It also accesses qobject pointer

      Dheerendra
      @Community Service
      Certified Qt Specialist
      https://www.pthinks.com

      1 Reply Last reply
      0
      • Christian EhrlicherC Online
        Christian EhrlicherC Online
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #7

        The specific problem was about a queued connection which is more or less a QCoreApplication::postEvent() which is thread safe ...

        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
        2
        • S Superlokkus

          @Christian-Ehrlicher said in Thread safety of QMetaObject::invokeMethod e.g. slot invoking from random threads:

          Since I don't know the exact internals the only way I see is to create a bug report report and ask directly.

          Just opened
          https://bugreports.qt.io/browse/QTBUG-72599

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

          invokeMethod is thread-safe with the Qt::QueuedConnection argument in the sense that it's going to do what you expect it to - i.e. put a message in the receiving thread's event loop for a meta-call. It is most certainly not thread-safe when used with Qt::AutoConnection.

          I would not define this as thread-safe, it would be thread safe, if the internals of QMetaObject::invokeMethod is reentrant

          Thread-safety and reentrancy are orthogonal to each other. A function can be thread-safe and non-reentrant (which invokeMethod actually is with the Qt::QueuedConnection, as it operates on the threading globals) or vice versa ... or any combination thereof.

          Read and abide by the Qt Code of Conduct

          S 1 Reply Last reply
          3
          • dheerendraD Offline
            dheerendraD Offline
            dheerendra
            Moderators Qt Champions 2024 Qt Champions 2022 Qt Champions 2017
            wrote on last edited by
            #9

            If it is queues connection as @kshegunov said it will just place in destination thread and move on. If multiple threads call same method with queued connection I don't see issue. If it mixes connection type then it shud create issue.

            Dheerendra
            @Community Service
            Certified Qt Specialist
            https://www.pthinks.com

            1 Reply Last reply
            0
            • kshegunovK kshegunov

              invokeMethod is thread-safe with the Qt::QueuedConnection argument in the sense that it's going to do what you expect it to - i.e. put a message in the receiving thread's event loop for a meta-call. It is most certainly not thread-safe when used with Qt::AutoConnection.

              I would not define this as thread-safe, it would be thread safe, if the internals of QMetaObject::invokeMethod is reentrant

              Thread-safety and reentrancy are orthogonal to each other. A function can be thread-safe and non-reentrant (which invokeMethod actually is with the Qt::QueuedConnection, as it operates on the threading globals) or vice versa ... or any combination thereof.

              S Offline
              S Offline
              Superlokkus
              wrote on last edited by
              #10

              @kshegunov said in Thread safety of QMetaObject::invokeMethod e.g. slot invoking from random threads:

              Thread-safety and reentrancy are orthogonal to each other.
              I know, however since we don't have to deal with Interrupts here, in practice reentrancy usually is a precondition for thread safety, because, when a function can not be called in thread A, while it has been execute to some in between state in Thread B, what is thread safety then.

              But anyway, that constraints, like "QMetaObject::invokeMethod is thread safe when called with Qt::QueuedConnection and with recipient and parameters living at least until slot completion or something" should be documented, so one can be sure, that it really is. (However for the parameters should be fine with Q_ARGS, call by value AFAIK)

              kshegunovK 1 Reply Last reply
              0
              • S Superlokkus

                @kshegunov said in Thread safety of QMetaObject::invokeMethod e.g. slot invoking from random threads:

                Thread-safety and reentrancy are orthogonal to each other.
                I know, however since we don't have to deal with Interrupts here, in practice reentrancy usually is a precondition for thread safety, because, when a function can not be called in thread A, while it has been execute to some in between state in Thread B, what is thread safety then.

                But anyway, that constraints, like "QMetaObject::invokeMethod is thread safe when called with Qt::QueuedConnection and with recipient and parameters living at least until slot completion or something" should be documented, so one can be sure, that it really is. (However for the parameters should be fine with Q_ARGS, call by value AFAIK)

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

                I think you misunderstand. QMetaObject::invokeMethod does not execute the method when it's called with Qt::QueuedConnection, which is the whole point of it. Instead it creates a QEvent::MetaCall event and puts it into the receiving object's thread's event queue. This all means that the event is processed (as all posted events) synchronously from the receiving thread's event loop. So you kind of lose the idea of "thread-safe" as you're not really calling the method itself. The receiving thread will call it when it gets to it. Unless if you mean if the actual event posting is thread-safe, then the answer is "yes, most certainly".

                Read and abide by the Qt Code of Conduct

                S 1 Reply Last reply
                2
                • kshegunovK kshegunov

                  I think you misunderstand. QMetaObject::invokeMethod does not execute the method when it's called with Qt::QueuedConnection, which is the whole point of it. Instead it creates a QEvent::MetaCall event and puts it into the receiving object's thread's event queue. This all means that the event is processed (as all posted events) synchronously from the receiving thread's event loop. So you kind of lose the idea of "thread-safe" as you're not really calling the method itself. The receiving thread will call it when it gets to it. Unless if you mean if the actual event posting is thread-safe, then the answer is "yes, most certainly".

                  S Offline
                  S Offline
                  Superlokkus
                  wrote on last edited by
                  #12

                  @kshegunov said in Thread safety of QMetaObject::invokeMethod e.g. slot invoking from random threads:

                  Unless if you mean if the actual event posting is thread-safe, then the answer is "yes, most certainly".

                  Exactly that is what I meant! Thats the reason why I tried to use QCoreApplication::postEvent first, since it seemed to me as the only thread safe way, to post an event to the global qt event queue.

                  kshegunovK 1 Reply Last reply
                  0
                  • S Superlokkus

                    @kshegunov said in Thread safety of QMetaObject::invokeMethod e.g. slot invoking from random threads:

                    Unless if you mean if the actual event posting is thread-safe, then the answer is "yes, most certainly".

                    Exactly that is what I meant! Thats the reason why I tried to use QCoreApplication::postEvent first, since it seemed to me as the only thread safe way, to post an event to the global qt event queue.

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

                    Thats the reason why I tried to use QCoreApplication::postEvent first

                    It is one way. You can't create QEvent::MetaCall events for it, however, this is where QMetaObject::invokeMethod comes into play.

                    to post an event to the global qt event queue.

                    There's no global event queue, there's an event queue for each thread that starts one with QEventLoop::exec (which the main thread does through QCoreApplication::exec).

                    Read and abide by the Qt Code of Conduct

                    S 1 Reply Last reply
                    3
                    • kshegunovK kshegunov

                      Thats the reason why I tried to use QCoreApplication::postEvent first

                      It is one way. You can't create QEvent::MetaCall events for it, however, this is where QMetaObject::invokeMethod comes into play.

                      to post an event to the global qt event queue.

                      There's no global event queue, there's an event queue for each thread that starts one with QEventLoop::exec (which the main thread does through QCoreApplication::exec).

                      S Offline
                      S Offline
                      Superlokkus
                      wrote on last edited by Superlokkus
                      #14

                      @kshegunov said in Thread safety of QMetaObject::invokeMethod e.g. slot invoking from random threads:

                      There's no global event queue, there's an event queue for each thread that starts one with QEventLoop::exec (which the main thread does through QCoreApplication::exec).

                      Yeah sorry, I often forget that you can also create extra QThreads/Widgets with own event loops. With global I meant of course the stuff you get by QCoreApplication::instance, like you said, (which AFAIK is special as it needs to be pumped in order to Qt in general to work), but thanks for clarifying.

                      However I just posted my "solution" aka version of the common pattern: https://stackoverflow.com/a/53806409/3537677 with also some assumptions by me, which of course you are invited to review!

                      kshegunovK 1 Reply Last reply
                      0
                      • S Superlokkus

                        @kshegunov said in Thread safety of QMetaObject::invokeMethod e.g. slot invoking from random threads:

                        There's no global event queue, there's an event queue for each thread that starts one with QEventLoop::exec (which the main thread does through QCoreApplication::exec).

                        Yeah sorry, I often forget that you can also create extra QThreads/Widgets with own event loops. With global I meant of course the stuff you get by QCoreApplication::instance, like you said, (which AFAIK is special as it needs to be pumped in order to Qt in general to work), but thanks for clarifying.

                        However I just posted my "solution" aka version of the common pattern: https://stackoverflow.com/a/53806409/3537677 with also some assumptions by me, which of course you are invited to review!

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

                        @Superlokkus said in Thread safety of QMetaObject::invokeMethod e.g. slot invoking from random threads:

                        which AFAIK is special as it needs to be pumped in order to Qt in general to work

                        No not really. QCoreApplication::exec just does QEventLoop::exec ... :)

                        PS:
                        Ah, I see Giuseppe already answered you. One note on your call, if you're using Qt 5.10+ you can use QMetaObject::invokeMethod with functors (i.e. lambdas or pointers to methods), which is often more convenient and less error prone than resolving the method address through its name.

                        Read and abide by the Qt Code of Conduct

                        1 Reply Last reply
                        2

                        • Login

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