generated from zhangwei/Matrixai
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__
|