overte-HifiExperiments/libraries/shared/src/GenericQueueThread.h

99 lines
2.4 KiB
C++

//
// Created by Bradley Austin Davis 2015/07/08.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#pragma once
#ifndef hifi_GenericQueueThread_h
#define hifi_GenericQueueThread_h
#include <stdint.h>
#include <QtCore/QElapsedTimer>
#include <QtCore/QMutex>
#include <QtCore/QQueue>
#include <QtCore/QWaitCondition>
#include "GenericThread.h"
#include "NumericalConstants.h"
template <typename T>
class GenericQueueThread : public GenericThread {
public:
using Queue = QQueue<T>;
GenericQueueThread(QObject* parent = nullptr)
: GenericThread() {}
virtual ~GenericQueueThread() {}
void queueItem(const T& t) {
lock();
queueItemInternal(t);
unlock();
_hasItems.wakeAll();
}
void waitIdle(uint32_t maxWaitMs = UINT32_MAX) {
QElapsedTimer timer;
timer.start();
// FIXME this will work as long as the thread doing the wait
// is the only thread which can add work to the queue.
// It would be better if instead we had a queue empty condition to wait on
// that would ensure that we get woken as soon as we're idle the very
// first time the queue was empty.
while (timer.elapsed() < maxWaitMs) {
lock();
if (!_items.size()) {
unlock();
return;
}
unlock();
}
}
virtual bool process() override {
lock();
if (!_items.size()) {
unlock();
_hasItemsMutex.lock();
_hasItems.wait(&_hasItemsMutex, getMaxWait());
_hasItemsMutex.unlock();
} else {
unlock();
}
lock();
if (!_items.size()) {
unlock();
return isStillRunning();
}
Queue processItems;
processItems.swap(_items);
unlock();
return processQueueItems(processItems);
}
protected:
virtual void queueItemInternal(const T& t) {
_items.push_back(t);
}
virtual uint32_t getMaxWait() {
return MSECS_PER_SECOND;
}
virtual bool processQueueItems(const Queue& items) = 0;
Queue _items;
QWaitCondition _hasItems;
QMutex _hasItemsMutex;
};
#endif // hifi_GenericQueueThread_h