Re: [Interest] Expected event execution order in this multi-thread application

2019-10-06 Thread Thiago Macieira
On Saturday, 5 October 2019 06:13:56 PDT Richard Weickelt wrote:
> >> Because I attached a debugger and stopped T1 during
> >> QCoreApplication::processEvents(). I can see E3 (the one that the thread
> >> is
> >> currently processing) in postEventList at index 0 and E2 at index 1.
> >> That's
> >> it. From there I see the following call chain
> >> QEventDispatcherGlib::processEvents() followed by emit awake() because
> >> canWait is false. I haven't traced it further. The signal emission
> >> doesn't
> >> have any consequence in the event loop though.
> > 
> > Can you check what happens when it calls into
> > QCoreApplicationPrivate::sendPostedEvents()? That function should loop
> > from
> > data->postEventList.startOffset to data->postEventList.size() (size at the
> > time you call into the function, so no new events wil be handed).
> > Like you said, it should be handled on the first iteration after it's been
> > queued.
> 
> The problem is that my explicit calls to QCoreApplication::processEvents()
> do not reach QCoreApplicationPrivate::sendPostedEvents(). I found the root
> cause:
[snip]

Thanks for the detailed debugging, Richard, and for the bug report you filed. 
Looks like I wasn't seeing the problem because I was looking at the UNIX event 
dispatcher, but you're running against the Glib one. I usually prefer reading 
the source of the former because I can scroll through all of it. With the Glib 
one, since it goes through Glib and comes back out via callbacks, it's hard to 
follow.

And that's exactly the problem: because of the need for callbacks, it's saving 
the state for too long. There's a difference in behaviour between the two 
dispatchers and that needs to be fixed.

> > It's not broken, that's why it's not deprecated. But that doesn't mean
> > it's a good API. It's not advisable to use nested event loops.
> > processEvents() is just the worst kind of nested event loops.
> 
> Sure. Unfortunately, our application relies on QScriptEngine and requires
> that the engine's thread stays somewhat responsive. Now that I understand
> the problem, I might be able to implement a work-around in our application.

You may want QT_NO_GLIB=1 or just not build with Glib support.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel System Software Products



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


Re: [Interest] Expected event execution order in this multi-thread application

2019-10-05 Thread Richard Weickelt

>> Because I attached a debugger and stopped T1 during
>> QCoreApplication::processEvents(). I can see E3 (the one that the thread is
>> currently processing) in postEventList at index 0 and E2 at index 1. That's
>> it. From there I see the following call chain
>> QEventDispatcherGlib::processEvents() followed by emit awake() because
>> canWait is false. I haven't traced it further. The signal emission doesn't
>> have any consequence in the event loop though.
> 
> Can you check what happens when it calls into 
> QCoreApplicationPrivate::sendPostedEvents()? That function should loop from 
> data->postEventList.startOffset to data->postEventList.size() (size at the 
> time you call into the function, so no new events wil be handed).
> Like you said, it should be handled on the first iteration after it's been
> queued.

The problem is that my explicit calls to QCoreApplication::processEvents()
do not reach QCoreApplicationPrivate::sendPostedEvents(). I found the root
cause:

1. Posted events will increase a counter (serial number) in the glib event
dispatcher

2. Before a call into QCoreApplication::sendPostedEvents, the dispatcher
stores the current counter value (lastSerialNumber). If multiple events are
sitting in the event queue, the counter value will reflect the last posted
event.

3. Explicit periodic calls to QCoreApplication::processEvents() go into
QEventDispatcherGlib::processEvents() which invokes an iteration in the glib
event loop. So far so good.

4. The glib event loop now calls postEventSourcePrepare() which compares the
stored lastSerialNumber to the current serial number. This function acts as
a filter to decide whether the glib event loop should invoke
QCoreApplicationPrivate::sendPostedEvents(). Since it finds lastSerialNumber
to be equal to the current serial number, it doesn't do anything.

Here is a minimal example of what is happening. It doesn't even need
multiple threads:

#include 
#include 
#include 

namespace {
QAtomicInt done = 0;
}

void E1();
void E2();
void E3();

void E1() {
qDebug() << "E1";
QMetaObject::invokeMethod(qApp, , Qt::QueuedConnection);
QMetaObject::invokeMethod(qApp, , Qt::QueuedConnection);
}

void E2() {
qDebug() << "E2";
while (done == 0) {
QCoreApplication::processEvents();
}
QCoreApplication::exit(0);
}

void E3() {
// We never reach this
qDebug() << "E3";
done = 1;
}

int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QMetaObject::invokeMethod(qApp, , Qt::QueuedConnection);
app.exec();
}


As soon as some other thread posts an event E4 to the current event loop, E3
will be executed, followed by E4 as expected.

>> It is a public API and it is not marked as deprecated. If the function does
>> not behave as documented, then either the documentation is wrong or the
>> implementation has a bug or I am using it the wrong way. I don't think the
>> latter is the case, but maybe I need a minimal test case to prove that.
> 
> It's not broken, that's why it's not deprecated. But that doesn't mean it's a 
> good API. It's not advisable to use nested event loops. processEvents() is 
> just the worst kind of nested event loops.

Sure. Unfortunately, our application relies on QScriptEngine and requires
that the engine's thread stays somewhat responsive. Now that I understand
the problem, I might be able to implement a work-around in our application.

But I would consider this behavior to be a bug in qeventdispatcher_glib. It
can never be wrong to fix bugs, even in bad APIs ;-)

https://bugreports.qt.io/browse/QTBUG-79020

Richard
___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] Expected event execution order in this multi-thread application

2019-09-30 Thread Konstantin Tokarev


30.09.2019, 11:38, "Rainer Wiesenfarth" :
> On Mon, Sep 30, 2019 at 9:26 AM Thiago Macieira  
> wrote:
>> [...] Anyway, this is when you should use processEvents(): never.
>
> ...which would be a perfect reason to at least mark it as obsolete in Qt 6?

I would strongly oppose such deprecation, as it would break a few places in 
QtWebKit where it's used to integrate non-Qt code with Qt event loop

>
> I strongly second Thiago's recommendation: processEvents() usually introduces 
> more problems than it solves.
>
> --
> Software Engineer | Trimble Imaging Division
> Rotebühlstraße 81 | 70178 Stuttgart | Germany
> Office +49 711 22881 0 | Fax +49 711 22881 11
> http://www.trimble.com/imaging/ | http://www.inpho.de/
>
> Trimble Germany GmbH, Am Prime Parc 11, 65479 Raunheim
> Eingetragen beim Amtsgericht Darmstadt unter HRB 83893,
> Geschäftsführer: Dr. Frank Heimberg, Jürgen Kesper
> ,
>
> ___
> Interest mailing list
> Interest@qt-project.org
> https://lists.qt-project.org/listinfo/interest


-- 
Regards,
Konstantin
___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] Expected event execution order in this multi-thread application

2019-09-30 Thread Thiago Macieira
On Monday, 30 September 2019 08:05:23 PDT Ola Røer Thorsen wrote:
> man. 30. sep. 2019 kl. 16:48 skrev Thiago Macieira <
> 
> thiago.macie...@intel.com>:
> > It's just wrong to use it. Just like QThread::{,m,u}sleep. Don't use them.
> 
> What's wrong with the sleep functions in particular? Are they worse than
> calling for example unistd.h's "usleep" or
> "std::this_thread::sleep_for(std::chrono::milliseconds(x));"?

The problem with the sleep functions is that they sleep for an amount of time 
different than the actual amount of time that you needed to sleep for.

Note: *needed* to sleep for, not *coded* for. Pretty much any time span 
different from 0 is wrong in at least one circumstance: either you're sleeping 
too little, in which case you woke the system up early and are consuming CPU 
time and battery, or you slept too much and you delayed processing some 
incoming event. 

Usually, it's both: you wake up early, consume battery, handle no events, then 
go back to sleep. Then the event you needed to handle arrives while you're 
still sleeping.

Don't sleep with a timeout. Sleep until *exactly* your event arrives, no 
sooner and no later.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel System Software Products



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


Re: [Interest] Expected event execution order in this multi-thread application

2019-09-30 Thread Thiago Macieira
On Monday, 30 September 2019 09:35:48 PDT Uwe Rathmann wrote:
> On 9/30/19 4:43 PM, Thiago Macieira wrote:
> > It's not advisable to use nested event loops.
> 
> It is not the first time that you gave this warning, but something like
> QDialog::exec is simply too handy for GUI development.

Which is why we can't remove such functions. They're too handy.

Even if they introduce hard to debug issues because events get handled out of 
order, states change from underneath signal emitters, etc.

> And yes: issues like this one (
> https://bugreports.qt.io/browse/QTBUG-73432 ) belong to the category of
> problems that should not exist.


-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel System Software Products



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


Re: [Interest] Expected event execution order in this multi-thread application

2019-09-30 Thread Uwe Rathmann

On 9/30/19 4:43 PM, Thiago Macieira wrote:


It's not advisable to use nested event loops.


It is not the first time that you gave this warning, but something like 
QDialog::exec is simply too handy for GUI development.


Of course there are known side effects, but IMHO it should be the job of 
a GUI framework to solve them as good as possible to make the life of 
the application programming easier.


And yes: issues like this one ( 
https://bugreports.qt.io/browse/QTBUG-73432 ) belong to the category of 
problems that should not exist.


Uwe




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


Re: [Interest] Expected event execution order in this multi-thread application

2019-09-30 Thread Konstantin Shegunov
On Mon, Sep 30, 2019 at 6:07 PM Ola Røer Thorsen  wrote:

> What's wrong with the sleep functions in particular?
>

They're uninterruptible. In 99.9(9)% of cases there's a better way to
suspend a thread for some time than unconditionally putting it to sleep.


> Are they worse than calling for example unistd.h's "usleep" or
> "std::this_thread::sleep_for(std::chrono::milliseconds(x));"?
>

No.
___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] Expected event execution order in this multi-thread application

2019-09-30 Thread Ola Røer Thorsen
man. 30. sep. 2019 kl. 16:48 skrev Thiago Macieira <
thiago.macie...@intel.com>:

>
> It's just wrong to use it. Just like QThread::{,m,u}sleep. Don't use them.
>
>
What's wrong with the sleep functions in particular? Are they worse than
calling for example unistd.h's "usleep" or
"std::this_thread::sleep_for(std::chrono::milliseconds(x));"?

Cheers,
Ola
___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] Expected event execution order in this multi-thread application

2019-09-30 Thread Thiago Macieira
On Monday, 30 September 2019 01:34:25 PDT Rainer Wiesenfarth wrote:
> > [...] Anyway, this is when you should use processEvents(): never.
> 
> ...which would be a perfect reason to at least mark it as obsolete in Qt 6?

It's not obsolete. It's not broken.

It's just wrong to use it. Just like QThread::{,m,u}sleep. Don't use them.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel System Software Products



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


Re: [Interest] Expected event execution order in this multi-thread application

2019-09-30 Thread Thiago Macieira
On Monday, 30 September 2019 01:33:12 PDT Richard Weickelt wrote:
> Because I attached a debugger and stopped T1 during
> QCoreApplication::processEvents(). I can see E3 (the one that the thread is
> currently processing) in postEventList at index 0 and E2 at index 1. That's
> it. From there I see the following call chain
> QEventDispatcherGlib::processEvents() followed by emit awake() because
> canWait is false. I haven't traced it further. The signal emission doesn't
> have any consequence in the event loop though.

Can you check what happens when it calls into 
QCoreApplicationPrivate::sendPostedEvents()? That function should loop from 
data->postEventList.startOffset to data->postEventList.size() (size at the 
time you call into the function, so no new events wil be handed).

Like you said, it should be handled on the first iteration after it's been 
queued.

> > Anyway, this is when you should use processEvents(): never.
> 
> It is a public API and it is not marked as deprecated. If the function does
> not behave as documented, then either the documentation is wrong or the
> implementation has a bug or I am using it the wrong way. I don't think the
> latter is the case, but maybe I need a minimal test case to prove that.

It's not broken, that's why it's not deprecated. But that doesn't mean it's a 
good API. It's not advisable to use nested event loops. processEvents() is 
just the worst kind of nested event loops.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel System Software Products



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


Re: [Interest] Expected event execution order in this, multi-thread application

2019-09-30 Thread Roland Hughes


On 9/30/19 3:51 AM, Rainer Wiesenfarth wrote:

...which would be a perfect reason to at least mark it as obsolete in Qt 6?
It cannot be obsoleted because there is too much bad code out there 
relying on it. Bad examples doing database I/O and serial I/O within the 
main event loop, etc.


I strongly second Thiago's recommendation: processEvents() usually
introduces more problems than it solves.


--
Roland Hughes, President
Logikal Solutions
(630)-205-1593

http://www.theminimumyouneedtoknow.com
http://www.infiniteexposure.net
http://www.johnsmith-book.com
http://www.logikalblog.com
http://www.interestingauthors.com/blog

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


Re: [Interest] Expected event execution order in this multi-thread application

2019-09-30 Thread Vasily Pupkin
>> - E2 is sitting in the event queue of T1 at the second position but gets
>> never executed.

Use combination of

  QCoreApplication::sendPostedEvents();
  QCoreApplication::processEvents();


.


пн, 30 сент. 2019 г. в 11:37, Rainer Wiesenfarth <
rainer_wiesenfa...@trimble.com>:

> On Mon, Sep 30, 2019 at 9:26 AM Thiago Macieira 
> wrote:
>
>> [...] Anyway, this is when you should use processEvents(): never.
>>
>
> ...which would be a perfect reason to at least mark it as obsolete in Qt 6?
>
> I strongly second Thiago's recommendation: processEvents() usually
> introduces more problems than it solves.
>
> --
> Software Engineer | Trimble Imaging Division
> Rotebühlstraße 81 | 70178 Stuttgart | Germany
> Office +49 711 22881 0 | Fax +49 711 22881 11
> http://www.trimble.com/imaging/ | http://www.inpho.de/
>
> Trimble Germany GmbH, Am Prime Parc 11, 65479 Raunheim
> Eingetragen beim Amtsgericht Darmstadt unter HRB 83893,
> Geschäftsführer: Dr. Frank Heimberg, Jürgen Kesper
> ___
> Interest mailing list
> Interest@qt-project.org
> https://lists.qt-project.org/listinfo/interest
>
___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] Expected event execution order in this multi-thread application

2019-09-30 Thread Rainer Wiesenfarth
On Mon, Sep 30, 2019 at 9:26 AM Thiago Macieira 
wrote:

> [...] Anyway, this is when you should use processEvents(): never.
>

...which would be a perfect reason to at least mark it as obsolete in Qt 6?

I strongly second Thiago's recommendation: processEvents() usually
introduces more problems than it solves.

-- 
Software Engineer | Trimble Imaging Division
Rotebühlstraße 81 | 70178 Stuttgart | Germany
Office +49 711 22881 0 | Fax +49 711 22881 11
http://www.trimble.com/imaging/ | http://www.inpho.de/

Trimble Germany GmbH, Am Prime Parc 11, 65479 Raunheim
Eingetragen beim Amtsgericht Darmstadt unter HRB 83893,
Geschäftsführer: Dr. Frank Heimberg, Jürgen Kesper
___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] Expected event execution order in this multi-thread application

2019-09-30 Thread Richard Weickelt
>> - Thread T1 is handling an event E1
>> - Thread T1 sends E3 to itself (queued connection)
>> - Thread T2 sends an event E2 to T1 (queued connection)
>> - Thread T1 handles E3 after completing E1.
>> - Thread T1 while handling E3 calls QCoreApplication::processEvents()
>> periodically
>> - E2 is sitting in the event queue of T1 at the second position but gets
>> never executed.
> 
> How do you know that? 

Because I attached a debugger and stopped T1 during 
QCoreApplication::processEvents(). I can see E3 (the one that the thread is 
currently processing) in postEventList at index 0 and E2 at index 1. That's it. 
From there I see the following call chain QEventDispatcherGlib::processEvents() 
followed by emit awake() because canWait is false. I haven't traced it further. 
The signal emission doesn't have any consequence in the event loop though.

> There's still a lack of synchronisation between T1 
> calling processEvents() and T2 posting the event. What if the event was 
> posted 
> after you called it?

Then I would expect the event to be handled by the next invocation of 
QCoreApplication::processEvents().
 
> Anyway, DON'T use processEvents(). Redesign your code.

It's unfortunately QScriptEngine which calls this method, triggered by a 
periodic timer. The application is Qbs and it is 
blackboxtest::concurrentExecution which triggers that behavior. It processes a 
long-running script that expects a file to appear in the file system produced 
by another thread. But for this to happen, the current execution thread needs 
to handle events. The testcase usually behaves as expected, but in rare cases 
it doesn't and that is what I am currently investigating. 
https://bugreports.qt.io/browse/QBS-1499 Before I suggest an action, I want to 
understand the error.

>> Sure, but I don't see a synchronization problem as long if
>> QCoreApplication::processEvents() would do what the documentation says:
>> executing pending events in the current thread. Am I misunderstanding
>> something?
> 
> ALREADY pending events.

Yeah, sure, but I have already said that QCoreApplication::processEvents() is 
called periodically. I don't care on which invocation E2 is handled.

> Anyway, this is when you should use processEvents(): never.

It is a public API and it is not marked as deprecated. If the function does not 
behave as documented, then either the documentation is wrong or the 
implementation has a bug or I am using it the wrong way. I don't think the 
latter is the case, but maybe I need a minimal test case to prove that.

Best regards
Richard

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


Re: [Interest] Expected event execution order in this multi-thread application

2019-09-30 Thread Thiago Macieira
On Sunday, 29 September 2019 22:51:57 PDT Richard Weickelt wrote:
> After debugging a bit, I come to realize that my above description is
> incorrect.
> 
> - Thread T1 is handling an event E1
> - Thread T1 sends E3 to itself (queued connection)
> - Thread T2 sends an event E2 to T1 (queued connection)
> - Thread T1 handles E3 after completing E1.
> - Thread T1 while handling E3 calls QCoreApplication::processEvents()
> periodically
> - E2 is sitting in the event queue of T1 at the second position but gets
> never executed.

How do you know that? There's still a lack of synchronisation between T1 
calling processEvents() and T2 posting the event. What if the event was posted 
after you called it?

Anyway, DON'T use processEvents(). Redesign your code.

> I think my question was misleading. I am not so much interested in the order
> of arrival, but rather in "when" E2 gets executed by T1. I am fine with any
> arrival order and start of execution as long as
> QCoreApplication::processEvents() executes pending events while E3 is
> running. But that is not the case in above scenario. E2 is such a pending
> event, yet it doesn't get executed.

processEvents() does not process events posted after it started. It may want 
for new timers and socket notifications, but not for new events.

> > The solution is to take a look at your threading code and see if you need
> > a
> > synchronisation.
> 
> Sure, but I don't see a synchronization problem as long if
> QCoreApplication::processEvents() would do what the documentation says:
> executing pending events in the current thread. Am I misunderstanding
> something?

ALREADY pending events.

Anyway, this is when you should use processEvents(): never.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel System Software Products



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


Re: [Interest] Expected event execution order in this multi-thread application

2019-09-29 Thread Richard Weickelt
>> what is the expected event execution order in the following scenario?
>>
>> - 2 Threads running their event loop
>> - Thread T1 is handling an event E1
>> - Thread T2 sends an event E2 to T1 (queued)
>> - Thread T1 (still handling E1) emits an event E3 to itself (direct) after
>> E2 has already been enqueued.
> 
> You did not describe a happens-before relationship between the sending of 
> events E2 and E3. So the order of either is unspecified.
> 
>> - E3 is a very long-running event. To prevent events from starving, T1 calls
>> QCoreApplication::processEvents() periodically.
>>
>> Observed behaviour:
>> - E3 gets immediately executed
>> - E2 is executed after E3/E1 have completed
> 
> Because you didn't force a E2 to be queued before E3. So the order of the 
> events in the T1 queue may have been E1-E3-E2.

After debugging a bit, I come to realize that my above description is incorrect.

- Thread T1 is handling an event E1
- Thread T1 sends E3 to itself (queued connection)
- Thread T2 sends an event E2 to T1 (queued connection)
- Thread T1 handles E3 after completing E1.
- Thread T1 while handling E3 calls QCoreApplication::processEvents()
periodically
- E2 is sitting in the event queue of T1 at the second position but gets
never executed.

I think my question was misleading. I am not so much interested in the order
of arrival, but rather in "when" E2 gets executed by T1. I am fine with any
arrival order and start of execution as long as
QCoreApplication::processEvents() executes pending events while E3 is
running. But that is not the case in above scenario. E2 is such a pending
event, yet it doesn't get executed.

> The solution is to take a look at your threading code and see if you need a 
> synchronisation.

Sure, but I don't see a synchronization problem as long if
QCoreApplication::processEvents() would do what the documentation says:
executing pending events in the current thread. Am I misunderstanding something?

Richard
___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] Expected event execution order in this multi-thread application

2019-09-29 Thread Thiago Macieira
On Sunday, 29 September 2019 02:49:36 PDT Richard Weickelt wrote:
> Hello,
> 
> what is the expected event execution order in the following scenario?
> 
> - 2 Threads running their event loop
> - Thread T1 is handling an event E1
> - Thread T2 sends an event E2 to T1 (queued)
> - Thread T1 (still handling E1) emits an event E3 to itself (direct) after
> E2 has already been enqueued.

You did not describe a happens-before relationship between the sending of 
events E2 and E3. So the order of either is unspecified.

> - E3 is a very long-running event. To prevent events from starving, T1 calls
> QCoreApplication::processEvents() periodically.
> 
> Observed behaviour:
> - E3 gets immediately executed
> - E2 is executed after E3/E1 have completed

Because you didn't force a E2 to be queued before E3. So the order of the 
events in the T1 queue may have been E1-E3-E2.

> Is this behavior expected? I would expected E2 being executed at least on
> the first invocation of QCoreApplication::processEvents(), but apparently it
> sits in the event queue until T1 returns from E3 (and also E1).

It's expected from your description. It's not the only possibility, though, 
since the order is unspecified.

> In my scenario E2 is rather short and E3 expectes something from E2 in order
> to complete. So I run into a deadlock here.
> 
> Would it be a solution to handle E3 in a queued connection? In case E2 is
> posted after E3 has started, would E2 be executed by processEvents()?

The solution is to take a look at your threading code and see if you need a 
synchronisation.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel System Software Products



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


Re: [Interest] Expected event execution order in this, multi-thread application

2019-09-29 Thread Roland Hughes


On 9/29/19 5:00 AM, Richard Weickelt wrote:

what is the expected event execution order in the following scenario?

- 2 Threads running their event loop
- Thread T1 is handling an event E1
- Thread T2 sends an event E2 to T1 (queued)
- Thread T1 (still handling E1) emits an event E3 to itself (direct) after
E2 has already been enqueued.
- E3 is a very long-running event. To prevent events from starving, T1 calls
QCoreApplication::processEvents() periodically.

Observed behaviour:
- E3 gets immediately executed
- E2 is executed after E3/E1 have completed

Is this behavior expected? I would expected E2 being executed at least on
the first invocation of QCoreApplication::processEvents(), but apparently it
sits in the event queue until T1 returns from E3 (and also E1).

In my scenario E2 is rather short and E3 expectes something from E2 in order
to complete. So I run into a deadlock here.

Would it be a solution to handle E3 in a queued connection? In case E2 is
posted after E3 has started, would E2 be executed by processEvents()?


Non-queued connections are basically local function calls. You would 
have to force a queued connection, but you still could not reliably get 
your design to work. You have a sequential problem where steps must 
occur in a given order but may require differing amounts of time. In 
effect you are trying to do this without having a full Application 
Control Management System.


http://h30266.www3.hpe.com/odl/vax/databases/acms45/6604/6604pro.html

You really need to split this into restartable units of work and utilize 
an external queing agent.


This solution hasn't properly utilized stepwise refinement. T1 _cannot_ 
issue E3 until there is a pending E2, but it does, so this logic isn't 
properly broken down. Without knowing what your application is or 
anything more than these BASIC (the language, not a shout) variable 
names, here's the 5 minute architect job.


*) Forget events. Wrong tool for this job. Having said that, you are 
using Qt and probably unwilling to code the necessary architecture so we 
will attempt to make them work. You really should use a message queing 
system for this if not a full blown ACMS.


*)  T1  = your T1   T2 = your T2   T3 = Control Thread (possibly main 
event loop)


T1 chews on whatever it chews on. When it gets to the state of issuing 
the previous E3 it sends a T1-TASK-COMPLETE message to the control thread.


T2 chews on whatever it chews on. When it gets to the state of issuing 
the previous E3 it sends a T2-TASK-COMPLETE message to control thread.


T3 receives one or more TASK-COMPLETE messages and first records them 
into some form of data store. Then it checks via some kind of key/id or 
something if it has a matching T1-TASK-COMPLETE and T2-TASK-COMPLETE. If 
so, it combines whatever data is in the "complete" messages and launches 
what was previously E3, preferably in its own thread.


Each "task" must be designed so it can run flat out without dependencies 
from other tasks. Your control task, depending on the required 
granularity could even be split into CONTROL-STORE and CONTROL-DISPATCH 
with the dispatch portion being triggered each time a store completes to 
search for matching completed tasks so the next task can be launched.


If you don't have a hardware (serial port or some other kind of polling 
device) or database involved in T1 I would be very worried about having 
to call QCoreApplication::processEvents(). If one is doing database I/O 
in the main event loop you could easily need to do this for a large 
cursor of data, but you are in a thread or at least this description is.


--
Roland Hughes, President
Logikal Solutions
(630)-205-1593

http://www.theminimumyouneedtoknow.com
http://www.infiniteexposure.net
http://www.johnsmith-book.com
http://www.logikalblog.com
http://www.interestingauthors.com/blog

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


[Interest] Expected event execution order in this multi-thread application

2019-09-29 Thread Richard Weickelt
Hello,

what is the expected event execution order in the following scenario?

- 2 Threads running their event loop
- Thread T1 is handling an event E1
- Thread T2 sends an event E2 to T1 (queued)
- Thread T1 (still handling E1) emits an event E3 to itself (direct) after
E2 has already been enqueued.
- E3 is a very long-running event. To prevent events from starving, T1 calls
QCoreApplication::processEvents() periodically.

Observed behaviour:
- E3 gets immediately executed
- E2 is executed after E3/E1 have completed

Is this behavior expected? I would expected E2 being executed at least on
the first invocation of QCoreApplication::processEvents(), but apparently it
sits in the event queue until T1 returns from E3 (and also E1).

In my scenario E2 is rather short and E3 expectes something from E2 in order
to complete. So I run into a deadlock here.

Would it be a solution to handle E3 in a queued connection? In case E2 is
posted after E3 has started, would E2 be executed by processEvents()?

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