summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2015-11-18 13:51:58 (GMT)
committerSwift Review <review@swift.im>2015-11-19 15:32:04 (GMT)
commitfcf6a898de9c4f89db5de686aa203b3a52c18029 (patch)
tree4df426d92600eba8d4d60a88faaff1d5839129b0 /Swiften/EventLoop/Qt
parentcda6fd478b3d8f7f30f771b18324db389a01b1b3 (diff)
downloadswift-fcf6a898de9c4f89db5de686aa203b3a52c18029.zip
swift-fcf6a898de9c4f89db5de686aa203b3a52c18029.tar.bz2
Redesign event loops to be thread-safe and deterministic
The new event loop design has a single event queue that is synchronized to protect against data races. The removal of events in the queue by EventOwner is deterministic. Test-Information: All unit and integration tests with TSAN and cxxflags=-DBOOST_SP_USE_PTHREADS on Debian 8.2 pass without reports. Multiple Swiften/QA/ClientTest/ClientTest runs under different CPU stress caused no TSAN reports on Debian 8.2. Swift itself only causes TSAN reports related to Qt itself, out of our control, and most likely false positives, i.e. TSAN not detecting the synchronization method inside Qt correctly. Unit tests pass without errors and successfully connected to Slimber on OS X 10.10.5. Change-Id: Ia1ed32ac2e758c5b9f86e0dac21362818740881e
Diffstat (limited to 'Swiften/EventLoop/Qt')
-rw-r--r--Swiften/EventLoop/Qt/QtEventLoop.h32
1 files changed, 22 insertions, 10 deletions
diff --git a/Swiften/EventLoop/Qt/QtEventLoop.h b/Swiften/EventLoop/Qt/QtEventLoop.h
index 0e048e5..389b0a7 100644
--- a/Swiften/EventLoop/Qt/QtEventLoop.h
+++ b/Swiften/EventLoop/Qt/QtEventLoop.h
@@ -6,28 +6,39 @@
#pragma once
-#include <QObject>
-#include <QEvent>
+#include <boost/thread.hpp>
+
#include <QCoreApplication>
+#include <QEvent>
+#include <QObject>
#include <Swiften/EventLoop/EventLoop.h>
namespace Swift {
class QtEventLoop : public QObject, public EventLoop {
public:
- QtEventLoop() {}
+ QtEventLoop() : isEventInQtEventLoop_(false) {}
virtual ~QtEventLoop() {
QCoreApplication::removePostedEvents(this);
}
- virtual void post(const Swift::Event& event) {
- QCoreApplication::postEvent(this, new Event(event));
+ protected:
+ virtual void eventPosted() {
+ boost::recursive_mutex::scoped_lock lock(isEventInQtEventLoopMutex_);
+ if (!isEventInQtEventLoop_) {
+ isEventInQtEventLoop_ = true;
+ QCoreApplication::postEvent(this, new Event());
+ }
}
virtual bool event(QEvent* qevent) {
Event* event = dynamic_cast<Event*>(qevent);
if (event) {
- handleEvent(event->event_);
+ {
+ boost::recursive_mutex::scoped_lock lock(isEventInQtEventLoopMutex_);
+ isEventInQtEventLoop_ = false;
+ }
+ handleNextEvent();
//event->deleteLater(); FIXME: Leak?
return true;
}
@@ -37,11 +48,12 @@ namespace Swift {
private:
struct Event : public QEvent {
- Event(const Swift::Event& event) :
- QEvent(QEvent::User), event_(event) {
+ Event() :
+ QEvent(QEvent::User) {
}
-
- Swift::Event event_;
};
+
+ bool isEventInQtEventLoop_;
+ boost::recursive_mutex isEventInQtEventLoopMutex_;
};
}