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/EventLoop.h
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/EventLoop.h')
-rw-r--r--Swiften/EventLoop/EventLoop.h41
1 files changed, 31 insertions, 10 deletions
diff --git a/Swiften/EventLoop/EventLoop.h b/Swiften/EventLoop/EventLoop.h
index e64ff35..54e0fe7 100644
--- a/Swiften/EventLoop/EventLoop.h
+++ b/Swiften/EventLoop/EventLoop.h
@@ -1,15 +1,15 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2015 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <list>
+
#include <boost/function.hpp>
#include <boost/thread.hpp>
-#include <list>
-#include <deque>
#include <Swiften/Base/API.h>
#include <Swiften/EventLoop/Event.h>
@@ -17,28 +17,49 @@
namespace Swift {
class EventOwner;
+ /**
+ * The \ref EventLoop class provides the abstract interface for implementing event loops to use with Swiften.
+ *
+ * Events are added to the event queue using the \ref postEvent method and can be removed from the queue using
+ * the \ref removeEventsFromOwner method.
+ */
class SWIFTEN_API EventLoop {
public:
EventLoop();
virtual ~EventLoop();
+ /**
+ * The \ref postEvent method allows events to be added to the event queue of the \ref EventLoop.
+ * An optional \ref EventOwner can be passed, allowing later removal of events that have not yet been
+ * executed using the \ref removeEventsFromOwner method.
+ */
void postEvent(boost::function<void ()> event, boost::shared_ptr<EventOwner> owner = boost::shared_ptr<EventOwner>());
+
+ /**
+ * The \ref removeEventsFromOwner method removes all events from the specified \ref owner from the
+ * event queue.
+ */
void removeEventsFromOwner(boost::shared_ptr<EventOwner> owner);
protected:
/**
- * Reimplement this to call handleEvent(event) from the thread in which
- * the event loop is residing.
+ * The \ref handleNextEvent method is called by an implementation of the abstract \ref EventLoop class
+ * at any point after the virtual \ref eventPosted method has been called.
+ * This method does not block, except for short-time synchronization.
*/
- virtual void post(const Event& event) = 0;
+ void handleNextEvent();
- void handleEvent(const Event& event);
+ /**
+ * The \ref eventPosted virtual method serves as notification for when events are still available in the queue.
+ * It is called after the first event is posted to an empty queue or after an event has been handled in
+ * \ref handleNextEvent and there are still remaining events in the queue.
+ */
+ virtual void eventPosted() = 0;
private:
- boost::mutex eventsMutex_;
unsigned int nextEventID_;
std::list<Event> events_;
- bool handlingEvents_;
- std::deque<Event> eventsToHandle_;
+ boost::recursive_mutex eventsMutex_;
+ boost::recursive_mutex removeEventsMutex_;
};
}