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__
 |