Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Qt::BlockingQueuedConnection With Null Receiver?



  • Howdy,

    My comms thread sometimes needs to communicate with my main thread; in particular I have a backend 'device' class (comms) that is represented to the user by a 'UIdevice' class (main). At teardown, I need to delete both classes, and, as of now, this can happen in a variety of ways.

    Anyway, what should I expect to happen if the comms device emits a Qt::BlockingQueuedConnection signal to a UIdevice that no longer exists? I'm suspecting deadlock. If so, is there a way to check for the existence of the receiver before emitting the signal?

    Thanks,
    Alex


  • Moderators

    @wumpus7 said in Qt::BlockingQueuedConnection With Null Receiver?:

    what should I expect to happen if the comms device emits a Qt::BlockingQueuedConnection signal to a UIdevice that no longer exists?

    When a QObject's destructor is called, it automatically disconnects from all existing signals so you shouldn't have to worry.


  • Moderators

    @wumpus7
    I wanted to expand an @JKSH answer.
    If you did all your connects in a proper way. You do not need to to worry. If either sender or receiver object is destroyed. The connect is dissolved.

    But, if you didn‘t specify a receiver, which you can get away with, if you connect to a lambda. Or if you simply omit it, in which case it defaults to this As receiver object.
    Than you may run into trouble, where you connect to a function/class or even object that no longer exists.

    Make sure all your lambda connects have reference receiver objects, and you should be always fine 😉



  • Thanks for the quick replies!

    I'd somehow missed the fact that the connect() should be broken by destruction - that totally makes sense.

    Just to be clear, though, the sequence of events for emitting a blocking signal isn't:

    1. Block
    2. Send signal (or don't in the case of no connection)
    3. Await return

    Is it? Because the fact that the connection was gone wouldn't necessarily help if that were true, as the block would still occur, and the return still wouldn't.

    I'm hoping that the sequence is, instead:

    1. Send signal (or don't in case of no connection)
    2. Block and await return (if signal sent in step 1)

    (And no, I'm not doing anything fancy with lambdas or defaults, so that shouldn't matter in my case.)


  • Qt Champions 2017

    @J.Hilk said in Qt::BlockingQueuedConnection With Null Receiver?:

    Or if you simply omit it, in which case it defaults to this As receiver object

    This is incorrect. The receiver's thread in that case is the emitter's thread.

    Make sure all your lambda connects have reference receiver objects

    Good advice! Just to reiterate, don't connect lambdas without specifying a context object!


  • Moderators

    @kshegunov said in Qt::BlockingQueuedConnection With Null Receiver?:

    @J.Hilk said in Qt::BlockingQueuedConnection With Null Receiver?:

    Or if you simply omit it, in which case it defaults to this As receiver object

    This is incorrect. The receiver's thread in that case is the emitter's thread.

    Maybe I expressed myself not good enough, what I meant was this overload:

    http://doc.qt.io/qt-5/qobject.html#connect-2

    0_1543470535444_abbe5f74-2f92-41cb-86b9-1a8f7a0e64e0-image.png

    not the relation between calling and executing threads :-)


  • Qt Champions 2017

    @J.Hilk said in Qt::BlockingQueuedConnection With Null Receiver?:

    Maybe I expressed myself not good enough, what I meant was this overload

    Yes, apparently we are talking about different things.


  • Moderators

    @wumpus7 said in Qt::BlockingQueuedConnection With Null Receiver?:

    Just to be clear, though, the sequence of events for emitting a blocking signal isn't:

    1. Block
    2. Send signal (or don't in the case of no connection)
    3. Await return

    Is it? Because the fact that the connection was gone wouldn't necessarily help if that were true, as the block would still occur, and the return still wouldn't.

    I'm hoping that the sequence is, instead:

    1. Send signal (or don't in case of no connection)
    2. Block and await return (if signal sent in step 1)

    Try it and find out :) 'Tis the hacker way.


Log in to reply