summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Swiften/EventLoop/BoostASIOEventLoop.cpp4
-rw-r--r--Swiften/EventLoop/Cocoa/CocoaEventLoop.mm4
-rw-r--r--Swiften/EventLoop/DummyEventLoop.cpp4
-rw-r--r--Swiften/EventLoop/EventLoop.cpp21
-rw-r--r--Swiften/EventLoop/EventLoop.h11
-rw-r--r--Swiften/EventLoop/Qt/QtEventLoop.h4
-rw-r--r--Swiften/EventLoop/SimpleEventLoop.cpp4
-rw-r--r--Swiften/EventLoop/SingleThreadedEventLoop.cpp4
-rw-r--r--Swiften/EventLoop/UnitTest/EventLoopTest.cpp13
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
29void BoostASIOEventLoop::eventPosted() { 29void 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
29void CocoaEventLoop::eventPosted() { 29void 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() {
22void DummyEventLoop::processEvents() { 22void 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) {
35EventLoop::~EventLoop() { 35EventLoop::~EventLoop() {
36} 36}
37 37
38void EventLoop::handleNextEvents() { 38void 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
36void SimpleEventLoop::runOnce() { 36void SimpleEventLoop::runOnce() {
37 handleNextEvents(); 37 handleNextEvent();
38} 38}
39 39
40void SimpleEventLoop::stop() { 40void 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
49void SingleThreadedEventLoop::stop() { 49void 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) {