diff options
Diffstat (limited to 'Swiften/EventLoop')
-rw-r--r-- | Swiften/EventLoop/BoostASIOEventLoop.cpp | 20 | ||||
-rw-r--r-- | Swiften/EventLoop/BoostASIOEventLoop.h | 24 | ||||
-rw-r--r-- | Swiften/EventLoop/Cocoa/CocoaEvent.h | 4 | ||||
-rw-r--r-- | Swiften/EventLoop/Cocoa/CocoaEvent.mm | 14 | ||||
-rw-r--r-- | Swiften/EventLoop/Cocoa/CocoaEventLoop.h | 24 | ||||
-rw-r--r-- | Swiften/EventLoop/Cocoa/CocoaEventLoop.mm | 32 | ||||
-rw-r--r-- | Swiften/EventLoop/DummyEventLoop.cpp | 22 | ||||
-rw-r--r-- | Swiften/EventLoop/DummyEventLoop.h | 22 | ||||
-rw-r--r-- | Swiften/EventLoop/Event.cpp | 18 | ||||
-rw-r--r-- | Swiften/EventLoop/Event.h | 22 | ||||
-rw-r--r-- | Swiften/EventLoop/EventLoop.cpp | 114 | ||||
-rw-r--r-- | Swiften/EventLoop/EventLoop.h | 94 | ||||
-rw-r--r-- | Swiften/EventLoop/EventOwner.h | 8 | ||||
-rw-r--r-- | Swiften/EventLoop/Qt/QtEventLoop.h | 82 | ||||
-rw-r--r-- | Swiften/EventLoop/SimpleEventLoop.cpp | 44 | ||||
-rw-r--r-- | Swiften/EventLoop/SimpleEventLoop.h | 48 | ||||
-rw-r--r-- | Swiften/EventLoop/SingleThreadedEventLoop.cpp | 36 | ||||
-rw-r--r-- | Swiften/EventLoop/SingleThreadedEventLoop.h | 48 | ||||
-rw-r--r-- | Swiften/EventLoop/UnitTest/EventLoopTest.cpp | 136 | ||||
-rw-r--r-- | Swiften/EventLoop/UnitTest/SimpleEventLoopTest.cpp | 76 |
20 files changed, 444 insertions, 444 deletions
diff --git a/Swiften/EventLoop/BoostASIOEventLoop.cpp b/Swiften/EventLoop/BoostASIOEventLoop.cpp index 1574434..a9d1440 100644 --- a/Swiften/EventLoop/BoostASIOEventLoop.cpp +++ b/Swiften/EventLoop/BoostASIOEventLoop.cpp @@ -19,19 +19,19 @@ BoostASIOEventLoop::~BoostASIOEventLoop() { } void BoostASIOEventLoop::handleASIOEvent() { - { - boost::recursive_mutex::scoped_lock lock(isEventInASIOEventLoopMutex_); - isEventInASIOEventLoop_ = false; - } - handleNextEvents(); + { + boost::recursive_mutex::scoped_lock 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)); - } + boost::recursive_mutex::scoped_lock 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..c39aaf5 100644 --- a/Swiften/EventLoop/BoostASIOEventLoop.h +++ b/Swiften/EventLoop/BoostASIOEventLoop.h @@ -15,20 +15,20 @@ #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(boost::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: + boost::shared_ptr<boost::asio::io_service> ioService_; - bool isEventInASIOEventLoop_; - boost::recursive_mutex isEventInASIOEventLoopMutex_; - }; + bool isEventInASIOEventLoop_; + boost::recursive_mutex isEventInASIOEventLoopMutex_; + }; } diff --git a/Swiften/EventLoop/Cocoa/CocoaEvent.h b/Swiften/EventLoop/Cocoa/CocoaEvent.h index 1e2c6f6..945056e 100644 --- a/Swiften/EventLoop/Cocoa/CocoaEvent.h +++ b/Swiften/EventLoop/Cocoa/CocoaEvent.h @@ -13,7 +13,7 @@ #undef check namespace Swift { - class CocoaEventLoop; + class CocoaEventLoop; } // Using deprecated declaration of instance vars in interface, because this @@ -22,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 8615b48..fc9695b 100644 --- a/Swiften/EventLoop/Cocoa/CocoaEvent.mm +++ b/Swiften/EventLoop/Cocoa/CocoaEvent.mm @@ -11,19 +11,19 @@ @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..bbe8390 100644 --- a/Swiften/EventLoop/Cocoa/CocoaEventLoop.h +++ b/Swiften/EventLoop/Cocoa/CocoaEventLoop.h @@ -11,18 +11,18 @@ #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_; + boost::recursive_mutex isEventInCocoaEventLoopMutex_; + }; } diff --git a/Swiften/EventLoop/Cocoa/CocoaEventLoop.mm b/Swiften/EventLoop/Cocoa/CocoaEventLoop.mm index 2d7c613..de7c1de 100644 --- a/Swiften/EventLoop/Cocoa/CocoaEventLoop.mm +++ b/Swiften/EventLoop/Cocoa/CocoaEventLoop.mm @@ -19,25 +19,25 @@ CocoaEventLoop::~CocoaEventLoop() { } void CocoaEventLoop::handleNextCocoaEvent() { - { - boost::recursive_mutex::scoped_lock lock(isEventInCocoaEventLoopMutex_); - isEventInCocoaEventLoop_ = false; - } - handleNextEvents(); + { + boost::recursive_mutex::scoped_lock 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]; - } + 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]; + } } } diff --git a/Swiften/EventLoop/DummyEventLoop.cpp b/Swiften/EventLoop/DummyEventLoop.cpp index 45e9af7..6eb730a 100644 --- a/Swiften/EventLoop/DummyEventLoop.cpp +++ b/Swiften/EventLoop/DummyEventLoop.cpp @@ -14,26 +14,26 @@ DummyEventLoop::DummyEventLoop() : hasEvents_(false) { } DummyEventLoop::~DummyEventLoop() { - if (hasEvents()) { - std::cerr << "DummyEventLoop: Unhandled events at destruction time" << std::endl; - } + if (hasEvents()) { + std::cerr << "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_; + boost::lock_guard<boost::mutex> lock(hasEventsMutex_); + return hasEvents_; } void DummyEventLoop::eventPosted() { - boost::lock_guard<boost::mutex> lock(hasEventsMutex_); - hasEvents_ = true; + boost::lock_guard<boost::mutex> lock(hasEventsMutex_); + hasEvents_ = true; } } diff --git a/Swiften/EventLoop/DummyEventLoop.h b/Swiften/EventLoop/DummyEventLoop.h index b41cd09..b78c1a6 100644 --- a/Swiften/EventLoop/DummyEventLoop.h +++ b/Swiften/EventLoop/DummyEventLoop.h @@ -15,19 +15,19 @@ #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: + bool hasEvents_; + boost::mutex hasEventsMutex_; + }; } diff --git a/Swiften/EventLoop/Event.cpp b/Swiften/EventLoop/Event.cpp index f3ea228..15d7146 100644 --- a/Swiften/EventLoop/Event.cpp +++ b/Swiften/EventLoop/Event.cpp @@ -10,13 +10,13 @@ #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 4585eb3..eecd896 100644 --- a/Swiften/EventLoop/Event.h +++ b/Swiften/EventLoop/Event.h @@ -12,19 +12,19 @@ #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) { - } + 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; - } + bool operator==(const Event& o) const { + return o.id == id; + } - unsigned int id; - boost::shared_ptr<EventOwner> owner; - boost::function<void()> callback; - }; + unsigned int id; + boost::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..2434277 100644 --- a/Swiften/EventLoop/EventLoop.cpp +++ b/Swiften/EventLoop/EventLoop.cpp @@ -23,16 +23,16 @@ 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 +42,59 @@ 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; + 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(); + } } 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(); - } + 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::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); + 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 2687501..84a3e9d 100644 --- a/Swiften/EventLoop/EventLoop.h +++ b/Swiften/EventLoop/EventLoop.h @@ -15,57 +15,57 @@ #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, 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); + /** + * The \ref removeEventsFromOwner method removes all events from the specified \ref owner from the + * event queue. + */ + void removeEventsFromOwner(boost::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_; + boost::recursive_mutex eventsMutex_; + boost::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..3f5e93c 100644 --- a/Swiften/EventLoop/Qt/QtEventLoop.h +++ b/Swiften/EventLoop/Qt/QtEventLoop.h @@ -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() { + 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_; + }; } diff --git a/Swiften/EventLoop/SimpleEventLoop.cpp b/Swiften/EventLoop/SimpleEventLoop.cpp index 59e799f..37fecd9 100644 --- a/Swiften/EventLoop/SimpleEventLoop.cpp +++ b/Swiften/EventLoop/SimpleEventLoop.cpp @@ -19,40 +19,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_) { + { + boost::unique_lock<boost::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(); + { + boost::unique_lock<boost::mutex> lock(eventAvailableMutex_); + eventAvailable_ = true; + } + eventAvailableCondition_.notify_one(); } diff --git a/Swiften/EventLoop/SimpleEventLoop.h b/Swiften/EventLoop/SimpleEventLoop.h index 6374a8a..98b3554 100644 --- a/Swiften/EventLoop/SimpleEventLoop.h +++ b/Swiften/EventLoop/SimpleEventLoop.h @@ -13,35 +13,35 @@ #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_; + boost::mutex eventAvailableMutex_; + boost::condition_variable eventAvailableCondition_; + }; } diff --git a/Swiften/EventLoop/SingleThreadedEventLoop.cpp b/Swiften/EventLoop/SingleThreadedEventLoop.cpp index c94b085..093b913 100644 --- a/Swiften/EventLoop/SingleThreadedEventLoop.cpp +++ b/Swiften/EventLoop/SingleThreadedEventLoop.cpp @@ -20,7 +20,7 @@ namespace Swift { -SingleThreadedEventLoop::SingleThreadedEventLoop() +SingleThreadedEventLoop::SingleThreadedEventLoop() : shouldShutDown_(false), eventAvailable_(false) { } @@ -30,33 +30,33 @@ SingleThreadedEventLoop::~SingleThreadedEventLoop() { } void SingleThreadedEventLoop::waitForEvents() { - boost::unique_lock<boost::mutex> lock(eventAvailableMutex_); - while (!eventAvailable_ && !shouldShutDown_) { - eventAvailableCondition_.wait(lock); - } + boost::unique_lock<boost::mutex> lock(eventAvailableMutex_); + while (!eventAvailable_ && !shouldShutDown_) { + eventAvailableCondition_.wait(lock); + } - if (shouldShutDown_) - throw EventLoopCanceledException(); + if (shouldShutDown_) + throw EventLoopCanceledException(); } void SingleThreadedEventLoop::handleEvents() { - { - boost::lock_guard<boost::mutex> lock(eventAvailableMutex_); - eventAvailable_ = false; - } - handleNextEvents(); + { + boost::lock_guard<boost::mutex> lock(eventAvailableMutex_); + eventAvailable_ = false; + } + handleNextEvents(); } void SingleThreadedEventLoop::stop() { - boost::unique_lock<boost::mutex> lock(eventAvailableMutex_); - shouldShutDown_ = true; - eventAvailableCondition_.notify_one(); + boost::unique_lock<boost::mutex> lock(eventAvailableMutex_); + shouldShutDown_ = true; + eventAvailableCondition_.notify_one(); } void SingleThreadedEventLoop::eventPosted() { - boost::lock_guard<boost::mutex> lock(eventAvailableMutex_); - eventAvailable_ = true; - eventAvailableCondition_.notify_one(); + 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 39f3fe3..eb897bf 100644 --- a/Swiften/EventLoop/SingleThreadedEventLoop.h +++ b/Swiften/EventLoop/SingleThreadedEventLoop.h @@ -29,39 +29,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 { }; + class SingleThreadedEventLoop : public EventLoop { + public: + class EventLoopCanceledException : public std::exception { }; + + public: + SingleThreadedEventLoop(); + virtual ~SingleThreadedEventLoop(); - 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(); - // 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(); - protected: - virtual void eventPosted(); - - private: - bool shouldShutDown_; + private: + bool shouldShutDown_; - bool eventAvailable_; - boost::mutex eventAvailableMutex_; - boost::condition_variable eventAvailableCondition_; - }; + bool eventAvailable_; + boost::mutex eventAvailableMutex_; + boost::condition_variable eventAvailableCondition_; + }; } diff --git a/Swiften/EventLoop/UnitTest/EventLoopTest.cpp b/Swiften/EventLoop/UnitTest/EventLoopTest.cpp index d1274e1..1028b7e 100644 --- a/Swiften/EventLoop/UnitTest/EventLoopTest.cpp +++ b/Swiften/EventLoop/UnitTest/EventLoopTest.cpp @@ -18,74 +18,74 @@ 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; + 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_REGISTRATION(EventLoopTest); diff --git a/Swiften/EventLoop/UnitTest/SimpleEventLoopTest.cpp b/Swiften/EventLoop/UnitTest/SimpleEventLoopTest.cpp index 1748953..167fe45 100644 --- a/Swiften/EventLoop/UnitTest/SimpleEventLoopTest.cpp +++ b/Swiften/EventLoop/UnitTest/SimpleEventLoopTest.cpp @@ -16,53 +16,53 @@ 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(); + 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; - } + public: + void setUp() { + counter_ = 0; + } - void testRun() { - SimpleEventLoop testling; - boost::thread thread(boost::bind(&SimpleEventLoopTest::runIncrementingThread, this, &testling)); - testling.run(); + void testRun() { + SimpleEventLoop testling; + boost::thread thread(boost::bind(&SimpleEventLoopTest::runIncrementingThread, this, &testling)); + testling.run(); - CPPUNIT_ASSERT_EQUAL(10, counter_); - } + CPPUNIT_ASSERT_EQUAL(10, counter_); + } - void testPostFromMainThread() { - SimpleEventLoop testling; - testling.postEvent(boost::bind(&SimpleEventLoopTest::incrementCounterAndStop, this, &testling)); - testling.run(); + void testPostFromMainThread() { + SimpleEventLoop testling; + testling.postEvent(boost::bind(&SimpleEventLoopTest::incrementCounterAndStop, this, &testling)); + testling.run(); - CPPUNIT_ASSERT_EQUAL(1, counter_); - } + 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(); - } + 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 incrementCounter() { + counter_++; + } - void incrementCounterAndStop(SimpleEventLoop* loop) { - counter_++; - loop->stop(); - } + void incrementCounterAndStop(SimpleEventLoop* loop) { + counter_++; + loop->stop(); + } - int counter_; + int counter_; }; CPPUNIT_TEST_SUITE_REGISTRATION(SimpleEventLoopTest); |