diff options
Diffstat (limited to 'Swiften/EventLoop/EventLoop.cpp')
-rw-r--r-- | Swiften/EventLoop/EventLoop.cpp | 77 |
1 files changed, 38 insertions, 39 deletions
diff --git a/Swiften/EventLoop/EventLoop.cpp b/Swiften/EventLoop/EventLoop.cpp index 0b50e82..d9a9081 100644 --- a/Swiften/EventLoop/EventLoop.cpp +++ b/Swiften/EventLoop/EventLoop.cpp @@ -1,20 +1,21 @@ /* - * Copyright (c) 2010-2013 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/EventLoop/EventLoop.h> #include <algorithm> -#include <iostream> #include <cassert> + #include <boost/bind.hpp> -#include <boost/lambda/lambda.hpp> #include <boost/lambda/bind.hpp> +#include <boost/lambda/lambda.hpp> +#include <boost/optional.hpp> #include <boost/thread/locks.hpp> #include <Swiften/Base/Log.h> namespace lambda = boost::lambda; @@ -23,71 +24,69 @@ namespace Swift { inline void invokeCallback(const Event& event) { try { assert(!event.callback.empty()); event.callback(); } catch (const std::exception& e) { - std::cerr << "Uncaught exception in event loop: " << e.what() << std::endl; + SWIFT_LOG(error) << "Uncaught exception in event loop: " << e.what() << std::endl; } catch (...) { - std::cerr << "Uncaught non-exception in event loop" << std::endl; + SWIFT_LOG(error) << "Uncaught non-exception in event loop" << std::endl; } } -EventLoop::EventLoop() : nextEventID_(0), handlingEvents_(false) { +EventLoop::EventLoop() : nextEventID_(0) { } EventLoop::~EventLoop() { } -void EventLoop::handleEvent(const Event& event) { - //SWIFT_LOG(debug) << "Handling event " << event.id << std::endl; - - 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; +void EventLoop::handleNextEvent() { + bool callEventPosted = false; { - boost::lock_guard<boost::mutex> lock(eventsMutex_); - std::list<Event>::iterator i = std::find(events_.begin(), events_.end(), event); - if (i != events_.end()) { - doCallback = true; - events_.erase(i); + boost::recursive_mutex::scoped_lock lock(removeEventsMutex_); + { + boost::optional<Event> nextEvent; + { + boost::recursive_mutex::scoped_lock lock(eventsMutex_); + if (!events_.empty()) { + nextEvent = events_.front(); + events_.pop_front(); + } + } + callEventPosted = !events_.empty(); + if (nextEvent) { + invokeCallback(nextEvent.get()); + } } + } - if (doCallback) { - handlingEvents_ = true; - invokeCallback(event); - - // 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(); - invokeCallback(nextEvent); - } - handlingEvents_ = false; + + if (callEventPosted) { + eventPosted(); } } void EventLoop::postEvent(boost::function<void ()> callback, boost::shared_ptr<EventOwner> owner) { Event event(owner, callback); + bool callEventPosted = false; { - boost::lock_guard<boost::mutex> lock(eventsMutex_); + boost::recursive_mutex::scoped_lock lock(eventsMutex_); + + callEventPosted = events_.empty(); + event.id = nextEventID_; nextEventID_++; events_.push_back(event); } - //SWIFT_LOG(debug) << "Posting event " << event.id << std::endl; - post(event); + if (callEventPosted) { + eventPosted(); + } } void EventLoop::removeEventsFromOwner(boost::shared_ptr<EventOwner> owner) { - boost::lock_guard<boost::mutex> lock(eventsMutex_); - events_.remove_if(lambda::bind(&Event::owner, lambda::_1) == owner); + boost::recursive_mutex::scoped_lock removeLock(removeEventsMutex_); + boost::recursive_mutex::scoped_lock lock(eventsMutex_); + events_.remove_if(lambda::bind(&Event::owner, lambda::_1) == owner); } } |