395 lines
7.4 KiB
C++
395 lines
7.4 KiB
C++
#ifndef _FF_CIRCLEQUEUE_H__
|
||
#define _FF_CIRCLEQUEUE_H__
|
||
|
||
#include <iostream>
|
||
#include <memory>
|
||
#include <queue>
|
||
#include <string>
|
||
#include <stdio.h>
|
||
#include <string.h>
|
||
#include <pthread.h>
|
||
|
||
#include "QueueStructDefine.h"
|
||
|
||
|
||
using namespace std;
|
||
|
||
template<typename T>
|
||
class FF_CircleQueue
|
||
{
|
||
public:
|
||
/**
|
||
* @brief Construct a new ff circlequeue object
|
||
*
|
||
* @param Size Circle Queue元素数量
|
||
* @param ElemArray 元素数组
|
||
*/
|
||
FF_CircleQueue(int Size, T ElemArray);
|
||
~FF_CircleQueue();
|
||
|
||
|
||
/**
|
||
* @brief 慢队列 入队
|
||
*
|
||
* @param Elem
|
||
* @return int
|
||
*/
|
||
int EnFullQueue(const T& Elem);
|
||
|
||
/**
|
||
* @brief 满队列 出队
|
||
*
|
||
* @param Elem
|
||
* @return int
|
||
*/
|
||
int DeFullQueue(T& Elem);
|
||
|
||
/**
|
||
* @brief 满队列尝试出对,如果此时队列为空,返回false,有数据返回true
|
||
*
|
||
* @param Elem
|
||
* @return true
|
||
* @return false
|
||
*/
|
||
bool Try_DeFullQueue(T& Elem);
|
||
|
||
/**
|
||
* @brief
|
||
*
|
||
* @param Elem
|
||
* @return int
|
||
*/
|
||
int Peek_DeFullQueue(T& Elem); ///< 获取数据,但不出队
|
||
|
||
/**
|
||
* @brief
|
||
*
|
||
* @param Elem
|
||
* @return int
|
||
*/
|
||
int TryPeek_DeFullQueue(T& Elem);
|
||
|
||
|
||
/**
|
||
* @brief 空队列 入队
|
||
*
|
||
* @param Elem
|
||
* @return int
|
||
*/
|
||
int EnFreeQueue(const T& Elem);
|
||
/**
|
||
* @brief 空队列 出队
|
||
*
|
||
* @param Elem
|
||
* @return int
|
||
*/
|
||
int DeFreeQueue(T& Elem);
|
||
/**
|
||
* @brief 空队列尝试出对,有数据为true,无数据返回false
|
||
*
|
||
* @param Elem
|
||
* @return true
|
||
* @return false
|
||
*/
|
||
bool Try_DeFreeQueue(T& Elem);
|
||
|
||
/**
|
||
* @brief
|
||
*
|
||
* @return true
|
||
* @return false
|
||
*/
|
||
bool IsValid();
|
||
|
||
/**
|
||
* @brief 获取各队列所持有元素数量
|
||
*
|
||
* @return unsigned int
|
||
*/
|
||
unsigned int GetFullQueueSize();
|
||
unsigned int GetFreeQueueSize();
|
||
|
||
private:
|
||
void SetValid()
|
||
{
|
||
qValid = true;
|
||
}
|
||
|
||
void SetInvalid()
|
||
{
|
||
qValid = false;
|
||
}
|
||
bool qValid;
|
||
|
||
int NumElem;
|
||
|
||
/**
|
||
* @brief 空队列,及其锁,条件变量
|
||
*
|
||
*/
|
||
std::queue<T> free_queue_;
|
||
pthread_mutexattr_t free_mutAttr_;
|
||
pthread_mutex_t free_mutex_;
|
||
pthread_cond_t free_condition_ = PTHREAD_COND_INITIALIZER;
|
||
|
||
/**
|
||
* @brief 满队列,及其锁,条件变量
|
||
*
|
||
*/
|
||
std::queue<T> full_queue_;
|
||
pthread_mutexattr_t full_mutAttr_;
|
||
pthread_mutex_t full_mutex_;
|
||
pthread_cond_t full_condition_ = PTHREAD_COND_INITIALIZER;
|
||
|
||
};
|
||
|
||
|
||
/**
|
||
* Implementation of Circle Queue, Designed by Derek.
|
||
*/
|
||
|
||
|
||
/**
|
||
* @brief Construct a new queuemanager object
|
||
* @tparam T
|
||
* @param Size
|
||
* @param ElemArray
|
||
*/
|
||
template<typename T>
|
||
FF_CircleQueue<T>::FF_CircleQueue(int Size, T ElemArray)
|
||
{
|
||
qValid = false;
|
||
NumElem = 0;
|
||
/// Prevent invalid queue element
|
||
if(Size==0 || ElemArray==NULL){
|
||
/// NULL
|
||
}
|
||
memset(&free_mutAttr_, 0, sizeof(pthread_mutexattr_t));
|
||
pthread_mutexattr_init(&free_mutAttr_);
|
||
pthread_mutexattr_settype(&free_mutAttr_, PTHREAD_MUTEX_RECURSIVE_NP);
|
||
pthread_mutex_init(&free_mutex_, &free_mutAttr_);
|
||
|
||
memset(&full_mutAttr_, 0, sizeof(pthread_mutexattr_t));
|
||
pthread_mutexattr_init(&full_mutAttr_);
|
||
pthread_mutexattr_settype(&full_mutAttr_, PTHREAD_MUTEX_RECURSIVE_NP);
|
||
pthread_mutex_init(&full_mutex_, &full_mutAttr_);
|
||
|
||
NumElem = Size; ///< Element size
|
||
|
||
for(int i=0; i<NumElem; i++){
|
||
free_queue_.push(&ElemArray[i]);
|
||
}
|
||
|
||
SetValid();
|
||
}
|
||
|
||
/**
|
||
* @brief Destroy the queuemanager object
|
||
* @tparam T
|
||
*/
|
||
template<typename T>
|
||
FF_CircleQueue<T>::~FF_CircleQueue()
|
||
{
|
||
pthread_mutex_destroy(&free_mutex_);
|
||
pthread_mutex_destroy(&full_mutex_);
|
||
|
||
/// NULL
|
||
}
|
||
|
||
/**
|
||
* @brief
|
||
* @param Elem
|
||
* @return int
|
||
*/
|
||
template<typename T>
|
||
int FF_CircleQueue<T>::EnFullQueue(const T& Elem) ///< 入队
|
||
{
|
||
pthread_mutex_lock(&full_mutex_);
|
||
full_queue_.push(Elem);
|
||
pthread_mutex_unlock(&full_mutex_); ///< 主动释放
|
||
|
||
pthread_cond_signal(&full_condition_);
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* @brief
|
||
* @param Elem
|
||
* @return int
|
||
*/
|
||
template<typename T>
|
||
int FF_CircleQueue<T>::DeFullQueue(T& Elem) ///< 出队
|
||
{
|
||
pthread_mutex_lock(&full_mutex_);
|
||
while (full_queue_.empty()) {
|
||
pthread_cond_wait(&full_condition_, &full_mutex_);
|
||
}
|
||
|
||
Elem = full_queue_.front();
|
||
full_queue_.pop();
|
||
pthread_mutex_unlock(&full_mutex_);
|
||
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* @brief
|
||
* @param Elem
|
||
* @return int
|
||
*/
|
||
template<typename T>
|
||
int FF_CircleQueue<T>::Peek_DeFullQueue(T& Elem) ///< 获取数据,但不出队
|
||
{
|
||
// *Elem = full_queue_.peek();
|
||
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* @brief
|
||
* @tparam T
|
||
* @param Elem
|
||
* @return int
|
||
*/
|
||
template<typename T>
|
||
bool FF_CircleQueue<T>::Try_DeFullQueue(T& Elem)
|
||
{
|
||
pthread_mutex_lock(&full_mutex_);
|
||
|
||
if (full_queue_.empty()) {
|
||
pthread_mutex_unlock(&full_mutex_);
|
||
return false;
|
||
}
|
||
|
||
Elem = full_queue_.front();
|
||
full_queue_.pop();
|
||
pthread_mutex_unlock(&full_mutex_);
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* @brief
|
||
* @tparam T
|
||
* @param Elem
|
||
* @return int
|
||
*/
|
||
template<typename T>
|
||
int FF_CircleQueue<T>::TryPeek_DeFullQueue(T& Elem)
|
||
{
|
||
//bool ret = false;
|
||
|
||
pthread_mutex_lock(&full_mutex_);
|
||
|
||
if (full_queue_.empty()) {
|
||
pthread_mutex_unlock(&full_mutex_);
|
||
return -1;
|
||
}
|
||
|
||
Elem = full_queue_.front();
|
||
pthread_mutex_unlock(&full_mutex_);
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
/**
|
||
* @brief
|
||
* @param Elem
|
||
* @return int
|
||
*/
|
||
template<typename T>
|
||
int FF_CircleQueue<T>::EnFreeQueue(const T& Elem)
|
||
{
|
||
pthread_mutex_lock(&free_mutex_);
|
||
free_queue_.push(Elem);
|
||
pthread_mutex_unlock(&free_mutex_); ///< 主动释放
|
||
|
||
pthread_cond_signal(&free_condition_);
|
||
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* @brief
|
||
* @param Elem
|
||
* @return int
|
||
*/
|
||
template<typename T>
|
||
int FF_CircleQueue<T>::DeFreeQueue(T& Elem)
|
||
{
|
||
pthread_mutex_lock(&free_mutex_);
|
||
|
||
while (free_queue_.empty()) {
|
||
pthread_cond_wait(&free_condition_, &free_mutex_);
|
||
}
|
||
|
||
Elem = free_queue_.front();
|
||
free_queue_.pop();
|
||
pthread_mutex_unlock(&free_mutex_);
|
||
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* @brief
|
||
* @tparam T
|
||
* @param Elem
|
||
* @return int
|
||
*/
|
||
template<typename T>
|
||
bool FF_CircleQueue<T>::Try_DeFreeQueue(T& Elem)
|
||
{
|
||
pthread_mutex_lock(&free_mutex_);
|
||
if (free_queue_.empty()) {
|
||
pthread_mutex_unlock(&free_mutex_);
|
||
return false;
|
||
}
|
||
|
||
Elem = free_queue_.front();
|
||
free_queue_.pop();
|
||
pthread_mutex_unlock(&free_mutex_);
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* @brief Check if queue manager is valid
|
||
* @return true
|
||
* @return false
|
||
*/
|
||
template<typename T>
|
||
bool FF_CircleQueue<T>::IsValid()
|
||
{
|
||
return qValid;
|
||
}
|
||
|
||
/**
|
||
* @brief Get the number of elements in the fullqueue
|
||
* @tparam T
|
||
* @return int
|
||
*/
|
||
template<typename T>
|
||
unsigned int FF_CircleQueue<T>::GetFullQueueSize()
|
||
{
|
||
return full_queue_.size();
|
||
}
|
||
|
||
/**
|
||
* @brief Get the number of elements in the freequeue
|
||
* @tparam T
|
||
* @return int
|
||
*/
|
||
template<typename T>
|
||
unsigned int FF_CircleQueue<T>::GetFreeQueueSize()
|
||
{
|
||
return free_queue_.size();
|
||
}
|
||
|
||
template class FF_CircleQueue<FFQBuffer*>; ///< TEST
|
||
template class FF_CircleQueue<ListenerQBuffer*>; ///< TEST
|
||
template class FF_CircleQueue<VideoQBuffer*>; ///< TEST
|
||
|
||
// int fun();
|
||
|
||
///////////////////////////////////////////////////////////////////////////////////
|
||
|
||
#endif ///_FF_QUEUE_MANAGER_H__
|