summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/EventLoop')
-rw-r--r--Swiften/EventLoop/Cocoa/CocoaEvent.h4
-rw-r--r--Swiften/EventLoop/Cocoa/CocoaEvent.mm13
-rw-r--r--Swiften/EventLoop/Cocoa/CocoaEventLoop.h14
-rw-r--r--Swiften/EventLoop/Cocoa/CocoaEventLoop.mm34
-rw-r--r--Swiften/EventLoop/DummyEventLoop.cpp22
-rw-r--r--Swiften/EventLoop/DummyEventLoop.h42
-rw-r--r--Swiften/EventLoop/EventLoop.cpp77
-rw-r--r--Swiften/EventLoop/EventLoop.h41
-rw-r--r--Swiften/EventLoop/Qt/QtEventLoop.h32
-rw-r--r--Swiften/EventLoop/SimpleEventLoop.cpp40
-rw-r--r--Swiften/EventLoop/SimpleEventLoop.h14
-rw-r--r--Swiften/EventLoop/SingleThreadedEventLoop.cpp37
-rw-r--r--Swiften/EventLoop/SingleThreadedEventLoop.h12
13 files changed, 206 insertions, 176 deletions
diff --git a/Swiften/EventLoop/Cocoa/CocoaEvent.h b/Swiften/EventLoop/Cocoa/CocoaEvent.h
index dc38f7f..4453c74 100644
--- a/Swiften/EventLoop/Cocoa/CocoaEvent.h
+++ b/Swiften/EventLoop/Cocoa/CocoaEvent.h
@@ -9,7 +9,6 @@
#include <Foundation/Foundation.h>
namespace Swift {
- class Event;
class CocoaEventLoop;
}
@@ -19,14 +18,13 @@ namespace Swift {
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
@interface CocoaEvent : NSObject {
- Swift::Event* event;
Swift::CocoaEventLoop* eventLoop;
}
#pragma clang diagnostic pop
// Takes ownership of event
-- (id) initWithEvent: (Swift::Event*) e eventLoop: (Swift::CocoaEventLoop*) el;
+- (id) init:(Swift::CocoaEventLoop*) el;
- (void) process;
- (void) dealloc;
diff --git a/Swiften/EventLoop/Cocoa/CocoaEvent.mm b/Swiften/EventLoop/Cocoa/CocoaEvent.mm
index 7b1b4b0..4f72c29 100644
--- a/Swiften/EventLoop/Cocoa/CocoaEvent.mm
+++ b/Swiften/EventLoop/Cocoa/CocoaEvent.mm
@@ -1,24 +1,27 @@
+/*
+ * Copyright (c) 2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#include <Swiften/EventLoop/Cocoa/CocoaEvent.h>
-#include <Swiften/EventLoop/Event.h>
#include <Swiften/EventLoop/Cocoa/CocoaEventLoop.h>
@implementation CocoaEvent
-- (id) initWithEvent: (Swift::Event*) e eventLoop: (Swift::CocoaEventLoop*) el {
+- (id) init:(Swift::CocoaEventLoop*) el {
self = [super init];
if (self != nil) {
- event = e;
eventLoop = el;
}
return self;
}
- (void) process {
- eventLoop->handleEvent(*event);
+ eventLoop->handleNextCocoaEvent();
}
- (void) dealloc {
- delete event;
[super dealloc];
}
diff --git a/Swiften/EventLoop/Cocoa/CocoaEventLoop.h b/Swiften/EventLoop/Cocoa/CocoaEventLoop.h
index ee33fbb..aad6b0a 100644
--- a/Swiften/EventLoop/Cocoa/CocoaEventLoop.h
+++ b/Swiften/EventLoop/Cocoa/CocoaEventLoop.h
@@ -1,20 +1,28 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2015 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <boost/thread.hpp>
+
#include <Swiften/EventLoop/EventLoop.h>
namespace Swift {
class CocoaEventLoop : public EventLoop {
public:
CocoaEventLoop();
+ virtual ~CocoaEventLoop();
- virtual void post(const Event& event);
+ void handleNextCocoaEvent();
+
+ protected:
+ virtual void eventPosted();
- using EventLoop::handleEvent;
+ private:
+ bool isEventInCocoaEventLoop_;
+ boost::recursive_mutex isEventInCocoaEventLoopMutex_;
};
}
diff --git a/Swiften/EventLoop/Cocoa/CocoaEventLoop.mm b/Swiften/EventLoop/Cocoa/CocoaEventLoop.mm
index ba73884..88da262 100644
--- a/Swiften/EventLoop/Cocoa/CocoaEventLoop.mm
+++ b/Swiften/EventLoop/Cocoa/CocoaEventLoop.mm
@@ -1,3 +1,9 @@
+/*
+ * Copyright (c) 2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#include <Swiften/EventLoop/Cocoa/CocoaEventLoop.h>
#include <Swiften/EventLoop/Cocoa/CocoaEvent.h>
@@ -5,17 +11,33 @@
namespace Swift {
-CocoaEventLoop::CocoaEventLoop() {
+CocoaEventLoop::CocoaEventLoop() : isEventInCocoaEventLoop_(false) {
+}
+
+CocoaEventLoop::~CocoaEventLoop() {
+
+}
+
+void CocoaEventLoop::handleNextCocoaEvent() {
+ {
+ boost::recursive_mutex::scoped_lock lock(isEventInCocoaEventLoopMutex_);
+ isEventInCocoaEventLoop_ = false;
+ }
+ handleNextEvent();
}
-void CocoaEventLoop::post(const Event& event) {
- Event* eventCopy = new Event(event);
- CocoaEvent* cocoaEvent = [[CocoaEvent alloc] initWithEvent: eventCopy eventLoop: this];
- [cocoaEvent
+void CocoaEventLoop::eventPosted() {
+ boost::recursive_mutex::scoped_lock lock(isEventInCocoaEventLoopMutex_);
+ if (!isEventInCocoaEventLoop_) {
+ isEventInCocoaEventLoop_ = true;
+
+ CocoaEvent* cocoaEvent = [[CocoaEvent alloc] init: this];
+ [cocoaEvent
performSelectorOnMainThread:@selector(process)
withObject: nil
waitUntilDone: NO];
- [cocoaEvent release];
+ [cocoaEvent release];
+ }
}
}
diff --git a/Swiften/EventLoop/DummyEventLoop.cpp b/Swiften/EventLoop/DummyEventLoop.cpp
index b8e631e..3675ead 100644
--- a/Swiften/EventLoop/DummyEventLoop.cpp
+++ b/Swiften/EventLoop/DummyEventLoop.cpp
@@ -10,16 +10,30 @@
namespace Swift {
-DummyEventLoop::DummyEventLoop() {
+DummyEventLoop::DummyEventLoop() : hasEvents_(false) {
}
DummyEventLoop::~DummyEventLoop() {
- boost::lock_guard<boost::mutex> lock(eventsMutex_);
- if (!events_.empty()) {
+ if (hasEvents()) {
std::cerr << "DummyEventLoop: Unhandled events at destruction time" << std::endl;
}
- events_.clear();
}
+void DummyEventLoop::processEvents() {
+ while(hasEvents()) {
+ hasEvents_ = false;
+ handleNextEvent();
+ }
+}
+
+bool DummyEventLoop::hasEvents() {
+ boost::lock_guard<boost::mutex> lock(hasEventsMutex_);
+ return hasEvents_;
+}
+
+void DummyEventLoop::eventPosted() {
+ boost::lock_guard<boost::mutex> lock(hasEventsMutex_);
+ hasEvents_ = true;
+}
}
diff --git a/Swiften/EventLoop/DummyEventLoop.h b/Swiften/EventLoop/DummyEventLoop.h
index 297549e..b41cd09 100644
--- a/Swiften/EventLoop/DummyEventLoop.h
+++ b/Swiften/EventLoop/DummyEventLoop.h
@@ -8,8 +8,8 @@
#include <deque>
-#include <boost/thread/mutex.hpp>
#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
#include <Swiften/Base/API.h>
#include <Swiften/EventLoop/EventLoop.h>
@@ -20,40 +20,14 @@ namespace Swift {
DummyEventLoop();
virtual ~DummyEventLoop();
- void processEvents() {
- while (hasEvents()) {
- /*
- Creating a copy of the to-be-handled Event object because handling
- it can result in a DummyEventLoop::post() call.
- This call would also try to lock the eventsMutex_, resulting in a
- deadlock.
- */
-
- eventsMutex_.lock();
- Event eventCopy = events_[0];
- eventsMutex_.unlock();
-
- handleEvent(eventCopy);
-
- {
- boost::lock_guard<boost::mutex> lock(eventsMutex_);
- events_.pop_front();
- }
- }
- }
-
- bool hasEvents() {
- boost::lock_guard<boost::mutex> lock(eventsMutex_);
- return !events_.empty();
- }
-
- virtual void post(const Event& event) {
- boost::lock_guard<boost::mutex> lock(eventsMutex_);
- events_.push_back(event);
- }
+ void processEvents();
+
+ bool hasEvents();
+
+ virtual void eventPosted();
private:
- boost::mutex eventsMutex_;
- std::deque<Event> events_;
+ bool hasEvents_;
+ boost::mutex hasEventsMutex_;
};
}
diff --git a/Swiften/EventLoop/EventLoop.cpp b/Swiften/EventLoop/EventLoop.cpp
index 0b50e82..d9a9081 100644
--- a/Swiften/EventLoop/EventLoop.cpp
+++ b/Swiften/EventLoop/EventLoop.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2013 Isode Limited.
+ * Copyright (c) 2010-2015 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,11 +7,12 @@
#include <Swiften/EventLoop/EventLoop.h>
#include <algorithm>
-#include <iostream>
#include <cassert>
+
#include <boost/bind.hpp>
-#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
+#include <boost/lambda/lambda.hpp>
+#include <boost/optional.hpp>
#include <boost/thread/locks.hpp>
#include <Swiften/Base/Log.h>
@@ -26,68 +27,66 @@ inline void invokeCallback(const Event& event) {
event.callback();
}
catch (const std::exception& e) {
- std::cerr << "Uncaught exception in event loop: " << e.what() << std::endl;
+ SWIFT_LOG(error) << "Uncaught exception in event loop: " << e.what() << std::endl;
}
catch (...) {
- std::cerr << "Uncaught non-exception in event loop" << std::endl;
+ SWIFT_LOG(error) << "Uncaught non-exception in event loop" << std::endl;
}
}
-EventLoop::EventLoop() : nextEventID_(0), handlingEvents_(false) {
+EventLoop::EventLoop() : nextEventID_(0) {
}
EventLoop::~EventLoop() {
}
-void EventLoop::handleEvent(const Event& event) {
- //SWIFT_LOG(debug) << "Handling event " << event.id << std::endl;
-
- if (handlingEvents_) {
- // We're being called recursively. Push in the list of events to
- // handle in the parent handleEvent()
- eventsToHandle_.push_back(event);
- return;
- }
-
- bool doCallback = false;
+void EventLoop::handleNextEvent() {
+ bool callEventPosted = false;
{
- boost::lock_guard<boost::mutex> lock(eventsMutex_);
- std::list<Event>::iterator i = std::find(events_.begin(), events_.end(), event);
- if (i != events_.end()) {
- doCallback = true;
- events_.erase(i);
+ boost::recursive_mutex::scoped_lock lock(removeEventsMutex_);
+ {
+ boost::optional<Event> nextEvent;
+ {
+ boost::recursive_mutex::scoped_lock lock(eventsMutex_);
+ if (!events_.empty()) {
+ nextEvent = events_.front();
+ events_.pop_front();
+ }
+ }
+ callEventPosted = !events_.empty();
+ if (nextEvent) {
+ invokeCallback(nextEvent.get());
+ }
}
+
}
- if (doCallback) {
- handlingEvents_ = true;
- invokeCallback(event);
-
- // Process events that were passed to handleEvent during the callback
- // (i.e. through recursive calls of handleEvent)
- while (!eventsToHandle_.empty()) {
- Event nextEvent = eventsToHandle_.front();
- eventsToHandle_.pop_front();
- invokeCallback(nextEvent);
- }
- handlingEvents_ = false;
+
+ if (callEventPosted) {
+ eventPosted();
}
}
void EventLoop::postEvent(boost::function<void ()> callback, boost::shared_ptr<EventOwner> owner) {
Event event(owner, callback);
+ bool callEventPosted = false;
{
- boost::lock_guard<boost::mutex> lock(eventsMutex_);
+ boost::recursive_mutex::scoped_lock lock(eventsMutex_);
+
+ callEventPosted = events_.empty();
+
event.id = nextEventID_;
nextEventID_++;
events_.push_back(event);
}
- //SWIFT_LOG(debug) << "Posting event " << event.id << std::endl;
- post(event);
+ if (callEventPosted) {
+ eventPosted();
+ }
}
void EventLoop::removeEventsFromOwner(boost::shared_ptr<EventOwner> owner) {
- boost::lock_guard<boost::mutex> lock(eventsMutex_);
- events_.remove_if(lambda::bind(&Event::owner, lambda::_1) == owner);
+ boost::recursive_mutex::scoped_lock removeLock(removeEventsMutex_);
+ boost::recursive_mutex::scoped_lock lock(eventsMutex_);
+ events_.remove_if(lambda::bind(&Event::owner, lambda::_1) == owner);
}
}
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_;
};
}
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_;
};
}
diff --git a/Swiften/EventLoop/SimpleEventLoop.cpp b/Swiften/EventLoop/SimpleEventLoop.cpp
index 09b84dc..0bc06c9 100644
--- a/Swiften/EventLoop/SimpleEventLoop.cpp
+++ b/Swiften/EventLoop/SimpleEventLoop.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2015 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,35 +7,28 @@
#include <Swiften/EventLoop/SimpleEventLoop.h>
#include <boost/bind.hpp>
-#include <iostream>
#include <Swiften/Base/foreach.h>
-
namespace Swift {
-SimpleEventLoop::SimpleEventLoop() : isRunning_(true) {
+SimpleEventLoop::SimpleEventLoop() : isRunning_(true), eventAvailable_(false) {
}
SimpleEventLoop::~SimpleEventLoop() {
- if (!events_.empty()) {
- std::cerr << "Warning: Pending events in SimpleEventLoop at destruction time" << std::endl;
- }
}
void SimpleEventLoop::doRun(bool breakAfterEvents) {
while (isRunning_) {
- std::vector<Event> events;
{
- boost::unique_lock<boost::mutex> lock(eventsMutex_);
- while (events_.empty()) {
- eventsAvailable_.wait(lock);
+ boost::unique_lock<boost::mutex> lock(eventAvailableMutex_);
+ while (!eventAvailable_) {
+ eventAvailableCondition_.wait(lock);
}
- events.swap(events_);
- }
- foreach(const Event& event, events) {
- handleEvent(event);
+
+ eventAvailable_ = false;
}
+ runOnce();
if (breakAfterEvents) {
return;
}
@@ -43,14 +36,7 @@ void SimpleEventLoop::doRun(bool breakAfterEvents) {
}
void SimpleEventLoop::runOnce() {
- std::vector<Event> events;
- {
- boost::unique_lock<boost::mutex> lock(eventsMutex_);
- events.swap(events_);
- }
- foreach(const Event& event, events) {
- handleEvent(event);
- }
+ handleNextEvent();
}
void SimpleEventLoop::stop() {
@@ -61,12 +47,12 @@ void SimpleEventLoop::doStop() {
isRunning_ = false;
}
-void SimpleEventLoop::post(const Event& event) {
+void SimpleEventLoop::eventPosted() {
{
- boost::lock_guard<boost::mutex> lock(eventsMutex_);
- events_.push_back(event);
+ boost::unique_lock<boost::mutex> lock(eventAvailableMutex_);
+ eventAvailable_ = true;
}
- eventsAvailable_.notify_one();
+ eventAvailableCondition_.notify_one();
}
diff --git a/Swiften/EventLoop/SimpleEventLoop.h b/Swiften/EventLoop/SimpleEventLoop.h
index eedaf88..221591e 100644
--- a/Swiften/EventLoop/SimpleEventLoop.h
+++ b/Swiften/EventLoop/SimpleEventLoop.h
@@ -6,8 +6,6 @@
#pragma once
-#include <vector>
-#include <boost/function.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
@@ -31,8 +29,9 @@ namespace Swift {
void runOnce();
void stop();
-
- virtual void post(const Event& event);
+
+ protected:
+ virtual void eventPosted();
private:
void doRun(bool breakAfterEvents);
@@ -40,8 +39,9 @@ namespace Swift {
private:
bool isRunning_;
- std::vector<Event> events_;
- boost::mutex eventsMutex_;
- boost::condition_variable eventsAvailable_;
+
+ bool eventAvailable_;
+ boost::mutex eventAvailableMutex_;
+ boost::condition_variable eventAvailableCondition_;
};
}
diff --git a/Swiften/EventLoop/SingleThreadedEventLoop.cpp b/Swiften/EventLoop/SingleThreadedEventLoop.cpp
index c2235b1..095b962 100644
--- a/Swiften/EventLoop/SingleThreadedEventLoop.cpp
+++ b/Swiften/EventLoop/SingleThreadedEventLoop.cpp
@@ -15,20 +15,18 @@
namespace Swift {
SingleThreadedEventLoop::SingleThreadedEventLoop()
-: shouldShutDown_(false)
+: shouldShutDown_(false), eventAvailable_(false)
{
}
SingleThreadedEventLoop::~SingleThreadedEventLoop() {
- if (!events_.empty()) {
- std::cerr << "Warning: Pending events in SingleThreadedEventLoop at destruction time." << std::endl;
- }
+
}
void SingleThreadedEventLoop::waitForEvents() {
- boost::unique_lock<boost::mutex> lock(eventsMutex_);
- while (events_.empty() && !shouldShutDown_) {
- eventsAvailable_.wait(lock);
+ boost::unique_lock<boost::mutex> lock(eventAvailableMutex_);
+ while (!eventAvailable_ && !shouldShutDown_) {
+ eventAvailableCondition_.wait(lock);
}
if (shouldShutDown_)
@@ -36,30 +34,23 @@ void SingleThreadedEventLoop::waitForEvents() {
}
void SingleThreadedEventLoop::handleEvents() {
- // Make a copy of the list of events so we don't block any threads that post
- // events while we process them.
- std::vector<Event> events;
{
- boost::unique_lock<boost::mutex> lock(eventsMutex_);
- events.swap(events_);
- }
-
- // Loop through all the events and handle them
- foreach(const Event& event, events) {
- handleEvent(event);
+ boost::lock_guard<boost::mutex> lock(eventAvailableMutex_);
+ eventAvailable_ = false;
}
+ handleNextEvent();
}
void SingleThreadedEventLoop::stop() {
- boost::unique_lock<boost::mutex> lock(eventsMutex_);
+ boost::unique_lock<boost::mutex> lock(eventAvailableMutex_);
shouldShutDown_ = true;
- eventsAvailable_.notify_one();
+ eventAvailableCondition_.notify_one();
}
-void SingleThreadedEventLoop::post(const Event& event) {
- boost::lock_guard<boost::mutex> lock(eventsMutex_);
- events_.push_back(event);
- eventsAvailable_.notify_one();
+void SingleThreadedEventLoop::eventPosted() {
+ boost::lock_guard<boost::mutex> lock(eventAvailableMutex_);
+ eventAvailable_ = true;
+ eventAvailableCondition_.notify_one();
}
} // namespace Swift
diff --git a/Swiften/EventLoop/SingleThreadedEventLoop.h b/Swiften/EventLoop/SingleThreadedEventLoop.h
index 75ffad0..2145d652 100644
--- a/Swiften/EventLoop/SingleThreadedEventLoop.h
+++ b/Swiften/EventLoop/SingleThreadedEventLoop.h
@@ -39,7 +39,7 @@ namespace Swift {
public:
SingleThreadedEventLoop();
- ~SingleThreadedEventLoop();
+ virtual ~SingleThreadedEventLoop();
// Blocks while waiting for new events and returns when new events are available.
// Throws EventLoopCanceledException when the wait is canceled.
@@ -47,12 +47,14 @@ namespace Swift {
void handleEvents();
void stop();
- virtual void post(const Event& event);
+ protected:
+ virtual void eventPosted();
private:
bool shouldShutDown_;
- std::vector<Event> events_;
- boost::mutex eventsMutex_;
- boost::condition_variable eventsAvailable_;
+
+ bool eventAvailable_;
+ boost::mutex eventAvailableMutex_;
+ boost::condition_variable eventAvailableCondition_;
};
}