diff options
author | Stefan Radomski <github@mintwerk.de> | 2016-12-11 13:29:10 (GMT) |
---|---|---|
committer | Stefan Radomski <github@mintwerk.de> | 2016-12-11 13:29:10 (GMT) |
commit | 277ca19814890939d5d0e4551e3acb651b1c42e6 (patch) | |
tree | 8233c9a4ff2b4104bf5f5f744a723cb19fab4f29 /src/uscxml/interpreter | |
parent | 1c1e72a2af9c23dfd800d3a162142d6fac8dbd44 (diff) | |
download | uscxml-277ca19814890939d5d0e4551e3acb651b1c42e6.zip uscxml-277ca19814890939d5d0e4551e3acb651b1c42e6.tar.gz uscxml-277ca19814890939d5d0e4551e3acb651b1c42e6.tar.bz2 |
Reduced foreign header dependencies
Diffstat (limited to 'src/uscxml/interpreter')
-rw-r--r-- | src/uscxml/interpreter/BasicDelayedEventQueue.cpp | 171 | ||||
-rw-r--r-- | src/uscxml/interpreter/BasicDelayedEventQueue.h | 86 | ||||
-rw-r--r-- | src/uscxml/interpreter/BasicEventQueue.cpp | 142 | ||||
-rw-r--r-- | src/uscxml/interpreter/BasicEventQueue.h | 52 | ||||
-rw-r--r-- | src/uscxml/interpreter/ContentExecutor.h | 1 | ||||
-rw-r--r-- | src/uscxml/interpreter/ContentExecutorImpl.h | 10 | ||||
-rw-r--r-- | src/uscxml/interpreter/EventQueueImpl.h | 2 | ||||
-rw-r--r-- | src/uscxml/interpreter/InterpreterImpl.cpp | 1 | ||||
-rw-r--r-- | src/uscxml/interpreter/InterpreterImpl.h | 1 | ||||
-rw-r--r-- | src/uscxml/interpreter/InterpreterMonitor.h | 1 | ||||
-rw-r--r-- | src/uscxml/interpreter/MicroStep.h | 2 | ||||
-rw-r--r-- | src/uscxml/interpreter/MicroStepImpl.h | 3 |
12 files changed, 266 insertions, 206 deletions
diff --git a/src/uscxml/interpreter/BasicDelayedEventQueue.cpp b/src/uscxml/interpreter/BasicDelayedEventQueue.cpp new file mode 100644 index 0000000..3ad9ebd --- /dev/null +++ b/src/uscxml/interpreter/BasicDelayedEventQueue.cpp @@ -0,0 +1,171 @@ +/** + * @file + * @author 2016 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#include "BasicDelayedEventQueue.h" +#include <event2/util.h> // for evutil_socket_t +#include <event2/thread.h> +#include <assert.h> + +#include "uscxml/interpreter/Logging.h" + +namespace uscxml { + +static void dummyCallback(evutil_socket_t fd, short what, void *arg) { + timeval tv; + tv.tv_sec = 365 * 24 * 3600; + tv.tv_usec = 0; + event *ev = *(event **)arg; + evtimer_add(ev, &tv); +} + +BasicDelayedEventQueue::BasicDelayedEventQueue(DelayedEventQueueCallbacks* callbacks) { + _callbacks = callbacks; +#ifndef _WIN32 + evthread_use_pthreads(); +#else + evthread_use_windows_threads(); +#endif + _eventLoop = event_base_new(); + + // see here: https://github.com/named-data/ndn.cxx/blob/master/scheduler/scheduler.cc + // and here: https://www.mail-archive.com/libevent-users@seul.org/msg01676.html + timeval tv; + tv.tv_sec = 365 * 24 * 3600; + tv.tv_usec = 0; + _dummyEvent = evtimer_new(_eventLoop, dummyCallback, &_dummyEvent); + evtimer_add(_dummyEvent, &tv); + + _thread = NULL; + _isStarted = false; + start(); +} + +BasicDelayedEventQueue::~BasicDelayedEventQueue() { + stop(); + evtimer_del(_dummyEvent); + event_free(_dummyEvent); + event_base_free(_eventLoop); +} + +std::shared_ptr<DelayedEventQueueImpl> BasicDelayedEventQueue::create(DelayedEventQueueCallbacks* callbacks) { + return std::shared_ptr<DelayedEventQueueImpl>(new BasicDelayedEventQueue(callbacks)); +} + +void BasicDelayedEventQueue::timerCallback(evutil_socket_t fd, short what, void *arg) { + struct callbackData *data = (struct callbackData*)arg; + std::lock_guard<std::recursive_mutex> lock(data->eventQueue->_mutex); + + if (data->eventQueue->_callbackData.find(data->eventUUID) == data->eventQueue->_callbackData.end()) + return; + + event_free(data->event); + data->eventQueue->_callbacks->eventReady(data->userData, data->eventUUID); + data->eventQueue->_callbackData.erase(data->eventUUID); +} + +void BasicDelayedEventQueue::enqueueDelayed(const Event& event, size_t delayMs, const std::string& eventUUID) { + std::lock_guard<std::recursive_mutex> lock(_mutex); + if(_callbackData.find(eventUUID) != _callbackData.end()) { + cancelDelayed(eventUUID); + } + + _callbackData[eventUUID].eventUUID = eventUUID; + _callbackData[eventUUID].userData = event; + _callbackData[eventUUID].eventQueue = this; + + struct timeval delay = {static_cast<int32_t>(delayMs / 1000), static_cast<int32_t>((delayMs % 1000) * 1000)}; + struct event* e = event_new(_eventLoop, -1, 0, timerCallback, &_callbackData[eventUUID]); + + _callbackData[eventUUID].event = e; + + event_add(e, &delay); +} + +void BasicDelayedEventQueue::cancelAllDelayed() { + std::lock_guard<std::recursive_mutex> lock(_mutex); + + while(_callbackData.size() > 0) { + std::pair<std::string, callbackData> item = *_callbackData.begin(); + Event data = item.second.userData; + event_del(item.second.event); + event_free(item.second.event); + _callbackData.erase(item.first); + } + +} + +void BasicDelayedEventQueue::cancelDelayed(const std::string& eventId) { + std::lock_guard<std::recursive_mutex> lock(_mutex); + + if(_callbackData.find(eventId) != _callbackData.end()) { + event_del(_callbackData[eventId].event); + event_free(_callbackData[eventId].event); + _callbackData.erase(eventId); + } +} + +void BasicDelayedEventQueue::run(void* instance) { + BasicDelayedEventQueue* INSTANCE = (BasicDelayedEventQueue*)instance; + int result; + while(INSTANCE->_isStarted) { + /** + * EVLOOP_NO_EXIT_ON_EMPTY was removed in libevent2.1 - we are + * using the event in the far future approach to get blocking + * behavior back (see comments in contructor) + */ + + // #ifndef EVLOOP_NO_EXIT_ON_EMPTY +// result = event_base_dispatch(INSTANCE->_eventLoop); + // #else + // TODO: this is polling when no events are enqueued + result = event_base_loop(INSTANCE->_eventLoop, EVLOOP_ONCE); +// assert(false); // NON-BLOCKING?! + //#endif + (void)result; + } +} + +void BasicDelayedEventQueue::start() { + if (_isStarted) { + return; + } + _isStarted = true; + _thread = new std::thread(BasicDelayedEventQueue::run, this); +} + +void BasicDelayedEventQueue::stop() { + if (_isStarted) { + _isStarted = false; + event_base_loopbreak(_eventLoop); + cancelAllDelayed(); + } + if (_thread) { + _thread->join(); + delete _thread; + _thread = NULL; + } +} + +void BasicDelayedEventQueue::reset() { + std::lock_guard<std::recursive_mutex> lock(_mutex); + cancelAllDelayed(); + _queue.clear(); +} + +} diff --git a/src/uscxml/interpreter/BasicDelayedEventQueue.h b/src/uscxml/interpreter/BasicDelayedEventQueue.h new file mode 100644 index 0000000..8666e9c --- /dev/null +++ b/src/uscxml/interpreter/BasicDelayedEventQueue.h @@ -0,0 +1,86 @@ +/** + * @file + * @author 2016 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#ifndef BASICDELAYEDEVENTQUEUE_H_49D837C4 +#define BASICDELAYEDEVENTQUEUE_H_49D837C4 + +#include "BasicEventQueue.h" +#include <string> +#include <map> +#include <list> +#include <thread> +#include <mutex> +#include <condition_variable> + +#include <event2/event.h> + +namespace uscxml { + +/** + * @ingroup eventqueue + * @ingroup impl + */ +class USCXML_API BasicDelayedEventQueue : public BasicEventQueue, public DelayedEventQueueImpl { +public: + BasicDelayedEventQueue(DelayedEventQueueCallbacks* callbacks); + virtual ~BasicDelayedEventQueue(); + virtual std::shared_ptr<DelayedEventQueueImpl> create(DelayedEventQueueCallbacks* callbacks); + virtual void enqueueDelayed(const Event& event, size_t delayMs, const std::string& eventUUID); + virtual void cancelDelayed(const std::string& eventId); + virtual void cancelAllDelayed(); + virtual Event dequeue(size_t blockMs) { + return BasicEventQueue::dequeue(blockMs); + } + virtual void enqueue(const Event& event) { + return BasicEventQueue::enqueue(event); + } + virtual void reset(); + +protected: + virtual std::shared_ptr<EventQueueImpl> create() { + ErrorEvent e("Cannot create a DelayedEventQueue without callbacks"); + throw e; + } + + struct callbackData { + Event userData; + std::string eventUUID; + bool persist; + struct event *event; + BasicDelayedEventQueue* eventQueue; + }; + + bool _isStarted; + std::thread* _thread; + + std::map<std::string, callbackData> _callbackData; + struct event_base* _eventLoop; + struct event* _dummyEvent; + + static void run(void* instance); + void start(); + void stop(); + + static void timerCallback(evutil_socket_t fd, short what, void *arg); + DelayedEventQueueCallbacks* _callbacks; +}; + +} + +#endif /* end of include guard: BASICDELAYEDEVENTQUEUE_H_49D837C4 */ diff --git a/src/uscxml/interpreter/BasicEventQueue.cpp b/src/uscxml/interpreter/BasicEventQueue.cpp index 287266d..3b51117 100644 --- a/src/uscxml/interpreter/BasicEventQueue.cpp +++ b/src/uscxml/interpreter/BasicEventQueue.cpp @@ -69,146 +69,4 @@ std::shared_ptr<EventQueueImpl> BasicEventQueue::create() { return std::shared_ptr<EventQueueImpl>(new BasicEventQueue()); } -static void dummyCallback(evutil_socket_t fd, short what, void *arg) { - timeval tv; - tv.tv_sec = 365 * 24 * 3600; - tv.tv_usec = 0; - event *ev = *(event **)arg; - evtimer_add(ev, &tv); -} - -BasicDelayedEventQueue::BasicDelayedEventQueue(DelayedEventQueueCallbacks* callbacks) { - _callbacks = callbacks; -#ifndef _WIN32 - evthread_use_pthreads(); -#else - evthread_use_windows_threads(); -#endif - _eventLoop = event_base_new(); - - // see here: https://github.com/named-data/ndn.cxx/blob/master/scheduler/scheduler.cc - // and here: https://www.mail-archive.com/libevent-users@seul.org/msg01676.html - timeval tv; - tv.tv_sec = 365 * 24 * 3600; - tv.tv_usec = 0; - _dummyEvent = evtimer_new(_eventLoop, dummyCallback, &_dummyEvent); - evtimer_add(_dummyEvent, &tv); - - _thread = NULL; - _isStarted = false; - start(); -} - -BasicDelayedEventQueue::~BasicDelayedEventQueue() { - stop(); - evtimer_del(_dummyEvent); - event_free(_dummyEvent); - event_base_free(_eventLoop); -} - -std::shared_ptr<DelayedEventQueueImpl> BasicDelayedEventQueue::create(DelayedEventQueueCallbacks* callbacks) { - return std::shared_ptr<DelayedEventQueueImpl>(new BasicDelayedEventQueue(callbacks)); -} - -void BasicDelayedEventQueue::timerCallback(evutil_socket_t fd, short what, void *arg) { - struct callbackData *data = (struct callbackData*)arg; - std::lock_guard<std::recursive_mutex> lock(data->eventQueue->_mutex); - - if (data->eventQueue->_callbackData.find(data->eventUUID) == data->eventQueue->_callbackData.end()) - return; - - event_free(data->event); - data->eventQueue->_callbacks->eventReady(data->userData, data->eventUUID); - data->eventQueue->_callbackData.erase(data->eventUUID); -} - -void BasicDelayedEventQueue::enqueueDelayed(const Event& event, size_t delayMs, const std::string& eventUUID) { - std::lock_guard<std::recursive_mutex> lock(_mutex); - if(_callbackData.find(eventUUID) != _callbackData.end()) { - cancelDelayed(eventUUID); - } - - _callbackData[eventUUID].eventUUID = eventUUID; - _callbackData[eventUUID].userData = event; - _callbackData[eventUUID].eventQueue = this; - - struct timeval delay = {static_cast<int32_t>(delayMs / 1000), static_cast<int32_t>((delayMs % 1000) * 1000)}; - struct event* e = event_new(_eventLoop, -1, 0, timerCallback, &_callbackData[eventUUID]); - - _callbackData[eventUUID].event = e; - - event_add(e, &delay); -} - -void BasicDelayedEventQueue::cancelAllDelayed() { - std::lock_guard<std::recursive_mutex> lock(_mutex); - - while(_callbackData.size() > 0) { - std::pair<std::string, callbackData> item = *_callbackData.begin(); - Event data = item.second.userData; - event_del(item.second.event); - event_free(item.second.event); - _callbackData.erase(item.first); - } - -} - -void BasicDelayedEventQueue::cancelDelayed(const std::string& eventId) { - std::lock_guard<std::recursive_mutex> lock(_mutex); - - if(_callbackData.find(eventId) != _callbackData.end()) { - event_del(_callbackData[eventId].event); - event_free(_callbackData[eventId].event); - _callbackData.erase(eventId); - } -} - -void BasicDelayedEventQueue::run(void* instance) { - BasicDelayedEventQueue* INSTANCE = (BasicDelayedEventQueue*)instance; - int result; - while(INSTANCE->_isStarted) { - /** - * EVLOOP_NO_EXIT_ON_EMPTY was removed in libevent2.1 - we are - * using the event in the far future approach to get blocking - * behavior back (see comments in contructor) - */ - - // #ifndef EVLOOP_NO_EXIT_ON_EMPTY -// result = event_base_dispatch(INSTANCE->_eventLoop); - // #else - // TODO: this is polling when no events are enqueued - result = event_base_loop(INSTANCE->_eventLoop, EVLOOP_ONCE); -// assert(false); // NON-BLOCKING?! - //#endif - (void)result; - } -} - -void BasicDelayedEventQueue::start() { - if (_isStarted) { - return; - } - _isStarted = true; - _thread = new std::thread(BasicDelayedEventQueue::run, this); -} - -void BasicDelayedEventQueue::stop() { - if (_isStarted) { - _isStarted = false; - event_base_loopbreak(_eventLoop); - cancelAllDelayed(); - } - if (_thread) { - _thread->join(); - delete _thread; - _thread = NULL; - } -} - -void BasicDelayedEventQueue::reset() { - std::lock_guard<std::recursive_mutex> lock(_mutex); - cancelAllDelayed(); - _queue.clear(); -} - } diff --git a/src/uscxml/interpreter/BasicEventQueue.h b/src/uscxml/interpreter/BasicEventQueue.h index 5911336..f9b6965 100644 --- a/src/uscxml/interpreter/BasicEventQueue.h +++ b/src/uscxml/interpreter/BasicEventQueue.h @@ -28,9 +28,6 @@ #include <mutex> #include <condition_variable> -#include <event2/event.h> - - namespace uscxml { /** @@ -52,55 +49,6 @@ protected: std::condition_variable_any _cond; }; -/** - * @ingroup eventqueue - * @ingroup impl - */ -class USCXML_API BasicDelayedEventQueue : public BasicEventQueue, public DelayedEventQueueImpl { -public: - BasicDelayedEventQueue(DelayedEventQueueCallbacks* callbacks); - virtual ~BasicDelayedEventQueue(); - virtual std::shared_ptr<DelayedEventQueueImpl> create(DelayedEventQueueCallbacks* callbacks); - virtual void enqueueDelayed(const Event& event, size_t delayMs, const std::string& eventUUID); - virtual void cancelDelayed(const std::string& eventId); - virtual void cancelAllDelayed(); - virtual Event dequeue(size_t blockMs) { - return BasicEventQueue::dequeue(blockMs); - } - virtual void enqueue(const Event& event) { - return BasicEventQueue::enqueue(event); - } - virtual void reset(); - -protected: - virtual std::shared_ptr<EventQueueImpl> create() { - ErrorEvent e("Cannot create a DelayedEventQueue without callbacks"); - throw e; - } - - struct callbackData { - Event userData; - std::string eventUUID; - bool persist; - struct event *event; - BasicDelayedEventQueue* eventQueue; - }; - - bool _isStarted; - std::thread* _thread; - - std::map<std::string, callbackData> _callbackData; - struct event_base* _eventLoop; - struct event* _dummyEvent; - - static void run(void* instance); - void start(); - void stop(); - - static void timerCallback(evutil_socket_t fd, short what, void *arg); - DelayedEventQueueCallbacks* _callbacks; -}; - } #endif /* end of include guard: BASICEVENTQUEUE_H_39DCC18B */ diff --git a/src/uscxml/interpreter/ContentExecutor.h b/src/uscxml/interpreter/ContentExecutor.h index e17d8dc..ae8ec64 100644 --- a/src/uscxml/interpreter/ContentExecutor.h +++ b/src/uscxml/interpreter/ContentExecutor.h @@ -21,7 +21,6 @@ #define CONTENTEXECUTOR_H_A2D592FA -#include "uscxml/config.h" #include "uscxml/Common.h" #include "uscxml/messages/Data.h" #include <string> diff --git a/src/uscxml/interpreter/ContentExecutorImpl.h b/src/uscxml/interpreter/ContentExecutorImpl.h index 2cf8566..c085756 100644 --- a/src/uscxml/interpreter/ContentExecutorImpl.h +++ b/src/uscxml/interpreter/ContentExecutorImpl.h @@ -22,15 +22,21 @@ #include "uscxml/Common.h" -#include "uscxml/util/DOM.h" #include "uscxml/messages/Event.h" #include "uscxml/interpreter/InterpreterMonitor.h" -#include <xercesc/dom/DOM.hpp> #include <string> +#include <set> + +namespace XERCESC_NS { + class DOMDocument; + class DOMNode; +} namespace uscxml { +class X; + /** * @ingroup execcontent * @ingroup callback diff --git a/src/uscxml/interpreter/EventQueueImpl.h b/src/uscxml/interpreter/EventQueueImpl.h index 4420c24..68c6d7c 100644 --- a/src/uscxml/interpreter/EventQueueImpl.h +++ b/src/uscxml/interpreter/EventQueueImpl.h @@ -29,8 +29,6 @@ #include <mutex> #include <condition_variable> -#include <event2/event.h> - namespace uscxml { diff --git a/src/uscxml/interpreter/InterpreterImpl.cpp b/src/uscxml/interpreter/InterpreterImpl.cpp index 0f77285..85c77a8 100644 --- a/src/uscxml/interpreter/InterpreterImpl.cpp +++ b/src/uscxml/interpreter/InterpreterImpl.cpp @@ -23,6 +23,7 @@ #include "uscxml/Interpreter.h" #include "uscxml/interpreter/InterpreterImpl.h" // beware cyclic reference! #include "uscxml/interpreter/BasicEventQueue.h" +#include "uscxml/interpreter/BasicDelayedEventQueue.h" #include "uscxml/messages/Event.h" #include "uscxml/util/String.h" #include "uscxml/util/Predicates.h" diff --git a/src/uscxml/interpreter/InterpreterImpl.h b/src/uscxml/interpreter/InterpreterImpl.h index 9b784d3..ade2a91 100644 --- a/src/uscxml/interpreter/InterpreterImpl.h +++ b/src/uscxml/interpreter/InterpreterImpl.h @@ -35,7 +35,6 @@ #include "uscxml/interpreter/EventQueue.h" #include "uscxml/interpreter/EventQueueImpl.h" #include "uscxml/util/DOM.h" -#include <xercesc/dom/DOM.hpp> namespace uscxml { diff --git a/src/uscxml/interpreter/InterpreterMonitor.h b/src/uscxml/interpreter/InterpreterMonitor.h index 80065f7..a3c527d 100644 --- a/src/uscxml/interpreter/InterpreterMonitor.h +++ b/src/uscxml/interpreter/InterpreterMonitor.h @@ -20,7 +20,6 @@ #ifndef INTERPRETERMONITOR_H_D3F21429 #define INTERPRETERMONITOR_H_D3F21429 -#include "uscxml/config.h" #include "uscxml/Common.h" #include "uscxml/messages/Event.h" #include "uscxml/debug/InterpreterIssue.h" diff --git a/src/uscxml/interpreter/MicroStep.h b/src/uscxml/interpreter/MicroStep.h index 341be2e..9238fc8 100644 --- a/src/uscxml/interpreter/MicroStep.h +++ b/src/uscxml/interpreter/MicroStep.h @@ -25,11 +25,9 @@ #include <list> #include <string> -#include "uscxml/config.h" #include "uscxml/Common.h" #include "uscxml/interpreter/InterpreterState.h" -// #include <xercesc/dom/DOM.hpp> // forward declare namespace XERCESC_NS { diff --git a/src/uscxml/interpreter/MicroStepImpl.h b/src/uscxml/interpreter/MicroStepImpl.h index d831fdd..110dbd2 100644 --- a/src/uscxml/interpreter/MicroStepImpl.h +++ b/src/uscxml/interpreter/MicroStepImpl.h @@ -20,12 +20,9 @@ #ifndef MICROSTEPIMPL_H_98233709 #define MICROSTEPIMPL_H_98233709 -#include "uscxml/config.h" - #include <list> #include <set> #include <string> -#include <xercesc/dom/DOM.hpp> #include "uscxml/Common.h" #include "uscxml/Interpreter.h" |