#pragma once #include "globalincs/pstypes.h" #include "tracing/tracing.h" #include "utils/boost/syncboundedqueue.h" #include /** @file * @ingroup tracing */ namespace tracing { /** * @brief A multi-threaded event processor * * This is a utility class that can be used to implement an event processor that uses a different thread to process the * events. To use this, declare your class with a method with the signature * * @code{.cpp} * void processEvent(const trace_event* event) * @endcode * * This function will be called in a background-thread whenever a new event arrives. * * @tparam Processor Your processor implementation * @tparam QUEUE_SIZE The maximum size of the internal event buffer */ template class ThreadedEventProcessor { sync_bounded_queue _event_queue; std::thread _worker_thread; Processor _processor; void workerThread() { while (!_event_queue.closed()) { try { trace_event evt; auto status = _event_queue.wait_pull_front(evt); if (status != success) { break; } _processor.processEvent(&evt); } catch (const sync_queue_is_closed&) { // We are done here break; } } } public: template explicit ThreadedEventProcessor(Params&& ... params) : _event_queue(QUEUE_SIZE), _worker_thread(&ThreadedEventProcessor::workerThread, this), _processor(std::forward(params)...) {} ~ThreadedEventProcessor() { _event_queue.close(); _worker_thread.join(); } void processEvent(const trace_event* event) { try { _event_queue.wait_push_back(*event); } catch (const sync_queue_is_closed&) { mprintf(("Stream queue was closed in processEvent! This should not be possible...\n")); } } }; }