You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
158 lines
5.0 KiB
C++
158 lines
5.0 KiB
C++
/***************************************************************************
|
|
* Copyright (C) gempa GmbH *
|
|
* All rights reserved. *
|
|
* Contact: gempa GmbH (seiscomp-dev@gempa.de) *
|
|
* *
|
|
* GNU Affero General Public License Usage *
|
|
* This file may be used under the terms of the GNU Affero *
|
|
* Public License version 3.0 as published by the Free Software Foundation *
|
|
* and appearing in the file LICENSE included in the packaging of this *
|
|
* file. Please review the following information to ensure the GNU Affero *
|
|
* Public License version 3.0 requirements will be met: *
|
|
* https://www.gnu.org/licenses/agpl-3.0.html. *
|
|
* *
|
|
* Other Usage *
|
|
* Alternatively, this file may be used in accordance with the terms and *
|
|
* conditions contained in a signed written agreement between you and *
|
|
* gempa GmbH. *
|
|
***************************************************************************/
|
|
|
|
|
|
#ifndef SEISCOMP_CLIENT_QUEUE_H
|
|
#define SEISCOMP_CLIENT_QUEUE_H
|
|
|
|
|
|
#include <vector>
|
|
#include <condition_variable>
|
|
#include <thread>
|
|
|
|
#include <seiscomp/core/baseobject.h>
|
|
|
|
|
|
namespace Seiscomp {
|
|
namespace Client {
|
|
|
|
class QueueClosedException : public Core::GeneralException {
|
|
public:
|
|
QueueClosedException() : Core::GeneralException("Queue has been closed") {}
|
|
QueueClosedException(const std::string& str ) : Core::GeneralException(str) {}
|
|
};
|
|
|
|
template <typename T>
|
|
class ThreadedQueue {
|
|
// ----------------------------------------------------------------------
|
|
// Public types
|
|
// ----------------------------------------------------------------------
|
|
public:
|
|
typedef std::unique_lock<std::mutex> lock;
|
|
|
|
|
|
// ----------------------------------------------------------------------
|
|
// Non copyable
|
|
// ----------------------------------------------------------------------
|
|
private:
|
|
ThreadedQueue(const ThreadedQueue&) = delete;
|
|
ThreadedQueue &operator=(const ThreadedQueue&) = delete;
|
|
|
|
|
|
// ----------------------------------------------------------------------
|
|
// X'truction
|
|
// ----------------------------------------------------------------------
|
|
public:
|
|
ThreadedQueue();
|
|
ThreadedQueue(int n);
|
|
~ThreadedQueue();
|
|
|
|
|
|
// ----------------------------------------------------------------------
|
|
// Interface
|
|
// ----------------------------------------------------------------------
|
|
public:
|
|
/**
|
|
* @brief Resizes the queue to hold a maximum of n items before
|
|
* blocking.
|
|
* @param n The number of items to queue before blocking occurs.
|
|
*/
|
|
void resize(int n);
|
|
|
|
/**
|
|
* @brief Checks whether the queue can take new items without blocking.
|
|
* @return true if non-blocking push is possible, false otherwise.
|
|
*/
|
|
bool canPush() const;
|
|
|
|
/**
|
|
* @brief Appends a new item to the end of the queue. If the queue is
|
|
* full then it will block until a consumer has popped an item.
|
|
* @param v The new item.
|
|
* @return true if successful, false if queue is closed.
|
|
*/
|
|
bool push(T v);
|
|
|
|
/**
|
|
* @brief Checks with equality operator if the item is already queued
|
|
* and if not, pushes it to the end of the queue.
|
|
* @param v The new item.
|
|
* @return true if successful which also covers the case that the item
|
|
* is already queued. False if the queue is closed.
|
|
*/
|
|
bool pushUnique(T v);
|
|
|
|
/**
|
|
* @brief Checks whether an item can be popped or not.
|
|
* Actually it returns whether the queue is empty or not.
|
|
* @return true if not empty, false if empty.
|
|
*/
|
|
bool canPop() const;
|
|
|
|
/**
|
|
* @brief Pops an items from the queue. If the queue is empty then
|
|
* it blocks until a producer pushed an item.
|
|
* @return The popped item.
|
|
*/
|
|
T pop();
|
|
|
|
/**
|
|
* @brief Close the queue and cause all subsequent calls to push and
|
|
* pop to fail.
|
|
*/
|
|
void close();
|
|
|
|
/**
|
|
* @brief Returns whether the queue is closed or not.
|
|
* @return The closed flag.
|
|
*/
|
|
bool isClosed() const;
|
|
|
|
/**
|
|
* @brief Query the number of queued items.
|
|
* @return The number of currently queued items.
|
|
*/
|
|
size_t size() const;
|
|
|
|
/**
|
|
* @brief Resets the queue which incorporates resetting the buffer
|
|
* insertations and the closed state.
|
|
*/
|
|
void reset();
|
|
|
|
|
|
// ----------------------------------------------------------------------
|
|
// Private members
|
|
// ----------------------------------------------------------------------
|
|
private:
|
|
volatile int _begin, _end;
|
|
volatile size_t _buffered;
|
|
volatile bool _closed;
|
|
std::vector<T> _buffer;
|
|
std::condition_variable _notFull, _notEmpty;
|
|
mutable std::mutex _monitor;
|
|
};
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
#endif
|