Discussion:
[Development] Qthread::create and ::exec
Иван Комиссаров
2018-11-20 13:30:47 UTC
Permalink
Hello, I've noticed that it would be nice to run QThread::exec() from a functor passed to QThread::create(). However, exec is marked as protected, thus I can't call QThread::currentThread()->exec().
Maybe it is worth to make exec() public method? Or make it static, like in QApp (is it BC?)?
This would be a nice addition to the create() method so worker objects can be created in a functor on stack instead of moving them to thread.

Иван Комиссаров
Volker Hilsheimer
2018-11-21 14:47:58 UTC
Permalink
Post by Иван Комиссаров
Hello, I've noticed that it would be nice to run QThread::exec() from a functor passed to QThread::create(). However, exec is marked as protected, thus I can't call QThread::currentThread()->exec().
Maybe it is worth to make exec() public method? Or make it static, like in QApp (is it BC?)?
This would be a nice addition to the create() method so worker objects can be created in a functor on stack instead of moving them to thread.
Иван Комиссаров
The reason why QThread::exec is protected so that people don’t get tempted to call it directly on a QThread object and expecting that the event loop is somehow executed in a separate thread. It is useful to generate a compile-time error when this is attempted:

QThread *heyNewThread = new QThread;
heyNewThread->exec();


I would rather not remove that limitation (and it would break BC on compilers that include the access level in the generated symbol). Making exec() public would indicate that the above is ok, while it actually breaks the semantics.

FWIW, if you reimplement run() you can allocate your objects on the stack and then call exec(). It’s of course some more boilerplate compared to using e.g a lambda as the worker.

Cheers,
Volker
Olivier Goffart
2018-11-21 15:10:00 UTC
Permalink
Post by Volker Hilsheimer
Post by Иван Комиссаров
Hello, I've noticed that it would be nice to run QThread::exec() from a functor passed to QThread::create(). However, exec is marked as protected, thus I can't call QThread::currentThread()->exec().
Maybe it is worth to make exec() public method? Or make it static, like in QApp (is it BC?)?
This would be a nice addition to the create() method so worker objects can be created in a functor on stack instead of moving them to thread.
Иван Комиссаров
QThread *heyNewThread = new QThread;
heyNewThread->exec();
I would rather not remove that limitation (and it would break BC on compilers that include the access level in the generated symbol). Making exec() public would indicate that the above is ok, while it actually breaks the semantics.
No need to access QThread::exec().
One can just call

QEventLoop().exec();

And that has the same effect.
--
Olivier

Woboq - Qt services and support - https://woboq.com - https://code.woboq.org
Иван Комиссаров
2018-11-21 15:26:06 UTC
Permalink
Except there's possible race-condition if quit() is called before loop started, isn't it? At least, qthread::exec do some checks under mutex

Иван Комиссаров
Post by Olivier Goffart
Post by Volker Hilsheimer
Post by Иван Комиссаров
Hello, I've noticed that it would be nice to run QThread::exec() from a functor passed to QThread::create(). However, exec is marked as protected, thus I can't call QThread::currentThread()->exec().
Maybe it is worth to make exec() public method? Or make it static, like in QApp (is it BC?)?
This would be a nice addition to the create() method so worker objects can be created in a functor on stack instead of moving them to thread.
Иван Комиссаров
QThread *heyNewThread = new QThread;
heyNewThread->exec();
I would rather not remove that limitation (and it would break BC on compilers that include the access level in the generated symbol). Making exec() public would indicate that the above is ok, while it actually breaks the semantics.
No need to access QThread::exec().
One can just call
QEventLoop().exec();
And that has the same effect.
--
Olivier
Woboq - Qt services and support - https://woboq.com - https://code.woboq.org
_______________________________________________
Development mailing list
https://lists.qt-project.org/listinfo/development
Olivier Goffart
2018-11-21 15:37:17 UTC
Permalink
Post by Иван Комиссаров
Except there's possible race-condition if quit() is called before loop started, isn't it? At least, qthread::exec do some checks under mutex
No, QEventLoop::exec also checks for d->threadData->quitNow

The only difference would be the return code.
(And note that there is a race condition in QThread::exec, which could lead the
return code to be lost if QThread::exit() is called right at the moment
QThread::exec() is called.)
Post by Иван Комиссаров
Иван Комиссаров
Post by Olivier Goffart
Post by Volker Hilsheimer
Post by Иван Комиссаров
Hello, I've noticed that it would be nice to run QThread::exec() from a functor passed to QThread::create(). However, exec is marked as protected, thus I can't call QThread::currentThread()->exec().
Maybe it is worth to make exec() public method? Or make it static, like in QApp (is it BC?)?
This would be a nice addition to the create() method so worker objects can be created in a functor on stack instead of moving them to thread.
Иван Комиссаров
QThread *heyNewThread = new QThread;
heyNewThread->exec();
I would rather not remove that limitation (and it would break BC on compilers that include the access level in the generated symbol). Making exec() public would indicate that the above is ok, while it actually breaks the semantics.
No need to access QThread::exec().
One can just call
QEventLoop().exec();
And that has the same effect.
--
Olivier
Woboq - Qt services and support - https://woboq.com - https://code.woboq.org
_______________________________________________
Development mailing list
https://lists.qt-project.org/listinfo/development
Иван Комиссаров
2018-11-21 18:27:50 UTC
Permalink
Иван Комиссаров
Post by Olivier Goffart
Post by Иван Комиссаров
Except there's possible race-condition if quit() is called before loop started, isn't it? At least, qthread::exec do some checks under mutex
No, QEventLoop::exec also checks for d->threadData->quitNow
Ok, thanks, I didn't dig that deep.
Post by Olivier Goffart
The only difference would be the return code.
(And note that there is a race condition in QThread::exec, which could lead the return code to be lost if QThread::exit() is called right at the moment QThread::exec() is called.)
Heh, that code looked suspicious to me:) I was wondering if I'm missing something but it appears that I don't

Thank's for the clarification.
Post by Olivier Goffart
Post by Иван Комиссаров
Иван Комиссаров
Post by Olivier Goffart
Post by Volker Hilsheimer
Post by Иван Комиссаров
Hello, I've noticed that it would be nice to run QThread::exec() from a functor passed to QThread::create(). However, exec is marked as protected, thus I can't call QThread::currentThread()->exec().
Maybe it is worth to make exec() public method? Or make it static, like in QApp (is it BC?)?
This would be a nice addition to the create() method so worker objects can be created in a functor on stack instead of moving them to thread.
Иван Комиссаров
QThread *heyNewThread = new QThread;
heyNewThread->exec();
I would rather not remove that limitation (and it would break BC on compilers that include the access level in the generated symbol). Making exec() public would indicate that the above is ok, while it actually breaks the semantics.
No need to access QThread::exec().
One can just call
QEventLoop().exec();
And that has the same effect.
--
Olivier
Woboq - Qt services and support - https://woboq.com - https://code.woboq.org
_______________________________________________
Development mailing list
https://lists.qt-project.org/listinfo/development
Иван Комиссаров
2018-11-21 18:29:53 UTC
Permalink
Actually, that's what I'm trying to avoid=)

Иван Комиссаров
Post by Volker Hilsheimer
FWIW, if you reimplement run() you can allocate your objects on the stack and then call exec(). It’s of course some more boilerplate compared to using e.g a lambda as the worker.
Loading...