Files
fs2open.github.com/code/tracing/ThreadedEventProcessor.h

78 lines
1.8 KiB
C++

#pragma once
#include "globalincs/pstypes.h"
#include "tracing/tracing.h"
#include "utils/boost/syncboundedqueue.h"
#include <thread>
/** @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 Processor, size_t QUEUE_SIZE = 200>
class ThreadedEventProcessor {
sync_bounded_queue<trace_event> _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<typename... Params>
explicit ThreadedEventProcessor(Params&& ... params)
: _event_queue(QUEUE_SIZE), _worker_thread(&ThreadedEventProcessor<Processor>::workerThread, this),
_processor(std::forward<Params>(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"));
}
}
};
}