[Development] invokeMethod() with function pointers
Olivier Goffart
olivier at woboq.com
Fri Jan 20 11:14:12 CET 2017
On Dienstag, 17. Januar 2017 11:21:56 CET Grégoire Barbier wrote:
> Le 16/01/2017 à 10:34, Olivier Goffart a écrit :
> > What's the use case for this function? For direct call you better of
> > calling the function directly, and the equivalent of QueuedConnection
> > can be achieved with QTimer::singleShot.
>
> Hi.
>
> AFAIK there is no other way to call a method across threads *and wait
> for it result* than QMetaObject::invokeMethod() with
> Qt::BlockingQueuedConnection and Q_RETURN_ARG (apart, of course, making
> the called method thread-safe).
That's a valid use case. Thank you for bringing that up.
[...]
> Also (I still dream), if there was a way to make invokeMethod()
> automagically choose between a direct call and
> Qt::BlockingQueuedConnection, it would be possible to get rid of this idiom:
> if (QThread::currentThread() == this->thread())
> foo = func();
> else
> QMetaObject::invokeMethod(this, "func",
> Qt::BlockingQueuedConnection,
> Q_RETURN_ARG(foo));
>
> Kind of Qt::DirectOrBlockingQueuedConnection.
See the discussion in https://codereview.qt-project.org/83404/ for why this is
not a good idea.
In summary, BlockingQueuedConnection is dangerous as it can lead to deadlock
if the other thread is waiting on your thread. In order to use it properly,
you really need to know, while programming in which thread you are and which
thread you try to communicate to, and be sure that there is never in your
program cases where the other thread may be waiting on a QWaitCondition for
your other thread. So this pattern with QThread::currentThread() == this-
>thread() before a BlockingQueuedConnection is really dangerous.
On the other hand, it would be useful to get the return value of a
QueuedConnection in a QFuture.
--
Olivier
Woboq - Qt services and support - https://woboq.com - https://code.woboq.org
More information about the Development
mailing list