summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/EventLoop')
-rw-r--r--Swiften/EventLoop/BoostASIOEventLoop.cpp24
-rw-r--r--Swiften/EventLoop/BoostASIOEventLoop.h31
-rw-r--r--Swiften/EventLoop/Cocoa/CocoaEvent.h10
-rw-r--r--Swiften/EventLoop/Cocoa/CocoaEvent.mm17
-rw-r--r--Swiften/EventLoop/Cocoa/CocoaEventLoop.h28
-rw-r--r--Swiften/EventLoop/Cocoa/CocoaEventLoop.mm34
-rw-r--r--Swiften/EventLoop/DummyEventLoop.cpp26
-rw-r--r--Swiften/EventLoop/DummyEventLoop.h28
-rw-r--r--Swiften/EventLoop/Event.cpp22
-rw-r--r--Swiften/EventLoop/Event.h31
-rw-r--r--Swiften/EventLoop/EventLoop.cpp124
-rw-r--r--Swiften/EventLoop/EventLoop.h96
-rw-r--r--Swiften/EventLoop/EventOwner.h8
-rw-r--r--Swiften/EventLoop/Qt/QtEventLoop.h86
-rw-r--r--Swiften/EventLoop/SConscript30
-rw-r--r--Swiften/EventLoop/SimpleEventLoop.cpp48
-rw-r--r--Swiften/EventLoop/SimpleEventLoop.h54
-rw-r--r--Swiften/EventLoop/SingleThreadedEventLoop.cpp51
-rw-r--r--Swiften/EventLoop/SingleThreadedEventLoop.h68
-rw-r--r--Swiften/EventLoop/UnitTest/EventLoopTest.cpp148
-rw-r--r--Swiften/EventLoop/UnitTest/SimpleEventLoopTest.cpp104
21 files changed, 542 insertions, 526 deletions
diff --git a/Swiften/EventLoop/BoostASIOEventLoop.cpp b/Swiften/EventLoop/BoostASIOEventLoop.cpp
index 1574434..30143b9 100644
--- a/Swiften/EventLoop/BoostASIOEventLoop.cpp
+++ b/Swiften/EventLoop/BoostASIOEventLoop.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -10,7 +10,7 @@
namespace Swift {
-BoostASIOEventLoop::BoostASIOEventLoop(boost::shared_ptr<boost::asio::io_service> ioService) : ioService_(ioService) {
+BoostASIOEventLoop::BoostASIOEventLoop(std::shared_ptr<boost::asio::io_service> ioService) : ioService_(ioService) {
}
@@ -19,19 +19,19 @@ BoostASIOEventLoop::~BoostASIOEventLoop() {
}
void BoostASIOEventLoop::handleASIOEvent() {
- {
- boost::recursive_mutex::scoped_lock lock(isEventInASIOEventLoopMutex_);
- isEventInASIOEventLoop_ = false;
- }
- handleNextEvents();
+ {
+ std::unique_lock<std::recursive_mutex> lock(isEventInASIOEventLoopMutex_);
+ isEventInASIOEventLoop_ = false;
+ }
+ handleNextEvents();
}
void BoostASIOEventLoop::eventPosted() {
- boost::recursive_mutex::scoped_lock lock(isEventInASIOEventLoopMutex_);
- if (!isEventInASIOEventLoop_) {
- isEventInASIOEventLoop_ = true;
- ioService_->post(boost::bind(&BoostASIOEventLoop::handleASIOEvent, this));
- }
+ std::unique_lock<std::recursive_mutex> lock(isEventInASIOEventLoopMutex_);
+ if (!isEventInASIOEventLoop_) {
+ isEventInASIOEventLoop_ = true;
+ ioService_->post(boost::bind(&BoostASIOEventLoop::handleASIOEvent, this));
+ }
}
}
diff --git a/Swiften/EventLoop/BoostASIOEventLoop.h b/Swiften/EventLoop/BoostASIOEventLoop.h
index a093199..fbdf443 100644
--- a/Swiften/EventLoop/BoostASIOEventLoop.h
+++ b/Swiften/EventLoop/BoostASIOEventLoop.h
@@ -1,34 +1,35 @@
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <memory>
+#include <mutex>
+
#include <boost/asio/io_service.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/thread.hpp>
#include <Swiften/Base/API.h>
#include <Swiften/EventLoop/Event.h>
#include <Swiften/EventLoop/EventLoop.h>
namespace Swift {
- class SWIFTEN_API BoostASIOEventLoop : public EventLoop {
- public:
- BoostASIOEventLoop(boost::shared_ptr<boost::asio::io_service> ioService);
- virtual ~BoostASIOEventLoop();
+ class SWIFTEN_API BoostASIOEventLoop : public EventLoop {
+ public:
+ BoostASIOEventLoop(std::shared_ptr<boost::asio::io_service> ioService);
+ virtual ~BoostASIOEventLoop();
- protected:
- void handleASIOEvent();
+ protected:
+ void handleASIOEvent();
- virtual void eventPosted();
+ virtual void eventPosted();
- private:
- boost::shared_ptr<boost::asio::io_service> ioService_;
+ private:
+ std::shared_ptr<boost::asio::io_service> ioService_;
- bool isEventInASIOEventLoop_;
- boost::recursive_mutex isEventInASIOEventLoopMutex_;
- };
+ bool isEventInASIOEventLoop_ = false;
+ std::recursive_mutex isEventInASIOEventLoopMutex_;
+ };
}
diff --git a/Swiften/EventLoop/Cocoa/CocoaEvent.h b/Swiften/EventLoop/Cocoa/CocoaEvent.h
index 4453c74..945056e 100644
--- a/Swiften/EventLoop/Cocoa/CocoaEvent.h
+++ b/Swiften/EventLoop/Cocoa/CocoaEvent.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2013 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,8 +8,12 @@
#include <Foundation/Foundation.h>
+// The following line is a workaround for a bug in Boost 1.60 when building as C++11.
+// See ticket #11897 and #11863 in Boost's bug tracker.
+#undef check
+
namespace Swift {
- class CocoaEventLoop;
+ class CocoaEventLoop;
}
// Using deprecated declaration of instance vars in interface, because this
@@ -18,7 +22,7 @@ namespace Swift {
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
@interface CocoaEvent : NSObject {
- Swift::CocoaEventLoop* eventLoop;
+ Swift::CocoaEventLoop* eventLoop;
}
#pragma clang diagnostic pop
diff --git a/Swiften/EventLoop/Cocoa/CocoaEvent.mm b/Swiften/EventLoop/Cocoa/CocoaEvent.mm
index 4f72c29..fc9695b 100644
--- a/Swiften/EventLoop/Cocoa/CocoaEvent.mm
+++ b/Swiften/EventLoop/Cocoa/CocoaEvent.mm
@@ -1,28 +1,29 @@
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swiften/EventLoop/Cocoa/CocoaEvent.h>
+
#include <Swiften/EventLoop/Cocoa/CocoaEventLoop.h>
@implementation CocoaEvent
- (id) init:(Swift::CocoaEventLoop*) el {
- self = [super init];
- if (self != nil) {
- eventLoop = el;
- }
- return self;
+ self = [super init];
+ if (self != nil) {
+ eventLoop = el;
+ }
+ return self;
}
- (void) process {
- eventLoop->handleNextCocoaEvent();
+ eventLoop->handleNextCocoaEvent();
}
- (void) dealloc {
- [super dealloc];
+ [super dealloc];
}
@end
diff --git a/Swiften/EventLoop/Cocoa/CocoaEventLoop.h b/Swiften/EventLoop/Cocoa/CocoaEventLoop.h
index aad6b0a..7f20e6c 100644
--- a/Swiften/EventLoop/Cocoa/CocoaEventLoop.h
+++ b/Swiften/EventLoop/Cocoa/CocoaEventLoop.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/thread.hpp>
+#include <mutex>
#include <Swiften/EventLoop/EventLoop.h>
namespace Swift {
- class CocoaEventLoop : public EventLoop {
- public:
- CocoaEventLoop();
- virtual ~CocoaEventLoop();
+ class CocoaEventLoop : public EventLoop {
+ public:
+ CocoaEventLoop();
+ virtual ~CocoaEventLoop();
- void handleNextCocoaEvent();
-
- protected:
- virtual void eventPosted();
+ void handleNextCocoaEvent();
- private:
- bool isEventInCocoaEventLoop_;
- boost::recursive_mutex isEventInCocoaEventLoopMutex_;
- };
+ protected:
+ virtual void eventPosted();
+
+ private:
+ bool isEventInCocoaEventLoop_;
+ std::recursive_mutex isEventInCocoaEventLoopMutex_;
+ };
}
diff --git a/Swiften/EventLoop/Cocoa/CocoaEventLoop.mm b/Swiften/EventLoop/Cocoa/CocoaEventLoop.mm
index 2d7c613..b8ab621 100644
--- a/Swiften/EventLoop/Cocoa/CocoaEventLoop.mm
+++ b/Swiften/EventLoop/Cocoa/CocoaEventLoop.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -19,25 +19,25 @@ CocoaEventLoop::~CocoaEventLoop() {
}
void CocoaEventLoop::handleNextCocoaEvent() {
- {
- boost::recursive_mutex::scoped_lock lock(isEventInCocoaEventLoopMutex_);
- isEventInCocoaEventLoop_ = false;
- }
- handleNextEvents();
+ {
+ std::unique_lock<std::recursive_mutex> lock(isEventInCocoaEventLoopMutex_);
+ isEventInCocoaEventLoop_ = false;
+ }
+ handleNextEvents();
}
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];
- }
+ std::unique_lock<std::recursive_mutex> lock(isEventInCocoaEventLoopMutex_);
+ if (!isEventInCocoaEventLoop_) {
+ isEventInCocoaEventLoop_ = true;
+
+ CocoaEvent* cocoaEvent = [[CocoaEvent alloc] init: this];
+ [cocoaEvent
+ performSelectorOnMainThread:@selector(process)
+ withObject: nil
+ waitUntilDone: NO];
+ [cocoaEvent release];
+ }
}
}
diff --git a/Swiften/EventLoop/DummyEventLoop.cpp b/Swiften/EventLoop/DummyEventLoop.cpp
index 45e9af7..4dfbac3 100644
--- a/Swiften/EventLoop/DummyEventLoop.cpp
+++ b/Swiften/EventLoop/DummyEventLoop.cpp
@@ -1,39 +1,37 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swiften/EventLoop/DummyEventLoop.h>
-#include <iostream>
+#include <Swiften/Base/Log.h>
namespace Swift {
-DummyEventLoop::DummyEventLoop() : hasEvents_(false) {
+DummyEventLoop::DummyEventLoop() {
}
DummyEventLoop::~DummyEventLoop() {
- if (hasEvents()) {
- std::cerr << "DummyEventLoop: Unhandled events at destruction time" << std::endl;
- }
+ if (hasEvents()) {
+ SWIFT_LOG(warning) << "DummyEventLoop: Unhandled events at destruction time" << std::endl;
+ }
}
void DummyEventLoop::processEvents() {
- while(hasEvents()) {
- hasEvents_ = false;
- handleNextEvents();
- }
+ while(hasEvents()) {
+ hasEvents_ = false;
+ handleNextEvents();
+ }
}
bool DummyEventLoop::hasEvents() {
- boost::lock_guard<boost::mutex> lock(hasEventsMutex_);
- return hasEvents_;
+ return hasEvents_;
}
void DummyEventLoop::eventPosted() {
- boost::lock_guard<boost::mutex> lock(hasEventsMutex_);
- hasEvents_ = true;
+ hasEvents_ = true;
}
}
diff --git a/Swiften/EventLoop/DummyEventLoop.h b/Swiften/EventLoop/DummyEventLoop.h
index b41cd09..da2a360 100644
--- a/Swiften/EventLoop/DummyEventLoop.h
+++ b/Swiften/EventLoop/DummyEventLoop.h
@@ -1,33 +1,29 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <deque>
-
-#include <boost/thread/locks.hpp>
-#include <boost/thread/mutex.hpp>
+#include <atomic>
#include <Swiften/Base/API.h>
#include <Swiften/EventLoop/EventLoop.h>
namespace Swift {
- class SWIFTEN_API DummyEventLoop : public EventLoop {
- public:
- DummyEventLoop();
- virtual ~DummyEventLoop();
+ class SWIFTEN_API DummyEventLoop : public EventLoop {
+ public:
+ DummyEventLoop();
+ virtual ~DummyEventLoop();
- void processEvents();
+ void processEvents();
- bool hasEvents();
+ bool hasEvents();
- virtual void eventPosted();
+ virtual void eventPosted();
- private:
- bool hasEvents_;
- boost::mutex hasEventsMutex_;
- };
+ private:
+ std::atomic<bool> hasEvents_ = ATOMIC_VAR_INIT(false);
+ };
}
diff --git a/Swiften/EventLoop/Event.cpp b/Swiften/EventLoop/Event.cpp
index 0da459b..15d7146 100644
--- a/Swiften/EventLoop/Event.cpp
+++ b/Swiften/EventLoop/Event.cpp
@@ -1,22 +1,22 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swiften/EventLoop/Event.h>
-#include <typeinfo>
#include <iostream>
+#include <typeinfo>
std::ostream& operator<<(std::ostream& os, const Swift::Event& e) {
- os << "Event(" << e.id << ",";
- if (e.owner) {
- os << typeid(*e.owner.get()).name();
- }
- else {
- os << "null";
- }
- os << ")";
- return os;
+ os << "Event(" << e.id << ",";
+ if (e.owner) {
+ os << typeid(*e.owner.get()).name();
+ }
+ else {
+ os << "null";
+ }
+ os << ")";
+ return os;
}
diff --git a/Swiften/EventLoop/Event.h b/Swiften/EventLoop/Event.h
index 082d366..e92bb33 100644
--- a/Swiften/EventLoop/Event.h
+++ b/Swiften/EventLoop/Event.h
@@ -1,30 +1,31 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
+
#include <boost/function.hpp>
#include <Swiften/EventLoop/EventOwner.h>
namespace Swift {
- class Event {
- public:
- Event(boost::shared_ptr<EventOwner> owner, const boost::function<void()>& callback) : id(~0U), owner(owner), callback(callback) {
- }
-
- bool operator==(const Event& o) const {
- return o.id == id;
- }
-
- unsigned int id;
- boost::shared_ptr<EventOwner> owner;
- boost::function<void()> callback;
- };
+ class Event {
+ public:
+ Event(std::shared_ptr<EventOwner> owner, const boost::function<void()>& callback) : id(~0U), owner(owner), callback(callback) {
+ }
+
+ bool operator==(const Event& o) const {
+ return o.id == id;
+ }
+
+ unsigned int id;
+ std::shared_ptr<EventOwner> owner;
+ boost::function<void()> callback;
+ };
}
std::ostream& operator<<(std::ostream& os, const Swift::Event& e);
diff --git a/Swiften/EventLoop/EventLoop.cpp b/Swiften/EventLoop/EventLoop.cpp
index 8e7add5..186616f 100644
--- a/Swiften/EventLoop/EventLoop.cpp
+++ b/Swiften/EventLoop/EventLoop.cpp
@@ -8,31 +8,30 @@
#include <algorithm>
#include <cassert>
+#include <vector>
#include <boost/bind.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>
-#include <Swiften/Base/foreach.h>
namespace lambda = boost::lambda;
namespace Swift {
inline void invokeCallback(const Event& event) {
- try {
- assert(!event.callback.empty());
- event.callback();
- }
- catch (const std::exception& e) {
- SWIFT_LOG(error) << "Uncaught exception in event loop: " << e.what() << std::endl;
- }
- catch (...) {
- SWIFT_LOG(error) << "Uncaught non-exception in event loop" << std::endl;
- }
+ try {
+ assert(!event.callback.empty());
+ event.callback();
+ }
+ catch (const std::exception& e) {
+ SWIFT_LOG(error) << "Uncaught exception in event loop: " << e.what() << std::endl;
+ }
+ catch (...) {
+ SWIFT_LOG(error) << "Uncaught non-exception in event loop" << std::endl;
+ }
}
EventLoop::EventLoop() : nextEventID_(0), handlingEvents_(false) {
@@ -42,59 +41,62 @@ EventLoop::~EventLoop() {
}
void EventLoop::handleNextEvents() {
- const int eventsBatched = 100;
- // If handleNextEvents is already in progress, e.g. in case of a recursive call due to
- // the event loop implementation, then do no handle further events. Instead call
- // eventPosted() to continue event handling later.
- bool callEventPosted = handlingEvents_;
- if (!handlingEvents_) {
- handlingEvents_ = true;
- boost::recursive_mutex::scoped_lock lock(removeEventsMutex_);
- {
- std::vector<Event> nextEvents;
- {
- boost::recursive_mutex::scoped_lock lock(eventsMutex_);
- for (int n = 0; ((n < eventsBatched) && !events_.empty()); n++) {
- nextEvents.push_back(events_.front());
- events_.pop_front();
- }
- callEventPosted = !events_.empty();
- }
- if (!nextEvents.empty()) {
- foreach (const Event& event, nextEvents) {
- invokeCallback(event);
- }
- }
- }
- handlingEvents_ = false;
- }
-
- if (callEventPosted) {
- eventPosted();
- }
+ const int eventsBatched = 100;
+ // If handleNextEvents is already in progress, e.g. in case of a recursive call due to
+ // the event loop implementation, then do no handle further events. Instead call
+ // eventPosted() to continue event handling later.
+ bool callEventPosted = handlingEvents_;
+ if (!handlingEvents_) {
+ handlingEvents_ = true;
+ std::unique_lock<std::recursive_mutex> lock(removeEventsMutex_);
+ {
+ std::vector<Event> nextEvents;
+ {
+ std::unique_lock<std::recursive_mutex> lock(eventsMutex_);
+ for (int n = 0; ((n < eventsBatched) && !events_.empty()); n++) {
+ nextEvents.push_back(events_.front());
+ events_.pop_front();
+ }
+ callEventPosted = !events_.empty();
+ }
+ if (!nextEvents.empty()) {
+ for (const auto& event : nextEvents) {
+ invokeCallback(event);
+ }
+ }
+ }
+ 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::recursive_mutex::scoped_lock lock(eventsMutex_);
-
- callEventPosted = events_.empty();
-
- event.id = nextEventID_;
- nextEventID_++;
- events_.push_back(event);
- }
- if (callEventPosted) {
- eventPosted();
- }
+void EventLoop::postEvent(boost::function<void ()> callback, std::shared_ptr<EventOwner> owner) {
+ Event event(owner, callback);
+ bool callEventPosted = false;
+ {
+ std::unique_lock<std::recursive_mutex> lock(eventsMutex_);
+
+ callEventPosted = events_.empty();
+
+ event.id = nextEventID_;
+ nextEventID_++;
+ events_.push_back(event);
+ }
+ if (callEventPosted) {
+ eventPosted();
+ }
}
-void EventLoop::removeEventsFromOwner(boost::shared_ptr<EventOwner> 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);
+void EventLoop::removeEventsFromOwner(std::shared_ptr<EventOwner> owner) {
+ std::unique_lock<std::recursive_mutex> removeLock(removeEventsMutex_, std::defer_lock);
+ std::unique_lock<std::recursive_mutex> eventsLock(eventsMutex_, std::defer_lock);
+
+ std::lock(removeLock, eventsLock);
+
+ events_.remove_if(lambda::bind(&Event::owner, lambda::_1) == owner);
}
}
diff --git a/Swiften/EventLoop/EventLoop.h b/Swiften/EventLoop/EventLoop.h
index 2687501..06b9fbb 100644
--- a/Swiften/EventLoop/EventLoop.h
+++ b/Swiften/EventLoop/EventLoop.h
@@ -7,65 +7,65 @@
#pragma once
#include <list>
+#include <mutex>
#include <boost/function.hpp>
-#include <boost/thread.hpp>
#include <Swiften/Base/API.h>
#include <Swiften/EventLoop/Event.h>
namespace Swift {
- class EventOwner;
+ 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 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 postEvent method allows events to be added to the event queue of the \ref EventLoop.
+ * An optional \ref EventOwner can be passed as \p owner, allowing later removal of events that have not yet been
+ * executed using the \ref removeEventsFromOwner method.
+ */
+ void postEvent(boost::function<void ()> event, std::shared_ptr<EventOwner> owner = std::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);
+ /**
+ * The \ref removeEventsFromOwner method removes all events from the specified \p owner from the
+ * event queue.
+ */
+ void removeEventsFromOwner(std::shared_ptr<EventOwner> owner);
- protected:
- /**
- * The \ref handleNextEvents 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.
- * It can process multiple events before it reutrns.
- * If called recursively, the event queue is not further processed. Instead, \ref eventPosted
- * is called to notify the implementing event loop of the non-empty event queue.
- * It is recommended to not call \ref handleNextEvents inside an event posted to the event loop
- * as this can lead to an infinite loop.
- */
- void handleNextEvents();
+ protected:
+ /**
+ * The \ref handleNextEvents 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.
+ * It can process multiple events before it reutrns.
+ * If called recursively, the event queue is not further processed. Instead, \ref eventPosted
+ * is called to notify the implementing event loop of the non-empty event queue.
+ * It is recommended to not call \ref handleNextEvents inside an event posted to the event loop
+ * as this can lead to an infinite loop.
+ */
+ void handleNextEvents();
- /**
- * 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 handleNextEvents and there are still remaining events in the queue.
- */
- virtual void eventPosted() = 0;
+ /**
+ * 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 handleNextEvents and there are still remaining events in the queue.
+ */
+ virtual void eventPosted() = 0;
- private:
- unsigned int nextEventID_;
- std::list<Event> events_;
- bool handlingEvents_;
- boost::recursive_mutex eventsMutex_;
- boost::recursive_mutex removeEventsMutex_;
- };
+ private:
+ unsigned int nextEventID_;
+ std::list<Event> events_;
+ bool handlingEvents_;
+ std::recursive_mutex eventsMutex_;
+ std::recursive_mutex removeEventsMutex_;
+ };
}
diff --git a/Swiften/EventLoop/EventOwner.h b/Swiften/EventLoop/EventOwner.h
index a62a778..cd4a80b 100644
--- a/Swiften/EventLoop/EventOwner.h
+++ b/Swiften/EventLoop/EventOwner.h
@@ -9,8 +9,8 @@
#include <Swiften/Base/API.h>
namespace Swift {
- class SWIFTEN_API EventOwner {
- public:
- virtual ~EventOwner();
- };
+ class SWIFTEN_API EventOwner {
+ public:
+ virtual ~EventOwner();
+ };
}
diff --git a/Swiften/EventLoop/Qt/QtEventLoop.h b/Swiften/EventLoop/Qt/QtEventLoop.h
index 123b6e8..b1644c2 100644
--- a/Swiften/EventLoop/Qt/QtEventLoop.h
+++ b/Swiften/EventLoop/Qt/QtEventLoop.h
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/thread.hpp>
+#include <mutex>
#include <QCoreApplication>
#include <QEvent>
@@ -15,45 +15,45 @@
#include <Swiften/EventLoop/EventLoop.h>
namespace Swift {
- class QtEventLoop : public QObject, public EventLoop {
- public:
- QtEventLoop() : isEventInQtEventLoop_(false) {}
- virtual ~QtEventLoop() {
- QCoreApplication::removePostedEvents(this);
- }
-
- 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) {
- {
- boost::recursive_mutex::scoped_lock lock(isEventInQtEventLoopMutex_);
- isEventInQtEventLoop_ = false;
- }
- handleNextEvents();
- //event->deleteLater(); FIXME: Leak?
- return true;
- }
-
- return false;
- }
-
- private:
- struct Event : public QEvent {
- Event() :
- QEvent(QEvent::User) {
- }
- };
-
- bool isEventInQtEventLoop_;
- boost::recursive_mutex isEventInQtEventLoopMutex_;
- };
+ class QtEventLoop : public QObject, public EventLoop {
+ public:
+ QtEventLoop() : isEventInQtEventLoop_(false) {}
+ virtual ~QtEventLoop() {
+ QCoreApplication::removePostedEvents(this);
+ }
+
+ protected:
+ virtual void eventPosted() {
+ std::unique_lock<std::recursive_mutex> lock(isEventInQtEventLoopMutex_);
+ if (!isEventInQtEventLoop_) {
+ isEventInQtEventLoop_ = true;
+ QCoreApplication::postEvent(this, new Event());
+ }
+ }
+
+ virtual bool event(QEvent* qevent) {
+ Event* event = dynamic_cast<Event*>(qevent);
+ if (event) {
+ {
+ std::unique_lock<std::recursive_mutex> lock(isEventInQtEventLoopMutex_);
+ isEventInQtEventLoop_ = false;
+ }
+ handleNextEvents();
+ //event->deleteLater(); FIXME: Leak?
+ return true;
+ }
+
+ return false;
+ }
+
+ private:
+ struct Event : public QEvent {
+ Event() :
+ QEvent(QEvent::User) {
+ }
+ };
+
+ bool isEventInQtEventLoop_;
+ std::recursive_mutex isEventInQtEventLoopMutex_;
+ };
}
diff --git a/Swiften/EventLoop/SConscript b/Swiften/EventLoop/SConscript
index b810e8c..7aea53f 100644
--- a/Swiften/EventLoop/SConscript
+++ b/Swiften/EventLoop/SConscript
@@ -1,23 +1,23 @@
Import("swiften_env")
sources = [
- "BoostASIOEventLoop.cpp",
- "DummyEventLoop.cpp",
- "Event.cpp",
- "EventLoop.cpp",
- "EventOwner.cpp",
- "SimpleEventLoop.cpp",
- "SingleThreadedEventLoop.cpp",
- ]
+ "BoostASIOEventLoop.cpp",
+ "DummyEventLoop.cpp",
+ "Event.cpp",
+ "EventLoop.cpp",
+ "EventOwner.cpp",
+ "SimpleEventLoop.cpp",
+ "SingleThreadedEventLoop.cpp",
+ ]
objects = swiften_env.SwiftenObject(sources)
swiften_env.Append(SWIFTEN_OBJECTS = [objects])
if swiften_env["PLATFORM"] == "darwin" and swiften_env["target"] == "native" or swiften_env["target"] == 'xcode':
- myenv = swiften_env.Clone()
- myenv.Append(CXXFLAGS = myenv["OBJCCFLAGS"])
- objects = myenv.SwiftenObject([
- "Cocoa/CocoaEventLoop.mm",
- "Cocoa/CocoaEvent.mm"
- ])
- swiften_env.Append(SWIFTEN_OBJECTS = [objects])
+ myenv = swiften_env.Clone()
+ myenv.Append(CXXFLAGS = myenv["OBJCCFLAGS"])
+ objects = myenv.SwiftenObject([
+ "Cocoa/CocoaEventLoop.mm",
+ "Cocoa/CocoaEvent.mm"
+ ])
+ swiften_env.Append(SWIFTEN_OBJECTS = [objects])
diff --git a/Swiften/EventLoop/SimpleEventLoop.cpp b/Swiften/EventLoop/SimpleEventLoop.cpp
index 59e799f..cac04e4 100644
--- a/Swiften/EventLoop/SimpleEventLoop.cpp
+++ b/Swiften/EventLoop/SimpleEventLoop.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,8 +8,6 @@
#include <boost/bind.hpp>
-#include <Swiften/Base/foreach.h>
-
namespace Swift {
SimpleEventLoop::SimpleEventLoop() : isRunning_(true), eventAvailable_(false) {
@@ -19,40 +17,40 @@ SimpleEventLoop::~SimpleEventLoop() {
}
void SimpleEventLoop::doRun(bool breakAfterEvents) {
- while (isRunning_) {
- {
- boost::unique_lock<boost::mutex> lock(eventAvailableMutex_);
- while (!eventAvailable_) {
- eventAvailableCondition_.wait(lock);
- }
-
- eventAvailable_ = false;
- }
- runOnce();
- if (breakAfterEvents) {
- return;
- }
- }
+ while (isRunning_) {
+ {
+ std::unique_lock<std::mutex> lock(eventAvailableMutex_);
+ while (!eventAvailable_) {
+ eventAvailableCondition_.wait(lock);
+ }
+
+ eventAvailable_ = false;
+ }
+ runOnce();
+ if (breakAfterEvents) {
+ return;
+ }
+ }
}
void SimpleEventLoop::runOnce() {
- handleNextEvents();
+ handleNextEvents();
}
void SimpleEventLoop::stop() {
- postEvent(boost::bind(&SimpleEventLoop::doStop, this));
+ postEvent(boost::bind(&SimpleEventLoop::doStop, this));
}
void SimpleEventLoop::doStop() {
- isRunning_ = false;
+ isRunning_ = false;
}
void SimpleEventLoop::eventPosted() {
- {
- boost::unique_lock<boost::mutex> lock(eventAvailableMutex_);
- eventAvailable_ = true;
- }
- eventAvailableCondition_.notify_one();
+ {
+ std::unique_lock<std::mutex> lock(eventAvailableMutex_);
+ eventAvailable_ = true;
+ }
+ eventAvailableCondition_.notify_one();
}
diff --git a/Swiften/EventLoop/SimpleEventLoop.h b/Swiften/EventLoop/SimpleEventLoop.h
index 221591e..fe5f509 100644
--- a/Swiften/EventLoop/SimpleEventLoop.h
+++ b/Swiften/EventLoop/SimpleEventLoop.h
@@ -1,47 +1,47 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/condition_variable.hpp>
+#include <condition_variable>
+#include <mutex>
#include <Swiften/Base/API.h>
#include <Swiften/EventLoop/EventLoop.h>
namespace Swift {
- class SWIFTEN_API SimpleEventLoop : public EventLoop {
- public:
- SimpleEventLoop();
- virtual ~SimpleEventLoop();
+ class SWIFTEN_API SimpleEventLoop : public EventLoop {
+ public:
+ SimpleEventLoop();
+ virtual ~SimpleEventLoop();
- void run() {
- doRun(false);
- }
+ void run() {
+ doRun(false);
+ }
- void runUntilEvents() {
- doRun(true);
- }
+ void runUntilEvents() {
+ doRun(true);
+ }
- void runOnce();
+ void runOnce();
- void stop();
-
- protected:
- virtual void eventPosted();
+ void stop();
- private:
- void doRun(bool breakAfterEvents);
- void doStop();
+ protected:
+ virtual void eventPosted();
- private:
- bool isRunning_;
+ private:
+ void doRun(bool breakAfterEvents);
+ void doStop();
- bool eventAvailable_;
- boost::mutex eventAvailableMutex_;
- boost::condition_variable eventAvailableCondition_;
- };
+ private:
+ bool isRunning_;
+
+ bool eventAvailable_;
+ std::mutex eventAvailableMutex_;
+ std::condition_variable eventAvailableCondition_;
+ };
}
diff --git a/Swiften/EventLoop/SingleThreadedEventLoop.cpp b/Swiften/EventLoop/SingleThreadedEventLoop.cpp
index d617534..0542f37 100644
--- a/Swiften/EventLoop/SingleThreadedEventLoop.cpp
+++ b/Swiften/EventLoop/SingleThreadedEventLoop.cpp
@@ -4,17 +4,21 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "Swiften/EventLoop/SingleThreadedEventLoop.h"
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
-#include <boost/bind.hpp>
-#include <iostream>
+#include <Swiften/EventLoop/SingleThreadedEventLoop.h>
-#include "Swiften/Base/foreach.h"
+#include <iostream>
+#include <boost/bind.hpp>
namespace Swift {
-SingleThreadedEventLoop::SingleThreadedEventLoop()
+SingleThreadedEventLoop::SingleThreadedEventLoop()
: shouldShutDown_(false), eventAvailable_(false)
{
}
@@ -24,33 +28,34 @@ SingleThreadedEventLoop::~SingleThreadedEventLoop() {
}
void SingleThreadedEventLoop::waitForEvents() {
- boost::unique_lock<boost::mutex> lock(eventAvailableMutex_);
- while (!eventAvailable_ && !shouldShutDown_) {
- eventAvailableCondition_.wait(lock);
- }
-
- if (shouldShutDown_)
- throw EventLoopCanceledException();
+ std::unique_lock<std::mutex> lock(eventAvailableMutex_);
+ while (!eventAvailable_ && !shouldShutDown_) {
+ eventAvailableCondition_.wait(lock);
+ }
+
+ if (shouldShutDown_) {
+ throw EventLoopCanceledException();
+ }
}
void SingleThreadedEventLoop::handleEvents() {
- {
- boost::lock_guard<boost::mutex> lock(eventAvailableMutex_);
- eventAvailable_ = false;
- }
- handleNextEvents();
+ {
+ std::lock_guard<std::mutex> lock(eventAvailableMutex_);
+ eventAvailable_ = false;
+ }
+ handleNextEvents();
}
void SingleThreadedEventLoop::stop() {
- boost::unique_lock<boost::mutex> lock(eventAvailableMutex_);
- shouldShutDown_ = true;
- eventAvailableCondition_.notify_one();
+ std::unique_lock<std::mutex> lock(eventAvailableMutex_);
+ shouldShutDown_ = true;
+ eventAvailableCondition_.notify_one();
}
void SingleThreadedEventLoop::eventPosted() {
- boost::lock_guard<boost::mutex> lock(eventAvailableMutex_);
- eventAvailable_ = true;
- eventAvailableCondition_.notify_one();
+ std::lock_guard<std::mutex> lock(eventAvailableMutex_);
+ eventAvailable_ = true;
+ eventAvailableCondition_.notify_one();
}
} // namespace Swift
diff --git a/Swiften/EventLoop/SingleThreadedEventLoop.h b/Swiften/EventLoop/SingleThreadedEventLoop.h
index 2145d652..9f8cb0a 100644
--- a/Swiften/EventLoop/SingleThreadedEventLoop.h
+++ b/Swiften/EventLoop/SingleThreadedEventLoop.h
@@ -4,13 +4,19 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
+#include <condition_variable>
+#include <mutex>
#include <vector>
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/condition_variable.hpp>
-#include "Swiften/EventLoop/EventLoop.h"
+#include <Swiften/EventLoop/EventLoop.h>
// DESCRIPTION:
//
@@ -22,39 +28,39 @@
// The SingleThreadedEventLoop class implements an event loop that can be used from such applications.
//
// USAGE:
-//
-// Spawn a new thread in the desired framework and call SingleThreadedEventLoop::waitForEvents(). The method
+//
+// Spawn a new thread in the desired framework and call SingleThreadedEventLoop::waitForEvents(). The method
// blocks until a new event has arrived at which time it'll return, or until the wait is canceled
-// at which time it throws EventLoopCanceledException.
+// at which time it throws EventLoopCanceledException.
//
// When a new event has arrived and SingleThreadedEventLoop::waitForEvents() returns, the caller should then
-// call SingleThreadedEventLoop::handleEvents() on the main GUI thread. For WPF applications, for instance,
+// call SingleThreadedEventLoop::handleEvents() on the main GUI thread. For WPF applications, for instance,
// the Dispatcher class can be used to execute the call on the GUI thread.
//
namespace Swift {
- class SingleThreadedEventLoop : public EventLoop {
- public:
- class EventLoopCanceledException : public std::exception { };
-
- public:
- SingleThreadedEventLoop();
- virtual ~SingleThreadedEventLoop();
-
- // Blocks while waiting for new events and returns when new events are available.
- // Throws EventLoopCanceledException when the wait is canceled.
- void waitForEvents();
- void handleEvents();
- void stop();
-
- protected:
- virtual void eventPosted();
-
- private:
- bool shouldShutDown_;
-
- bool eventAvailable_;
- boost::mutex eventAvailableMutex_;
- boost::condition_variable eventAvailableCondition_;
- };
+ class SingleThreadedEventLoop : public EventLoop {
+ public:
+ class EventLoopCanceledException : public std::exception { };
+
+ public:
+ SingleThreadedEventLoop();
+ virtual ~SingleThreadedEventLoop();
+
+ // Blocks while waiting for new events and returns when new events are available.
+ // Throws EventLoopCanceledException when the wait is canceled.
+ void waitForEvents();
+ void handleEvents();
+ void stop();
+
+ protected:
+ virtual void eventPosted();
+
+ private:
+ bool shouldShutDown_;
+
+ bool eventAvailable_;
+ std::mutex eventAvailableMutex_;
+ std::condition_variable eventAvailableCondition_;
+ };
}
diff --git a/Swiften/EventLoop/UnitTest/EventLoopTest.cpp b/Swiften/EventLoop/UnitTest/EventLoopTest.cpp
index 509134e..00a4376 100644
--- a/Swiften/EventLoop/UnitTest/EventLoopTest.cpp
+++ b/Swiften/EventLoop/UnitTest/EventLoopTest.cpp
@@ -1,90 +1,92 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
+#include <thread>
+
+#include <boost/bind.hpp>
+
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
-#include <boost/thread.hpp>
-#include <boost/bind.hpp>
+#include <Swiften/Base/sleep.h>
+#include <Swiften/EventLoop/DummyEventLoop.h>
#include <Swiften/EventLoop/EventOwner.h>
#include <Swiften/EventLoop/SimpleEventLoop.h>
-#include <Swiften/EventLoop/DummyEventLoop.h>
-#include <Swiften/Base/sleep.h>
using namespace Swift;
class EventLoopTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(EventLoopTest);
- CPPUNIT_TEST(testPost);
- CPPUNIT_TEST(testRemove);
- CPPUNIT_TEST(testHandleEvent_Recursive);
- CPPUNIT_TEST_SUITE_END();
-
- public:
- void setUp() {
- events_.clear();
- }
-
- void testPost() {
- SimpleEventLoop testling;
-
- testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 1));
- testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 2));
- testling.stop();
- testling.run();
-
- CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(events_.size()));
- CPPUNIT_ASSERT_EQUAL(1, events_[0]);
- CPPUNIT_ASSERT_EQUAL(2, events_[1]);
- }
-
- void testRemove() {
- SimpleEventLoop testling;
- boost::shared_ptr<MyEventOwner> eventOwner1(new MyEventOwner());
- boost::shared_ptr<MyEventOwner> eventOwner2(new MyEventOwner());
-
- testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 1), eventOwner1);
- testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 2), eventOwner2);
- testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 3), eventOwner1);
- testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 4), eventOwner2);
- testling.removeEventsFromOwner(eventOwner2);
- testling.stop();
- testling.run();
-
- CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(events_.size()));
- CPPUNIT_ASSERT_EQUAL(1, events_[0]);
- CPPUNIT_ASSERT_EQUAL(3, events_[1]);
- }
-
- void testHandleEvent_Recursive() {
- DummyEventLoop testling;
- boost::shared_ptr<MyEventOwner> eventOwner(new MyEventOwner());
-
- testling.postEvent(boost::bind(&EventLoopTest::runEventLoop, this, &testling, eventOwner), eventOwner);
- testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 0), eventOwner);
- testling.processEvents();
-
- CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(events_.size()));
- CPPUNIT_ASSERT_EQUAL(0, events_[0]);
- CPPUNIT_ASSERT_EQUAL(1, events_[1]);
- }
-
- private:
- struct MyEventOwner : public EventOwner {};
- void logEvent(int i) {
- events_.push_back(i);
- }
- void runEventLoop(DummyEventLoop* loop, boost::shared_ptr<MyEventOwner> eventOwner) {
- loop->processEvents();
- CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(events_.size()));
- loop->postEvent(boost::bind(&EventLoopTest::logEvent, this, 1), eventOwner);
- }
-
- private:
- std::vector<int> events_;
+ CPPUNIT_TEST_SUITE(EventLoopTest);
+ CPPUNIT_TEST(testPost);
+ CPPUNIT_TEST(testRemove);
+ CPPUNIT_TEST(testHandleEvent_Recursive);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp() {
+ events_.clear();
+ }
+
+ void testPost() {
+ SimpleEventLoop testling;
+
+ testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 1));
+ testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 2));
+ testling.stop();
+ testling.run();
+
+ CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(events_.size()));
+ CPPUNIT_ASSERT_EQUAL(1, events_[0]);
+ CPPUNIT_ASSERT_EQUAL(2, events_[1]);
+ }
+
+ void testRemove() {
+ SimpleEventLoop testling;
+ std::shared_ptr<MyEventOwner> eventOwner1(new MyEventOwner());
+ std::shared_ptr<MyEventOwner> eventOwner2(new MyEventOwner());
+
+ testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 1), eventOwner1);
+ testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 2), eventOwner2);
+ testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 3), eventOwner1);
+ testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 4), eventOwner2);
+ testling.removeEventsFromOwner(eventOwner2);
+ testling.stop();
+ testling.run();
+
+ CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(events_.size()));
+ CPPUNIT_ASSERT_EQUAL(1, events_[0]);
+ CPPUNIT_ASSERT_EQUAL(3, events_[1]);
+ }
+
+ void testHandleEvent_Recursive() {
+ DummyEventLoop testling;
+ std::shared_ptr<MyEventOwner> eventOwner(new MyEventOwner());
+
+ testling.postEvent(boost::bind(&EventLoopTest::runEventLoop, this, &testling, eventOwner), eventOwner);
+ testling.postEvent(boost::bind(&EventLoopTest::logEvent, this, 0), eventOwner);
+ testling.processEvents();
+
+ CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(events_.size()));
+ CPPUNIT_ASSERT_EQUAL(0, events_[0]);
+ CPPUNIT_ASSERT_EQUAL(1, events_[1]);
+ }
+
+ private:
+ struct MyEventOwner : public EventOwner {};
+ void logEvent(int i) {
+ events_.push_back(i);
+ }
+ void runEventLoop(DummyEventLoop* loop, std::shared_ptr<MyEventOwner> eventOwner) {
+ loop->processEvents();
+ CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(events_.size()));
+ loop->postEvent(boost::bind(&EventLoopTest::logEvent, this, 1), eventOwner);
+ }
+
+ private:
+ std::vector<int> events_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(EventLoopTest);
diff --git a/Swiften/EventLoop/UnitTest/SimpleEventLoopTest.cpp b/Swiften/EventLoop/UnitTest/SimpleEventLoopTest.cpp
index 759ccad..3d096d3 100644
--- a/Swiften/EventLoop/UnitTest/SimpleEventLoopTest.cpp
+++ b/Swiften/EventLoop/UnitTest/SimpleEventLoopTest.cpp
@@ -1,67 +1,69 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
+#include <thread>
+
+#include <boost/bind.hpp>
+
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
-#include <boost/thread.hpp>
-#include <boost/bind.hpp>
-#include <Swiften/EventLoop/SimpleEventLoop.h>
#include <Swiften/Base/sleep.h>
+#include <Swiften/EventLoop/SimpleEventLoop.h>
using namespace Swift;
class SimpleEventLoopTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(SimpleEventLoopTest);
- // FIXME: Temporarily disabling run, because it generates a "vector
- // iterator not incrementable" on XP
- //CPPUNIT_TEST(testRun);
- CPPUNIT_TEST(testPostFromMainThread);
- CPPUNIT_TEST_SUITE_END();
-
- public:
- void setUp() {
- counter_ = 0;
- }
-
- void testRun() {
- SimpleEventLoop testling;
- boost::thread thread(boost::bind(&SimpleEventLoopTest::runIncrementingThread, this, &testling));
- testling.run();
-
- CPPUNIT_ASSERT_EQUAL(10, counter_);
- }
-
- void testPostFromMainThread() {
- SimpleEventLoop testling;
- testling.postEvent(boost::bind(&SimpleEventLoopTest::incrementCounterAndStop, this, &testling));
- testling.run();
-
- CPPUNIT_ASSERT_EQUAL(1, counter_);
- }
-
- private:
- void runIncrementingThread(SimpleEventLoop* loop) {
- for (unsigned int i = 0; i < 10; ++i) {
- Swift::sleep(1);
- loop->postEvent(boost::bind(&SimpleEventLoopTest::incrementCounter, this));
- }
- loop->stop();
- }
-
- void incrementCounter() {
- counter_++;
- }
-
- void incrementCounterAndStop(SimpleEventLoop* loop) {
- counter_++;
- loop->stop();
- }
-
- int counter_;
+ CPPUNIT_TEST_SUITE(SimpleEventLoopTest);
+ // FIXME: Temporarily disabling run, because it generates a "vector
+ // iterator not incrementable" on XP
+ //CPPUNIT_TEST(testRun);
+ CPPUNIT_TEST(testPostFromMainThread);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp() {
+ counter_ = 0;
+ }
+
+ void testRun() {
+ SimpleEventLoop testling;
+ std::thread thread(boost::bind(&SimpleEventLoopTest::runIncrementingThread, this, &testling));
+ testling.run();
+
+ CPPUNIT_ASSERT_EQUAL(10, counter_);
+ }
+
+ void testPostFromMainThread() {
+ SimpleEventLoop testling;
+ testling.postEvent(boost::bind(&SimpleEventLoopTest::incrementCounterAndStop, this, &testling));
+ testling.run();
+
+ CPPUNIT_ASSERT_EQUAL(1, counter_);
+ }
+
+ private:
+ void runIncrementingThread(SimpleEventLoop* loop) {
+ for (unsigned int i = 0; i < 10; ++i) {
+ Swift::sleep(1);
+ loop->postEvent(boost::bind(&SimpleEventLoopTest::incrementCounter, this));
+ }
+ loop->stop();
+ }
+
+ void incrementCounter() {
+ counter_++;
+ }
+
+ void incrementCounterAndStop(SimpleEventLoop* loop) {
+ counter_++;
+ loop->stop();
+ }
+
+ int counter_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(SimpleEventLoopTest);