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,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) {