QTimer doesn't stop on calling stop()
-
First please post the actual code which really runs - your code above does not compile at all. Then please minimize your code so we can run it also. Since it's crashing in process() - what does this function do?
When you call stop() then the timer stops - except you call it from another thread then you will get a runtime warning.
-
@Christian-Ehrlicher This is actually part of a larger program. Let me see if I can strip it, but I am not too sure if the problem is with the timer or I am getting an incorrect stack trace. The
process
method copiesProbes
that have timed out to aQList
. The problem is that even iftimeoutFired
gets called,m_pending
is empty at that point and all that code should have been skipped including the for-loop. If I add logs in thetimeoutFired
method then they don't get printed in the invocation where it crashes which makes me doubtful that it was called.Also, the program is single-threaded.
-
I experienced that the (last) pending event can be fired despite the timer is stopped !
-
@mpergand said in QTimer doesn't stop on calling stop():
I experienced that the (last) pending event can be fired despite the timer is stopped !
Only when the event is already in the event queue.
-
@Christian-Ehrlicher said in QTimer doesn't stop on calling stop():
Only when the event is already in the event queue.
Correct, could be problematic.
-
@Christian-Ehrlicher Is this possible with a direct connection? Even then it doesn't explain why the logs are not getting printed. I also tried setting a debugger breakpoint but it is also not working for the invocation where it crashes.
-
@schrute said in QTimer doesn't stop on calling stop():
Is this possible with a direct connection?
I don't see what this has to do with the connection. We were talking about the fact that you call stop() within a slot while in the Qt event queue the timer event is already added. Then the slot might get called but I'm unsure about it. You have to read the source code wrt this to be really sure. But I doubt this is your problem.
-
@schrute
As @Christian-Ehrlicher said,QTimer::timeout
can be posted before and delivered after the timer was stopped.
QTimer::stop()
removes the timer synchronously, which means no more signals are emitted from that moment.
Disconnecting a driver when no longer used, is never a bad idea. That could be implemented in a small functionstopTimer()
. However, it does not prevent previously emitted signals from being delivered.
Theactive
property should normally be synchronous, but I am not sure if it can leak a bit behind (it's a computed property and not a simple bool).In
void timeoutFired()
,QTimer::isActive()
is used as a proxy assertion thatm_pending
has content.
That's a like hazarding a bet that nobody is home, because the doorbell remains unanswered. The proxy assertion bet is lost, when the inhabitant was stuck on the loo ;-) It may be better to checkm_pending
directly:void timeoutFired() { if (m_pending.isEmpty()) { qDebug() << __FUNCTION__ << "without probes"; return; } qDebug() << __FUNCTION << "with" << m_pending.count() << "probes"; auto pivot = std::partition(m_pending.begin(), m_pending.end(), [this](const Probe& probe) { return !probe.expired; }); for (auto it = pivot; it != m_pending.end(); ++it) { process(*it); } m_pending.resize(std::distance(m_pending.begin(), pivot)); }
If I add logs in the timeoutFired method then they don't get printed in the invocation where it crashes which makes me doubtful that it was called.
The stack trace is clear about
timeoutFired
being the crime scene. So either the source with theqDebug()
is newer than the binary or the crash kicks in beforeqDebug()
has had time to speak up. -
@Axel-Spoerl The issue was with my build setup. After a clean build the debugger started behaving properly and I was able to resolve the crash.