#ifndef mutexlocker_h_included#definemutexlocker_h_included#include<pthread.h>#include<stdexcept>classmutexlocker{ Public: ExplicitMutexlocker (pthread_mutex_t *mutex): M_mutex (mutex) {intRET =Pthread_mutex_lock (M_mutex); if(Ret! =0) {printf ("Lock Mutex failed"); ThrowStd::logic_error ("Could not lock mutex"); } } Virtual~Mutexlocker () {pthread_mutex_unlock (M_mutex); }Private: pthread_mutex_t*M_mutex;};#endif //mutexlocker_h_included
#ifndef safequeue_h_included#definesafequeue_h_included#include"MutexLocker.h"#include<pthread.h>#include<list>Template<classT>classsafequeue{ Public: SafeQueue (intSize =0) {m_capacity=capacity; M_total_enqueue_count=0; pthread_mutexattr_t attr; Pthread_mutexattr_init (&attr); Pthread_mutexattr_settype (&attr, pthread_mutex_recursive); Pthread_mutex_init (&m_lock, &attr); Pthread_mutexattr_destroy (&attr); } ~SafeQueue () {intFrame_count =m_list.size (); for(inti =0; i < Frame_count; i++) {M_list.pop_front (); } Pthread_mutex_destroy (&M_lock); } voidSetcapacity (intcapacity) {m_capacity=capacity; } //return 0 if succeed;-1 if the queue is full intEnqueue (T node) {Ctmutexlocker Locker (&M_lock); //Pthread_mutex_lock (&m_lock); if(M_capacity >0&& Size () >=m_capacity) { //Pthread_mutex_unlock (&m_lock); return-1;//Overflow} m_list.push_back (node); M_total_enqueue_count++; //Pthread_mutex_unlock (&m_lock); return 0; } //dequeue a item, and save the result to the @item pointer. //return 0 if succeed,-1 if the queue is empty; intDequeue (T *item,intReserve_len =0) {Ctmutexlocker Locker (&M_lock); //*item = NULL;memset (Item,0,sizeof(T)); intTotal_count =m_list.size (); if(Total_count = =0|| Total_count <Reserve_len) { return-1; } *item =M_list.front (); M_list.pop_front (); //Pthread_mutex_unlock (&m_lock); return 0; } intDequeueall (std::list<t> *out_queue,intReserve_len =0) {Ctmutexlocker Locker (&M_lock); if(M_list.size () <=Reserve_len) { return 0; } T Item; intRemove_size = M_list.size ()-Reserve_len; while(Remove_size >0) {Item=M_list.front (); M_list.pop_front (); if(out_queue) {Out_queue-push_back (item); } remove_size--; } return 0; } intFront (T *Item) {Ctmutexlocker Locker (&M_lock); if(m_list.size () = =0){ return-1; } *item =M_list.front (); return 0; } intBack (T *Item) {Ctmutexlocker Locker (&M_lock); if(Size () = =0){ return-1; } *item =M_list.back (); return 0; } intSize () {Ctmutexlocker locker (&M_lock); returnm_list.size (); } intLock () {returnPthread_mutex_lock (&M_lock); } intUnlock () {returnPthread_mutex_unlock (&M_lock); } intRepushfront (T node) {Ctmutexlocker Locker (&M_lock); if(M_capacity >0&& Size () >=m_capacity)return-1;//OverflowM_list.push_front (node); return 0; } intPopback () {Ctmutexlocker locker (&M_lock); M_list.pop_back (); return 0; }Private: Std::list<T>m_list; intm_capacity; pthread_mutex_t M_lock; uint64_t M_total_enqueue_count;};#endif //safequeue_h_included
A simple implementation example of a secure queue for C/C + + thread synchronization