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,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2015-2016 Isode Limited. | 2 | * Copyright (c) 2015-2019 Isode Limited. |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * See the COPYING file for more information. | 4 | * See the COPYING file for more information. |
| 5 | */ | 5 | */ |
| @@ -23,7 +23,7 @@ void BoostASIOEventLoop::handleASIOEvent() { | |||
| 23 | std::unique_lock<std::recursive_mutex> lock(isEventInASIOEventLoopMutex_); | 23 | std::unique_lock<std::recursive_mutex> lock(isEventInASIOEventLoopMutex_); |
| 24 | isEventInASIOEventLoop_ = false; | 24 | isEventInASIOEventLoop_ = false; |
| 25 | } | 25 | } |
| 26 | handleNextEvents(); | 26 | handleNextEvent(); |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | void BoostASIOEventLoop::eventPosted() { | 29 | void BoostASIOEventLoop::eventPosted() { |
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,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2015-2016 Isode Limited. | 2 | * Copyright (c) 2015-2019 Isode Limited. |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * See the COPYING file for more information. | 4 | * See the COPYING file for more information. |
| 5 | */ | 5 | */ |
| @@ -23,7 +23,7 @@ void CocoaEventLoop::handleNextCocoaEvent() { | |||
| 23 | std::unique_lock<std::recursive_mutex> lock(isEventInCocoaEventLoopMutex_); | 23 | std::unique_lock<std::recursive_mutex> lock(isEventInCocoaEventLoopMutex_); |
| 24 | isEventInCocoaEventLoop_ = false; | 24 | isEventInCocoaEventLoop_ = false; |
| 25 | } | 25 | } |
| 26 | handleNextEvents(); | 26 | handleNextEvent(); |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | void CocoaEventLoop::eventPosted() { | 29 | void CocoaEventLoop::eventPosted() { |
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,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2010-2016 Isode Limited. | 2 | * Copyright (c) 2010-2019 Isode Limited. |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * See the COPYING file for more information. | 4 | * See the COPYING file for more information. |
| 5 | */ | 5 | */ |
| @@ -22,7 +22,7 @@ DummyEventLoop::~DummyEventLoop() { | |||
| 22 | void DummyEventLoop::processEvents() { | 22 | void DummyEventLoop::processEvents() { |
| 23 | while(hasEvents()) { | 23 | while(hasEvents()) { |
| 24 | hasEvents_ = false; | 24 | hasEvents_ = false; |
| 25 | handleNextEvents(); | 25 | handleNextEvent(); |
| 26 | } | 26 | } |
| 27 | } | 27 | } |
| 28 | 28 | ||
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,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2010-2018 Isode Limited. | 2 | * Copyright (c) 2010-2019 Isode Limited. |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * See the COPYING file for more information. | 4 | * See the COPYING file for more information. |
| 5 | */ | 5 | */ |
| @@ -35,9 +35,8 @@ EventLoop::EventLoop() : nextEventID_(0), handlingEvents_(false) { | |||
| 35 | EventLoop::~EventLoop() { | 35 | EventLoop::~EventLoop() { |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | void EventLoop::handleNextEvents() { | 38 | void EventLoop::handleNextEvent() { |
| 39 | const int eventsBatched = 100; | 39 | // If handleNextEvent is already in progress, e.g. in case of a recursive call due to |
| 40 | // If handleNextEvents is already in progress, e.g. in case of a recursive call due to | ||
| 41 | // the event loop implementation, then do no handle further events. Instead call | 40 | // the event loop implementation, then do no handle further events. Instead call |
| 42 | // eventPosted() to continue event handling later. | 41 | // eventPosted() to continue event handling later. |
| 43 | bool callEventPosted = handlingEvents_; | 42 | bool callEventPosted = handlingEvents_; |
| @@ -45,19 +44,17 @@ void EventLoop::handleNextEvents() { | |||
| 45 | handlingEvents_ = true; | 44 | handlingEvents_ = true; |
| 46 | std::unique_lock<std::recursive_mutex> lock(removeEventsMutex_); | 45 | std::unique_lock<std::recursive_mutex> lock(removeEventsMutex_); |
| 47 | { | 46 | { |
| 48 | std::vector<Event> nextEvents; | 47 | boost::optional<Event> nextEvent; |
| 49 | { | 48 | { |
| 50 | std::unique_lock<std::recursive_mutex> lock(eventsMutex_); | 49 | std::unique_lock<std::recursive_mutex> eventsLock(eventsMutex_); |
| 51 | for (int n = 0; ((n < eventsBatched) && !events_.empty()); n++) { | 50 | if (!events_.empty()) { |
| 52 | nextEvents.push_back(events_.front()); | 51 | nextEvent = events_.front(); |
| 53 | events_.pop_front(); | 52 | events_.pop_front(); |
| 54 | } | 53 | } |
| 55 | callEventPosted = !events_.empty(); | 54 | callEventPosted = !events_.empty(); |
| 56 | } | 55 | } |
| 57 | if (!nextEvents.empty()) { | 56 | if (nextEvent) { |
| 58 | for (const auto& event : nextEvents) { | 57 | invokeCallback(*nextEvent); |
| 59 | invokeCallback(event); | ||
| 60 | } | ||
| 61 | } | 58 | } |
| 62 | } | 59 | } |
| 63 | handlingEvents_ = false; | 60 | handlingEvents_ = false; |
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,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2010-2016 Isode Limited. | 2 | * Copyright (c) 2010-2019 Isode Limited. |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * See the COPYING file for more information. | 4 | * See the COPYING file for more information. |
| 5 | */ | 5 | */ |
| @@ -43,21 +43,20 @@ namespace Swift { | |||
| 43 | 43 | ||
| 44 | protected: | 44 | protected: |
| 45 | /** | 45 | /** |
| 46 | * The \ref handleNextEvents method is called by an implementation of the abstract \ref EventLoop class | 46 | * The \ref handleNextEvent method is called by an implementation of the abstract \ref EventLoop class |
| 47 | * at any point after the virtual \ref eventPosted method has been called. | 47 | * at any point after the virtual \ref eventPosted method has been called. |
| 48 | * This method does not block, except for short-time synchronization. | 48 | * This method does not block, except for short-time synchronization. |
| 49 | * It can process multiple events before it reutrns. | ||
| 50 | * If called recursively, the event queue is not further processed. Instead, \ref eventPosted | 49 | * If called recursively, the event queue is not further processed. Instead, \ref eventPosted |
| 51 | * is called to notify the implementing event loop of the non-empty event queue. | 50 | * is called to notify the implementing event loop of the non-empty event queue. |
| 52 | * It is recommended to not call \ref handleNextEvents inside an event posted to the event loop | 51 | * It is recommended to not call \ref handleNextEvent inside an event posted to the event loop |
| 53 | * as this can lead to an infinite loop. | 52 | * as this can lead to an infinite loop. |
| 54 | */ | 53 | */ |
| 55 | void handleNextEvents(); | 54 | void handleNextEvent(); |
| 56 | 55 | ||
| 57 | /** | 56 | /** |
| 58 | * The \ref eventPosted virtual method serves as notification for when events are still available in the queue. | 57 | * The \ref eventPosted virtual method serves as notification for when events are still available in the queue. |
| 59 | * It is called after the first event is posted to an empty queue or after an event has been handled in | 58 | * It is called after the first event is posted to an empty queue or after an event has been handled in |
| 60 | * \ref handleNextEvents and there are still remaining events in the queue. | 59 | * \ref handleNextEvent and there are still remaining events in the queue. |
| 61 | */ | 60 | */ |
| 62 | virtual void eventPosted() = 0; | 61 | virtual void eventPosted() = 0; |
| 63 | 62 | ||
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,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2010-2016 Isode Limited. | 2 | * Copyright (c) 2010-2019 Isode Limited. |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * See the COPYING file for more information. | 4 | * See the COPYING file for more information. |
| 5 | */ | 5 | */ |
| @@ -38,7 +38,7 @@ namespace Swift { | |||
| 38 | std::unique_lock<std::recursive_mutex> lock(isEventInQtEventLoopMutex_); | 38 | std::unique_lock<std::recursive_mutex> lock(isEventInQtEventLoopMutex_); |
| 39 | isEventInQtEventLoop_ = false; | 39 | isEventInQtEventLoop_ = false; |
| 40 | } | 40 | } |
| 41 | handleNextEvents(); | 41 | handleNextEvent(); |
| 42 | //event->deleteLater(); FIXME: Leak? | 42 | //event->deleteLater(); FIXME: Leak? |
| 43 | return true; | 43 | return true; |
| 44 | } | 44 | } |
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,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2010-2016 Isode Limited. | 2 | * Copyright (c) 2010-2019 Isode Limited. |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * See the COPYING file for more information. | 4 | * See the COPYING file for more information. |
| 5 | */ | 5 | */ |
| @@ -34,7 +34,7 @@ void SimpleEventLoop::doRun(bool breakAfterEvents) { | |||
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | void SimpleEventLoop::runOnce() { | 36 | void SimpleEventLoop::runOnce() { |
| 37 | handleNextEvents(); | 37 | handleNextEvent(); |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | void SimpleEventLoop::stop() { | 40 | void SimpleEventLoop::stop() { |
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 | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | /* | 7 | /* |
| 8 | * Copyright (c) 2016 Isode Limited. | 8 | * Copyright (c) 2016-2019 Isode Limited. |
| 9 | * All rights reserved. | 9 | * All rights reserved. |
| 10 | * See the COPYING file for more information. | 10 | * See the COPYING file for more information. |
| 11 | */ | 11 | */ |
| @@ -43,7 +43,7 @@ void SingleThreadedEventLoop::handleEvents() { | |||
| 43 | std::lock_guard<std::mutex> lock(eventAvailableMutex_); | 43 | std::lock_guard<std::mutex> lock(eventAvailableMutex_); |
| 44 | eventAvailable_ = false; | 44 | eventAvailable_ = false; |
| 45 | } | 45 | } |
| 46 | handleNextEvents(); | 46 | handleNextEvent(); |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | void SingleThreadedEventLoop::stop() { | 49 | void SingleThreadedEventLoop::stop() { |
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 | |||
| @@ -23,6 +23,7 @@ class EventLoopTest : public CppUnit::TestFixture { | |||
| 23 | CPPUNIT_TEST(testPost); | 23 | CPPUNIT_TEST(testPost); |
| 24 | CPPUNIT_TEST(testRemove); | 24 | CPPUNIT_TEST(testRemove); |
| 25 | CPPUNIT_TEST(testHandleEvent_Recursive); | 25 | CPPUNIT_TEST(testHandleEvent_Recursive); |
| 26 | CPPUNIT_TEST(testHandleEvent_FirstEventRemovesSecondEvent); | ||
| 26 | CPPUNIT_TEST_SUITE_END(); | 27 | CPPUNIT_TEST_SUITE_END(); |
| 27 | 28 | ||
| 28 | public: | 29 | public: |
| @@ -74,6 +75,18 @@ class EventLoopTest : public CppUnit::TestFixture { | |||
| 74 | CPPUNIT_ASSERT_EQUAL(1, events_[1]); | 75 | CPPUNIT_ASSERT_EQUAL(1, events_[1]); |
| 75 | } | 76 | } |
| 76 | 77 | ||
| 78 | void testHandleEvent_FirstEventRemovesSecondEvent() { | ||
| 79 | DummyEventLoop testling; | ||
| 80 | auto eventOwner = std::make_shared<MyEventOwner>(); | ||
| 81 | auto secondEventFired = false; | ||
| 82 | |||
| 83 | testling.postEvent([&](){ testling.removeEventsFromOwner(eventOwner); }, eventOwner); | ||
| 84 | testling.postEvent([&](){ secondEventFired = true; }, eventOwner); | ||
| 85 | testling.processEvents(); | ||
| 86 | |||
| 87 | CPPUNIT_ASSERT_EQUAL(false, secondEventFired); | ||
| 88 | } | ||
| 89 | |||
| 77 | private: | 90 | private: |
| 78 | struct MyEventOwner : public EventOwner {}; | 91 | struct MyEventOwner : public EventOwner {}; |
| 79 | void logEvent(int i) { | 92 | void logEvent(int i) { |
Swift