diff options
| -rw-r--r-- | Swiften/EventLoop/BoostASIOEventLoop.cpp | 4 | ||||
| -rw-r--r-- | Swiften/EventLoop/Cocoa/CocoaEventLoop.mm | 4 | ||||
| -rw-r--r-- | Swiften/EventLoop/DummyEventLoop.cpp | 4 | ||||
| -rw-r--r-- | Swiften/EventLoop/EventLoop.cpp | 21 | ||||
| -rw-r--r-- | Swiften/EventLoop/EventLoop.h | 11 | ||||
| -rw-r--r-- | Swiften/EventLoop/Qt/QtEventLoop.h | 4 | ||||
| -rw-r--r-- | Swiften/EventLoop/SimpleEventLoop.cpp | 4 | ||||
| -rw-r--r-- | Swiften/EventLoop/SingleThreadedEventLoop.cpp | 4 | ||||
| -rw-r--r-- | Swiften/EventLoop/UnitTest/EventLoopTest.cpp | 13 |
9 files changed, 39 insertions, 30 deletions
diff --git a/Swiften/EventLoop/BoostASIOEventLoop.cpp b/Swiften/EventLoop/BoostASIOEventLoop.cpp index 30143b9..45dd4a2 100644 --- a/Swiften/EventLoop/BoostASIOEventLoop.cpp +++ b/Swiften/EventLoop/BoostASIOEventLoop.cpp @@ -1,8 +1,8 @@ /* - * Copyright (c) 2015-2016 Isode Limited. + * Copyright (c) 2015-2019 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/EventLoop/BoostASIOEventLoop.h> @@ -20,13 +20,13 @@ BoostASIOEventLoop::~BoostASIOEventLoop() { void BoostASIOEventLoop::handleASIOEvent() { { std::unique_lock<std::recursive_mutex> lock(isEventInASIOEventLoopMutex_); isEventInASIOEventLoop_ = false; } - handleNextEvents(); + handleNextEvent(); } void BoostASIOEventLoop::eventPosted() { std::unique_lock<std::recursive_mutex> lock(isEventInASIOEventLoopMutex_); if (!isEventInASIOEventLoop_) { isEventInASIOEventLoop_ = true; diff --git a/Swiften/EventLoop/Cocoa/CocoaEventLoop.mm b/Swiften/EventLoop/Cocoa/CocoaEventLoop.mm index b8ab621..39dc7ec 100644 --- a/Swiften/EventLoop/Cocoa/CocoaEventLoop.mm +++ b/Swiften/EventLoop/Cocoa/CocoaEventLoop.mm @@ -1,8 +1,8 @@ /* - * Copyright (c) 2015-2016 Isode Limited. + * Copyright (c) 2015-2019 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/EventLoop/Cocoa/CocoaEventLoop.h> #include <Swiften/EventLoop/Cocoa/CocoaEvent.h> @@ -20,13 +20,13 @@ CocoaEventLoop::~CocoaEventLoop() { void CocoaEventLoop::handleNextCocoaEvent() { { std::unique_lock<std::recursive_mutex> lock(isEventInCocoaEventLoopMutex_); isEventInCocoaEventLoop_ = false; } - handleNextEvents(); + handleNextEvent(); } void CocoaEventLoop::eventPosted() { std::unique_lock<std::recursive_mutex> lock(isEventInCocoaEventLoopMutex_); if (!isEventInCocoaEventLoop_) { isEventInCocoaEventLoop_ = true; diff --git a/Swiften/EventLoop/DummyEventLoop.cpp b/Swiften/EventLoop/DummyEventLoop.cpp index 4dfbac3..4712fad 100644 --- a/Swiften/EventLoop/DummyEventLoop.cpp +++ b/Swiften/EventLoop/DummyEventLoop.cpp @@ -1,8 +1,8 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2019 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/EventLoop/DummyEventLoop.h> @@ -19,13 +19,13 @@ DummyEventLoop::~DummyEventLoop() { } } void DummyEventLoop::processEvents() { while(hasEvents()) { hasEvents_ = false; - handleNextEvents(); + handleNextEvent(); } } bool DummyEventLoop::hasEvents() { return hasEvents_; } diff --git a/Swiften/EventLoop/EventLoop.cpp b/Swiften/EventLoop/EventLoop.cpp index f6af699..31c93e9 100644 --- a/Swiften/EventLoop/EventLoop.cpp +++ b/Swiften/EventLoop/EventLoop.cpp @@ -1,8 +1,8 @@ /* - * Copyright (c) 2010-2018 Isode Limited. + * Copyright (c) 2010-2019 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/EventLoop/EventLoop.h> @@ -32,35 +32,32 @@ inline void invokeCallback(const Event& event) { EventLoop::EventLoop() : nextEventID_(0), handlingEvents_(false) { } 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 +void EventLoop::handleNextEvent() { + // If handleNextEvent 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; + boost::optional<Event> nextEvent; { - std::unique_lock<std::recursive_mutex> lock(eventsMutex_); - for (int n = 0; ((n < eventsBatched) && !events_.empty()); n++) { - nextEvents.push_back(events_.front()); + std::unique_lock<std::recursive_mutex> eventsLock(eventsMutex_); + if (!events_.empty()) { + nextEvent = events_.front(); events_.pop_front(); } callEventPosted = !events_.empty(); } - if (!nextEvents.empty()) { - for (const auto& event : nextEvents) { - invokeCallback(event); - } + if (nextEvent) { + invokeCallback(*nextEvent); } } handlingEvents_ = false; } if (callEventPosted) { diff --git a/Swiften/EventLoop/EventLoop.h b/Swiften/EventLoop/EventLoop.h index 06b9fbb..f61b9bc 100644 --- a/Swiften/EventLoop/EventLoop.h +++ b/Swiften/EventLoop/EventLoop.h @@ -1,8 +1,8 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2019 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once @@ -40,27 +40,26 @@ namespace Swift { * 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 + * 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. - * 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 + * It is recommended to not call \ref handleNextEvent inside an event posted to the event loop * as this can lead to an infinite loop. */ - void handleNextEvents(); + void handleNextEvent(); /** * 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. + * \ref handleNextEvent and there are still remaining events in the queue. */ virtual void eventPosted() = 0; private: unsigned int nextEventID_; std::list<Event> events_; diff --git a/Swiften/EventLoop/Qt/QtEventLoop.h b/Swiften/EventLoop/Qt/QtEventLoop.h index b1644c2..cf374ab 100644 --- a/Swiften/EventLoop/Qt/QtEventLoop.h +++ b/Swiften/EventLoop/Qt/QtEventLoop.h @@ -1,8 +1,8 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2019 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once @@ -35,13 +35,13 @@ namespace Swift { Event* event = dynamic_cast<Event*>(qevent); if (event) { { std::unique_lock<std::recursive_mutex> lock(isEventInQtEventLoopMutex_); isEventInQtEventLoop_ = false; } - handleNextEvents(); + handleNextEvent(); //event->deleteLater(); FIXME: Leak? return true; } return false; } diff --git a/Swiften/EventLoop/SimpleEventLoop.cpp b/Swiften/EventLoop/SimpleEventLoop.cpp index cac04e4..745fadb 100644 --- a/Swiften/EventLoop/SimpleEventLoop.cpp +++ b/Swiften/EventLoop/SimpleEventLoop.cpp @@ -1,8 +1,8 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2019 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/EventLoop/SimpleEventLoop.h> @@ -31,13 +31,13 @@ void SimpleEventLoop::doRun(bool breakAfterEvents) { return; } } } void SimpleEventLoop::runOnce() { - handleNextEvents(); + handleNextEvent(); } void SimpleEventLoop::stop() { postEvent(boost::bind(&SimpleEventLoop::doStop, this)); } diff --git a/Swiften/EventLoop/SingleThreadedEventLoop.cpp b/Swiften/EventLoop/SingleThreadedEventLoop.cpp index 0542f37..89b4460 100644 --- a/Swiften/EventLoop/SingleThreadedEventLoop.cpp +++ b/Swiften/EventLoop/SingleThreadedEventLoop.cpp @@ -2,13 +2,13 @@ * Copyright (c) 2010 Soren Dreijer * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* - * Copyright (c) 2016 Isode Limited. + * Copyright (c) 2016-2019 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/EventLoop/SingleThreadedEventLoop.h> @@ -40,13 +40,13 @@ void SingleThreadedEventLoop::waitForEvents() { void SingleThreadedEventLoop::handleEvents() { { std::lock_guard<std::mutex> lock(eventAvailableMutex_); eventAvailable_ = false; } - handleNextEvents(); + handleNextEvent(); } void SingleThreadedEventLoop::stop() { std::unique_lock<std::mutex> lock(eventAvailableMutex_); shouldShutDown_ = true; eventAvailableCondition_.notify_one(); diff --git a/Swiften/EventLoop/UnitTest/EventLoopTest.cpp b/Swiften/EventLoop/UnitTest/EventLoopTest.cpp index 00a4376..26c56d3 100644 --- a/Swiften/EventLoop/UnitTest/EventLoopTest.cpp +++ b/Swiften/EventLoop/UnitTest/EventLoopTest.cpp @@ -20,12 +20,13 @@ using namespace Swift; class EventLoopTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(EventLoopTest); CPPUNIT_TEST(testPost); CPPUNIT_TEST(testRemove); CPPUNIT_TEST(testHandleEvent_Recursive); + CPPUNIT_TEST(testHandleEvent_FirstEventRemovesSecondEvent); CPPUNIT_TEST_SUITE_END(); public: void setUp() { events_.clear(); } @@ -71,12 +72,24 @@ class EventLoopTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(events_.size())); CPPUNIT_ASSERT_EQUAL(0, events_[0]); CPPUNIT_ASSERT_EQUAL(1, events_[1]); } + void testHandleEvent_FirstEventRemovesSecondEvent() { + DummyEventLoop testling; + auto eventOwner = std::make_shared<MyEventOwner>(); + auto secondEventFired = false; + + testling.postEvent([&](){ testling.removeEventsFromOwner(eventOwner); }, eventOwner); + testling.postEvent([&](){ secondEventFired = true; }, eventOwner); + testling.processEvents(); + + CPPUNIT_ASSERT_EQUAL(false, secondEventFired); + } + private: struct MyEventOwner : public EventOwner {}; void logEvent(int i) { events_.push_back(i); } void runEventLoop(DummyEventLoop* loop, std::shared_ptr<MyEventOwner> eventOwner) { |
Swift