diff options
author | Remko Tronçon <git@el-tramo.be> | 2010-10-07 18:35:10 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2010-10-07 18:35:10 (GMT) |
commit | e433e70d3dd015db5124ee72085e758635260168 (patch) | |
tree | 1d5d151deb2e474b841bbf9c92eeaa3690cd86d4 /Swiften/EventLoop/EventLoop.cpp | |
parent | 83c5c774b9e71133401e574b1ca7fc6d766bc492 (diff) | |
download | swift-contrib-e433e70d3dd015db5124ee72085e758635260168.zip swift-contrib-e433e70d3dd015db5124ee72085e758635260168.tar.bz2 |
Avoid recursive calling of event callbacks.
When EventLoop::handleEvent() was called recursively (i.e. by calling
processEvents() from a slot), weird things happened, especially in the
XMPP parser (assertion triggers, parse error from server, ...). Now, callbacks
are put in a queue handled by the topmost handleEvent.
Resolves: #592, #568
Diffstat (limited to 'Swiften/EventLoop/EventLoop.cpp')
-rw-r--r-- | Swiften/EventLoop/EventLoop.cpp | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/Swiften/EventLoop/EventLoop.cpp b/Swiften/EventLoop/EventLoop.cpp index 25dd19a..2e9e021 100644 --- a/Swiften/EventLoop/EventLoop.cpp +++ b/Swiften/EventLoop/EventLoop.cpp @@ -8,12 +8,13 @@ #include <algorithm> #include <boost/bind.hpp> +#include <iostream> #include "Swiften/EventLoop/MainEventLoop.h" namespace Swift { -EventLoop::EventLoop() : nextEventID_(0) { +EventLoop::EventLoop() : nextEventID_(0), handlingEvents_(false) { MainEventLoop::setInstance(this); } @@ -22,6 +23,13 @@ EventLoop::~EventLoop() { } void EventLoop::handleEvent(const Event& event) { + if (handlingEvents_) { + // We're being called recursively. Push in the list of events to + // handle in the parent handleEvent() + eventsToHandle_.push_back(event); + return; + } + bool doCallback = false; { boost::lock_guard<boost::mutex> lock(eventsMutex_); @@ -32,7 +40,16 @@ void EventLoop::handleEvent(const Event& event) { } } if (doCallback) { + handlingEvents_ = true; event.callback(); + // Process events that were passed to handleEvent during the callback + // (i.e. through recursive calls of handleEvent) + while (!eventsToHandle_.empty()) { + Event nextEvent = eventsToHandle_.front(); + eventsToHandle_.pop_front(); + nextEvent.callback(); + } + handlingEvents_ = false; } } |