CThreadDeque.hh 4.48 KB
/* -*- 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 :
	<ul>
	<li>
	</ul>

------------------------------------------------------------------------*/

//=============================================================================
// 
// History of code
//
// creation 
//
// modification 
//=============================================================================

#ifndef _CTHREADDEQUE_HH_
#define _CTHREADDEQUE_HH_ 1

#include <deque>
#include <semaphore.h>

/**

*/

//=============================================================================
// 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<Object>  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_