[Development] [fix]: Assistant (and others) burning CPU because of #f27d1ccbb24ec2fd4098f2976503478831006cc8 ?

René J. V. Bertin rjvbertin at gmail.com
Thu Aug 31 10:35:08 CEST 2017


Thiago Macieira wrote:

>> I guess so :) I still don't get what purpose calling QObject::timerEvent()
>> has if the method itself does nothing. Gives me something to ponder.
> 
> Again, that's what makes QTimer possible.
> 
> void QTimer::timerEvent(QTimerEvent *e)
> {
>     if (e->timerId() == id) {
>         if (single)
>             stop();
>         emit timeout(QPrivateSignal());
>     }
> }

That's QTimer's override of QObject::timerEvent(), from kernel/qtimer.cpp . What 
I thought of was a simple security for classes that inherit QObject but don't 
override timerEvent(), something like this:

void QObject::timerEvent(QTimerEvent *e)
{
    if (m_timerInterval == 0 && e->timerId() == m_timerId) {
        killTimer(m_timerId);
    }
}

I see now that's not as trivial as I though since a single QObject can have any 
number of associated timers (at some level I knew that of course). 

> This is the same as any event override in Qt, which is basically the same as
> any virtual function override in C++. The overriding function gets to decide
> whether it needs to call the base implementation for something.
> 
> QObject::timerEvent does nothing, but other QObject::xxxEvent functions might,
> ditto for QWidget::xxxEvent().

Exactly. 

> Source compatibility. Which is why it's unlikely we'll do it.

Qt6 isn't going to break anything that builds against a sufficiently recent Qt5 
version?

>> class QFoo : public QObject, public QObjectTimer

> That said, it's not a horrible idea to move this out of QObject.

There are of course those who are horrified by the concept of multiple 
inheritance but it looks a bit late to start worrying about that :)

>> I did try monitoring the process with Instruments but that failed to attach.
> 
> But how did you find out it was a timer? And that it was a timer in
> QCocoaMenu?

Well, that's because I knew I had changed nothing else used by the offending 
application. Remember, I just merged upstream changes to the Cocoa QPA into my 
own standalone copy so this time that little project of mine really served a 
foolproofing purpose. It was trivial to put back the previous version of the 
plugin, start the application and confirm that it didn't show the issue. Then I 
just had to bisect. To be honest, looking at the commit log I had already 
deduced that it could in fact only be this change (I've written my own timers in 
the past). I'd have saved myself a lot of time if I hadn't decided to be clever 
but instead put qInfo probes at each and every turn of the new code.

Come to think of it, it's actually logical that a timer with interval=0 can take 
up all available resources ... when the event loop is idle. Gives a new 
interpretation to the term busy-waiting. I wonder if it could be put to good use 
in applications that must always react in "realtime" to user input, no matter 
how much change the application has had to be swapped out, demoted etc.

(All this reminded me of a fantasy novel I read long ago, involving a kind of 
flywheel capable of eating up all magical manna in the area by just spinning ever 
faster. Can't remember the title, pity.)

R.




More information about the Development mailing list