/* -*- Base: 10 ; Mode: C++ -*- */ /*------------------------------------------------------------------------ ** FOST project ** -------------------------------------------------------------------------- -------------------------------------------------------------------------- FILE LOG $Revision: 1.3 $ $Date: 2012-06-15 13:04:37 $ -------------------------------------------------------------------------- CREATION F.CASIMIR SUMMARY DESCRIPTION The main function performs the following actions : ------------------------------------------------------------------------*/ //============================================================================= // // History of code // // creation // // modification //============================================================================= #ifndef _CTHREADDEQUE_HH_ #define _CTHREADDEQUE_HH_ 1 #include #include /** */ //============================================================================= // Class CThreadDeque //============================================================================= /** * @brief thread salfe std::deque of object * * @details manage a deque of any object */ template< class Object> class CThreadDeque { public: typedef std::deque ObjectList; /** Constructor (default one) */ CThreadDeque() { pthread_mutex_init( & _objectListMutex, NULL); sem_init( & _objectSem, 0, 0); } /** Destructor */ virtual ~CThreadDeque() { pthread_mutex_destroy( & _objectListMutex); sem_destroy( & _objectSem); } // Get Methods // Set Methods // Other Methods /** * @brief add an Object and Post SEM. */ void push( Object object) { Lock sync( & _objectListMutex); _objectList.push_back(object); sem_post( & _objectSem); } /** * @brief Wait for SEM being posted and pop an Object */ Object pop() { sem_wait( & _objectSem); return internalPop(); } /** * Wait wait second for SEM being posted. */ Object pop_timedwait( int wait, Object null) { Object object = null; struct timespec ts; if (clock_gettime(CLOCK_REALTIME, &ts) != -1) { ts.tv_sec += wait; if ( sem_timedwait( & _objectSem, &ts) != -1 ) { object = internalPop(); } } return object; } Object tryToPop( Object null) { Object object = null; Lock lock( & _objectListMutex); if ( ! _objectList.empty() ) { if ( sem_trywait( & _objectSem) == 0 ) { object = _objectList.front(); _objectList.pop_front(); } } return object; } void remove( Object object) { Lock lock( & _objectListMutex); typename ObjectList::iterator it = _objectList.begin(); for (; it != _objectList.end(); ++it) { if ( (*it) == object ) { _objectList.erase(it); break; } } } void flush(ObjectList& objectList) { Lock lock( & _objectListMutex); while ( ! _objectList.empty() ) { sem_wait( & _objectSem); objectList.push_back( _objectList.front()); _objectList.pop_front(); } } bool empty() { Lock lock( & _objectListMutex); return _objectList.empty(); } private: class Lock { public: Lock(pthread_mutex_t* mutex) : _mutex(mutex) { pthread_mutex_lock( _mutex); } ~Lock() { pthread_mutex_unlock( _mutex); } private: pthread_mutex_t* _mutex; }; Object internalPop() { Object object = NULL; Lock sync( & _objectListMutex); if ( ! _objectList.empty() ) { object = _objectList.front(); _objectList.pop_front(); } return object; } /** Copy Constructor (normally should not be used) */ CThreadDeque(const CThreadDeque& copied) {} pthread_mutex_t _objectListMutex; sem_t _objectSem; ObjectList _objectList; }; //============================================================================= // Inline Methods for Class CThreadDeque //============================================================================= //----------------------------------------------------------------------------- // Get Methods //----------------------------------------------------------------------------- // Set Methods //----------------------------------------------------------------------------- // Other Methods //============================================================================= // End of Class CThreadDeque //============================================================================= #endif // _CTHREADDEQUE_HH_