summaryrefslogtreecommitdiffstats
path: root/src/corelib/statemachine/qstatemachine_p.h
diff options
context:
space:
mode:
authorKent Hansen <kent.hansen@nokia.com>2012-06-04 21:51:04 +0200
committerQt by Nokia <qt-info@nokia.com>2012-06-06 13:27:32 +0200
commit302e6968f1152d5dee8d5debafb313bd53fa55ff (patch)
tree983df82f4846fd042efec5979dc0c46d8c85d31c /src/corelib/statemachine/qstatemachine_p.h
parentfc15a1d5e2cb064df7b6e7b9e821e9db20a91b85 (diff)
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>
Diffstat (limited to 'src/corelib/statemachine/qstatemachine_p.h')
-rw-r--r--src/corelib/statemachine/qstatemachine_p.h15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h
index d01b050e15..ae5660719f 100644
--- a/src/corelib/statemachine/qstatemachine_p.h
+++ b/src/corelib/statemachine/qstatemachine_p.h
@@ -62,6 +62,7 @@
#include <QtCore/qpair.h>
#include <QtCore/qset.h>
#include <QtCore/qvector.h>
+#include <private/qfreelist_p.h>
QT_BEGIN_NAMESPACE
@@ -120,6 +121,8 @@ public:
#ifndef QT_NO_ANIMATION
void _q_animationFinished();
#endif
+ void _q_startDelayedEventTimer(int id, int delay);
+ void _q_killDelayedEventTimer(int id, int timerId);
QState *rootState() const;
@@ -232,7 +235,17 @@ public:
#ifndef QT_NO_STATEMACHINE_EVENTFILTER
QHash<QObject*, QHash<QEvent::Type, int> > qobjectEvents;
#endif
- QHash<int, QEvent*> delayedEvents;
+ QFreeList<void> delayedEventIdFreeList;
+ struct DelayedEvent {
+ QEvent *event;
+ int timerId;
+ DelayedEvent(QEvent *e, int tid)
+ : event(e), timerId(tid) {}
+ DelayedEvent()
+ : event(0), timerId(0) {}
+ };
+ QHash<int, DelayedEvent> delayedEvents;
+ QHash<int, int> timerIdToDelayedEventId;
QMutex delayedEventsMutex;
typedef QEvent* (*f_cloneEvent)(QEvent*);