Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().

2016-08-08 Thread Konrad Rosenbaum
Hi,

On Sunday 07 August 2016 10:06:54 Thiago Macieira wrote:
> On domingo, 7 de agosto de 2016 10:17:44 PDT André Somers wrote:
> > > Yet, I don't see where the problem is. QDialog::exec() displays a
> > > modal
> > > dialog. It is not possible to click again on the menu or button that
> > > displayed the dialog in the first place. It effectively breaks
> > > recursive
> > > looping, right?
> > 
> > Wrong. There are many sources of events, and only the ones related to
> > user input are blocked this way.
> 
> Indeed. Think of your sockets, that are still receiving data and that is
> being processed. Are you sure that your dialog wasn't created as a
> response to some data being processed earlier?
> 
> Think also of all the timers that will time out.

Let me weigh in at this point: yes, it is true - nested event loops make it 
very easy to shoot yourself in the foot. Sorry, you are using C++, if you 
wanted it safe you would bake bread.

I use them all the time because they make simple algorithms understandable - 
event based constructs, even using lambdas, make them horribly hard to 
understand. I even wrote a few such methods for my own code.

Here's the choice:

a) avoid exec() at all costs and suffer unreadable code and a lot of the 
problems described below simply get hidden in a forest of less readable code

b) follow a few simple rules instead:

 - avoid direct delete on QObjects - use deleteLater instead (it is delayed 
for the main event loop)

 - use high-level methods instead of deletes: e.g. tell a window to close 
itself and set it up for automatic cleanup instead of deleting it directly

 - try to communicate via signals and set the connections up when you create 
the receiver object - Qt will clean the connections up when the receiver is 
deleted

 - if you absolutely and positively cannot avoid using a pointer - use 
QPointer and check it before you call a method

 - enable your code to deal with disappearing objects - i.e. let a child 
object tell its parent that it is gone and stop any actions that depend on 
it when you receive this signal (otherwise you risk endless waiting)

 - when you write code that can take a while: think about everything that 
could conceivably happen in between and prepare the program for "stuff 
happening" - i.e. disappearing objects, more events coming in, things 
queuing up, the user losing patience and clicking "Exit", etc.

Qt make it very easy for you to write readable code - I refuse to compromise 
this out of paranoia.

Konrad


signature.asc
Description: This is a digitally signed message part.
___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().

2016-08-07 Thread Thiago Macieira
On domingo, 7 de agosto de 2016 10:17:44 PDT André Somers wrote:
> > Yet, I don't see where the problem is. QDialog::exec() displays a modal
> > dialog. It is not possible to click again on the menu or button that
> > displayed the dialog in the first place. It effectively breaks recursive
> > looping, right?
> Wrong. There are many sources of events, and only the ones related to user
> input are blocked this way. 

Indeed. Think of your sockets, that are still receiving data and that is being 
processed. Are you sure that your dialog wasn't created as a response to some 
data being processed earlier?

Think also of all the timers that will time out.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().

2016-08-07 Thread André Somers


Verstuurd vanaf mijn iPhone

> Op 7 aug. 2016 om 09:12 heeft Frederic Marchal 
>  het volgende geschreven:
> 
> On Thursday 04 August 2016 11:20:58 Thiago Macieira wrote:
> > On quinta-feira, 4 de agosto de 2016 10:32:26 PDT John Weeks wrote:
> > > > On Aug 4, 2016, at 10:04 AM, Thiago Macieira 
> > > > wrote:
> > > >
> > > > Starting an event loop from inside another event loop.
> > > >
> > > > exec() → some slot or event handler → exec()
> > >
> > > It would also seem to cover any use of QDialog::exec() in the main thread,
> > > and QDialog can be used only in the main thread.
> >
> > Correct. Don't use exec(). Call show() it and return to the existing
> > mainloop.
>  
> That's very restrictive!
>  
> It is common (at least to me) to call QFileDialog::getOpenFileName() when the 
> user clicks on the "Open" menu and then use the returned file name to carry 
> on the open action. QFileDialog::getOpenFileName() does call QDialog::exec(). 
> According to you, it must be avoided like the plague… It means it renders 
> similar QFileDialog static methods useless.
>  
> Yet, I don't see where the problem is. QDialog::exec() displays a modal 
> dialog. It is not possible to click again on the menu or button that 
> displayed the dialog in the first place. It effectively breaks recursive 
> looping, right?
>  
Wrong. There are many sources of events, and only the ones related to user 
input are blocked this way. 

André

> Frederic
>  
> ___
> Interest mailing list
> Interest@qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest

___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().

2016-08-07 Thread Frederic Marchal
On Thursday 04 August 2016 11:20:58 Thiago Macieira wrote:
> On quinta-feira, 4 de agosto de 2016 10:32:26 PDT John Weeks wrote:
> > > On Aug 4, 2016, at 10:04 AM, Thiago Macieira 

> > > wrote:
> > > 
> > > Starting an event loop from inside another event loop.
> > > 
> > > exec() → some slot or event handler → exec()
> > 
> > It would also seem to cover any use of QDialog::exec() in the main 
thread,
> > and QDialog can be used only in the main thread.
> 
> Correct. Don't use exec(). Call show() it and return to the existing
> mainloop.

That's very restrictive!

It is common (at least to me) to call QFileDialog::getOpenFileName() when 
the user clicks on the "Open" menu and then use the returned file name to 
carry on the open action. QFileDialog::getOpenFileName() does call 
QDialog::exec(). According to you, it must be avoided like the plague… It 
means it renders similar QFileDialog static methods useless.

Yet, I don't see where the problem is. QDialog::exec() displays a modal 
dialog. It is not possible to click again on the menu or button that 
displayed the dialog in the first place. It effectively breaks recursive 
looping, right?

Frederic

___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().

2016-08-04 Thread Thiago Macieira
On quinta-feira, 4 de agosto de 2016 10:32:26 PDT John Weeks wrote:
> > On Aug 4, 2016, at 10:04 AM, Thiago Macieira 
> > wrote:
> > 
> > Starting an event loop from inside another event loop.
> > 
> > exec() → some slot or event handler → exec()
> 
> OK, so that would cover any use of QEventLoop::exec() in the main thread.

Correct, unless you did it in the main() function before or instead of 
QCoreApplication::main().

> It would also seem to cover any use of QDialog::exec() in the main thread,
> and QDialog can be used only in the main thread.

Correct. Don't use exec(). Call show() it and return to the existing mainloop.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().

2016-08-04 Thread John Weeks

> On Aug 4, 2016, at 10:04 AM, Thiago Macieira  
> wrote:
> 
> Starting an event loop from inside another event loop.
> 
> exec() → some slot or event handler → exec()

OK, so that would cover any use of QEventLoop::exec() in the main thread.

It would also seem to cover any use of QDialog::exec() in the main thread, and 
QDialog can be used only in the main thread.

-John Weeks

___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().

2016-08-04 Thread Thiago Macieira
On quinta-feira, 4 de agosto de 2016 09:25:21 PDT John Weeks wrote:
> At the risk of displaying my ignorance...
> 
> Having followed this thread with great interest, I have come to the
> conclusion that perhaps I'm not really certain what you mean by "nested".
> Any chance of an example?

Starting an event loop from inside another event loop.

exec() → some slot or event handler → exec()

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().

2016-08-04 Thread John Weeks
At the risk of displaying my ignorance...

Having followed this thread with great interest, I have come to the conclusion 
that perhaps I'm not really certain what you mean by "nested". Any chance of an 
example?


> On Aug 3, 2016, at 10:31 PM, Thiago Macieira  
> wrote:
> 
> I disagree. You should try to split. Lambdas might help.
> 
> -- 
> Thiago Macieira - thiago.macieira (AT) intel.com
>  Software Architect - Intel Open Source Technology Center
> 
> ___
> Interest mailing list
> Interest@qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest

Lambdas have always seemed like a great way to write large blocks of obscure 
code, but it seems like I'm missing something. Another example?

-John

___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().

2016-08-03 Thread Thiago Macieira
On quinta-feira, 4 de agosto de 2016 04:21:44 PDT Uwe Rathmann wrote:
> Having to write this code without nested loops ( f.e. QDialog::exec() ) 
> leads to 3 method ...
> 
> - before askForOption
> - between askForOption and doYouReallyWantTo
> - after doYouReallyWantTo
> 
> ... where you always have the problem to transfer the variables from the 
> stack ( here option ).
> 
> Once your code ends up in sequences of between-GUI-interactions methods 
> you will have way more problems, than what nested event loops might be.
> 
> So yes nested loops might be a problem, but not using them is IMHO the 
> wrong consequence.

I disagree. You should try to split. Lambdas might help.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().

2016-08-03 Thread Uwe Rathmann
On Wed, 03 Aug 2016 13:41:51 -0700, Thiago Macieira wrote:

> It's still a source of errors because the nesting counter can be
> incremented in different ways, depending on what triggered the event. So
> the recommendation remains: avoid nesting like the plague.

void doIt()
{
...

int option = askForOption();

...

if ( doYouReallyWantTo( option ) )
{
...
}
}

Having to write this code without nested loops ( f.e. QDialog::exec() ) 
leads to 3 method ...

- before askForOption
- between askForOption and doYouReallyWantTo
- after doYouReallyWantTo

... where you always have the problem to transfer the variables from the 
stack ( here option ).

Once your code ends up in sequences of between-GUI-interactions methods 
you will have way more problems, than what nested event loops might be.

So yes nested loops might be a problem, but not using them is IMHO the 
wrong consequence.

Uwe


___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().

2016-08-03 Thread Thiago Macieira
On quarta-feira, 3 de agosto de 2016 22:25:32 PDT Konstantin Shegunov wrote:
> On Wed, Aug 3, 2016 at 8:58 PM, Thiago Macieira 
> 
> wrote:
> > On quarta-feira, 3 de agosto de 2016 11:22:36 PDT Jorge Fierro wrote:
> > > - If QEventLoop::exec() spins the main loop then any event at all can
> > > be generated. Is this why one must use it very carefully to avoid
> > > reentrancy issues?
> > 
> > Yes. Avoid nesting event loops like the plague.
> 
> With, I believe, the important exception being the deferred deletion
> events, which are processed only be the last (main) event loop.

Correct, the deletion events are only processed by an event loop of the same 
equally or less nested than when the event was posted. That exists because a 
lot of code depends on deleteLater() being much later than what was happening.

It's still a source of errors because the nesting counter can be incremented 
in different ways, depending on what triggered the event. So the 
recommendation remains: avoid nesting like the plague.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().

2016-08-03 Thread Konstantin Shegunov
On Wed, Aug 3, 2016 at 8:58 PM, Thiago Macieira 
wrote:

> On quarta-feira, 3 de agosto de 2016 11:22:36 PDT Jorge Fierro wrote:


> > - If QEventLoop::exec() spins the main loop then any event at all can
> > be generated. Is this why one must use it very carefully to avoid
> > reentrancy issues?
>
> Yes. Avoid nesting event loops like the plague.
>

With, I believe, the important exception being the deferred deletion
events, which are processed only be the last (main) event loop.
___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().

2016-08-03 Thread Jason H


> Sent: Wednesday, August 03, 2016 at 1:22 PM
> From: "Jorge Fierro" <jo...@jorgefierro.com>
> To: interest@qt-project.org
> Subject: [Interest] Relationship between a QEventLoop and 
> QCoreApplication::exec().
>
> Hi. I've been reading through the documentation and mailing list
> archives and I haven't found an authoritative and/or conclusive answer to
> the following question:
> 
> What exactly is the relationship between an event loop entered by
> calling QEventLoop::exec() and *the* main event loop (the one running
> when you can QCoreApplication::exec())?
> 
> There are a number of related questions:
> 
> - Does QEventLoop::exec() enter *the* main event loop? Or,
> - Does QEventLoop::exec() enter a different event loop independent
> from QCoreApplication::exec()?
> - Can QEventLoop::exec() be called outside QCoreApplication::exec()
> (i.e., in a call stack that didn't originate from
> QCoreApplication::exec())?
> - If QEventLoop::exec() spins the main loop then any event at all can
> be generated. Is this why one must use it very carefully to avoid
> reentrancy issues?

As far as I know QCoreApplication::exec() does call QEventLoop::exec(). 
A thread can have a event loop, and cross-thread signal/slot communication is 
done via messages in each thread's event loop.
A thread may have more than one event loop. (I think I used this in the past to 
handle some modal dialog issues. I think while the second event loop is running 
that the first is unresponsive.)

HTH.


___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Relationship between a QEventLoop and QCoreApplication::exec().

2016-08-03 Thread Thiago Macieira
On quarta-feira, 3 de agosto de 2016 11:22:36 PDT Jorge Fierro wrote:
> What exactly is the relationship between an event loop entered by
> calling QEventLoop::exec() and *the* main event loop (the one running
> when you can QCoreApplication::exec())?

Both functions as well as QThread::exec() are windows into the actual event 
dispatcher that runs behind the scenes. All three control the 
QAbstractEventDispatcher that either QCoreApplication or QThread creates.

I think these two links answer your question best:

https://code.woboq.org/qt5/qtbase/src/corelib/kernel/
qcoreapplication.cpp.html#_ZN16QCoreApplication4execEv (line 1258)
https://code.woboq.org/qt5/qtbase/src/corelib/thread/
qthread.cpp.html#_ZN7QThread4execEv (line 506)

As you can see, both QCoreApplication::exec or QThread::exec create a 
QEventLoop and call exec on it. The same is also true, for that matter, for 
QDialog::exec.

> There are a number of related questions:
> 
> - Does QEventLoop::exec() enter *the* main event loop? Or,
> - Does QEventLoop::exec() enter a different event loop independent
> from QCoreApplication::exec()?

There's only one event dispatcher per thread. 

> - Can QEventLoop::exec() be called outside QCoreApplication::exec()
> (i.e., in a call stack that didn't originate from QCoreApplication::exec())?

Sure. You could even use QEventLoop::exec() in place of 
QCoreApplication::exec() in your main function or QThread::exec() in your run 
function. The two are very similar, but not identical. QCoreApplication's loop 
emits aboutToQuit and its descendant classes react to the last window closing, 
while QEventLoop does not.

> - If QEventLoop::exec() spins the main loop then any event at all can
> be generated. Is this why one must use it very carefully to avoid
> reentrancy issues?

Yes. Avoid nesting event loops like the plague.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


[Interest] Relationship between a QEventLoop and QCoreApplication::exec().

2016-08-03 Thread Jorge Fierro
Hi. I've been reading through the documentation and mailing list
archives and I haven't found an authoritative and/or conclusive answer to
the following question:

What exactly is the relationship between an event loop entered by
calling QEventLoop::exec() and *the* main event loop (the one running
when you can QCoreApplication::exec())?

There are a number of related questions:

- Does QEventLoop::exec() enter *the* main event loop? Or,
- Does QEventLoop::exec() enter a different event loop independent
from QCoreApplication::exec()?
- Can QEventLoop::exec() be called outside QCoreApplication::exec()
(i.e., in a call stack that didn't originate from
QCoreApplication::exec())?
- If QEventLoop::exec() spins the main loop then any event at all can
be generated. Is this why one must use it very carefully to avoid
reentrancy issues?

Thanks.
___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest