statemachine: Make delayed event posting work from secondary thread
authorKent Hansen <kent.hansen@nokia.com>
Mon, 4 Jun 2012 19:51:04 +0000 (21:51 +0200)
committerQt by Nokia <qt-info@nokia.com>
Wed, 6 Jun 2012 11:27:32 +0000 (13:27 +0200)
commit302e6968f1152d5dee8d5debafb313bd53fa55ff
tree983df82f4846fd042efec5979dc0c46d8c85d31c
parentfc15a1d5e2cb064df7b6e7b9e821e9db20a91b85
statemachine: Make delayed event posting work from secondary thread

postDelayedEvent() and cancelDelayedEvent() are marked as thread-safe
in the documentation. Unfortunately, they didn't actually work when
called from another thread; they just produced some warnings:

QObject::startTimer: timers cannot be started from another thread
QObject::killTimer: timers cannot be stopped from another thread

As the warnings indicate, the issue was that postDelayedEvent()
(cancelDelayedEvent()) unconditionally called QObject::startTimer()
(stopTimer()), i.e. without considering which thread the function
was called from.

If the function is called from a different thread, the actual
starting/stopping of the associated timer is now done from the
correct thread, by asynchronously calling a private slot on the
state machine.

This also means that the raw timer id can no longer be used as the
id of the delayed event, since a valid event id must be returned
before the timer has started. The state machine now manages those
ids itself (using a QFreeList, just like startTimer() and
killTimer() do), and also keeps a mapping from timer id to event
id once the timer has been started. This is inherently more complex
than before, but at least the API should work as advertised/intended
now.

Task-number: QTBUG-17975
Change-Id: I3a866d01dca23174c8841112af50b87141df0943
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>
src/corelib/statemachine/qstatemachine.cpp
src/corelib/statemachine/qstatemachine.h
src/corelib/statemachine/qstatemachine_p.h
tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp