From 95b6826ed47b0341d21b631712c65f895b4c38e0 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 12 Jul 2012 21:54:41 +0200 Subject: statemachine: Make signal transition registration thread-safe Since Qt's connections are thread-safe, QStateMachine's plumbing around them should be thread-safe too. Change-Id: I8ae91c2edc2d32ca4ed4258b71e5da22de30ed91 Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../qstatemachine/tst_qstatemachine.cpp | 50 ++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp index 8c67c0ec03..77dc8dd1cc 100644 --- a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp @@ -209,6 +209,7 @@ private slots: void createSignalTransitionWhenRunning(); void createEventTransitionWhenRunning(); void signalTransitionSenderInDifferentThread(); + void signalTransitionRegistrationThreadSafety(); }; class TestState : public QState @@ -4884,5 +4885,54 @@ void tst_QStateMachine::signalTransitionSenderInDifferentThread() QTRY_VERIFY(thread.wait()); } +class SignalTransitionMutatorThread : public QThread +{ +public: + SignalTransitionMutatorThread(QSignalTransition *transition) + : m_transition(transition) + {} + void run() + { + // Cause repeated registration and unregistration + for (int i = 0; i < 50000; ++i) { + m_transition->setSenderObject(this); + m_transition->setSenderObject(0); + } + } +private: + QSignalTransition *m_transition; +}; + +// Should not crash: +void tst_QStateMachine::signalTransitionRegistrationThreadSafety() +{ + QStateMachine machine; + QState *s1 = new QState(&machine); + machine.setInitialState(s1); + machine.start(); + QTRY_VERIFY(machine.configuration().contains(s1)); + + QSignalTransition *t1 = new QSignalTransition(); + t1->setSignal(SIGNAL(objectNameChanged(QString))); + s1->addTransition(t1); + + QSignalTransition *t2 = new QSignalTransition(); + t2->setSignal(SIGNAL(objectNameChanged(QString))); + s1->addTransition(t2); + + SignalTransitionMutatorThread thread(t1); + thread.start(); + QTRY_VERIFY(thread.isRunning()); + + // Cause repeated registration and unregistration + for (int i = 0; i < 50000; ++i) { + t2->setSenderObject(this); + t2->setSenderObject(0); + } + + thread.quit(); + QTRY_VERIFY(thread.wait()); +} + QTEST_MAIN(tst_QStateMachine) #include "tst_qstatemachine.moc" -- cgit v1.2.3