1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
#if !defined(__WXMSW__)
#ifndef __equeue_unix_impl_h__
#define __equeue_unix_impl_h__
#include <pthread.h>
#include <list>
#include <errno.h>
#include <sys/time.h>
template <class T>
class eQueueImpl
{
protected:
pthread_mutex_t m_mutex;
pthread_cond_t m_cond;
std::list<T> m_queue;
public:
eQueueImpl();
virtual ~eQueueImpl();
bool put ( const T& item );
bool get ( T& item, long timeout );
};
//----------------------------
// Implementation
//----------------------------
template<class T>
eQueueImpl<T>::eQueueImpl()
{
pthread_mutexattr_t attr;
pthread_mutexattr_init ( &attr );
pthread_mutexattr_settype ( &attr, PTHREAD_MUTEX_NORMAL );
pthread_mutex_init ( &m_mutex, &attr );
pthread_condattr_t cattr;
pthread_condattr_init ( &cattr );
pthread_cond_init ( &m_cond, &cattr );
}
template<class T>
eQueueImpl<T>::~eQueueImpl()
{
}
template<class T>
bool eQueueImpl<T>::get ( T& item, long timeout )
{
struct timespec ts;
struct timeval tv;
pthread_mutex_lock ( &m_mutex );
while ( m_queue.empty() ) {
gettimeofday ( &tv, NULL );
/* Convert from timeval to timespec */
ts.tv_sec = tv.tv_sec;
ts.tv_nsec = tv.tv_usec * 1000;
// add our timeout
ts.tv_sec += ( timeout / 1000 );
ts.tv_nsec += ( timeout % 1000 ) * 1000000;
// nsec can not bre greater than 1000000000 (sec)
if ( ts.tv_nsec >= 1000000000 ) {
ts.tv_nsec -= 1000000000;
++ts.tv_sec;
}
int rc = pthread_cond_timedwait ( &m_cond, &m_mutex, &ts );
if ( rc == ETIMEDOUT ) {
pthread_mutex_unlock ( &m_mutex );
return false;
}
}
// get copy of the data
item = m_queue.front();
m_queue.pop_front();
pthread_mutex_unlock ( &m_mutex );
return true;
}
template<class T>
bool eQueueImpl<T>::put ( const T& item )
{
pthread_mutex_lock ( &m_mutex );
bool was_empty = m_queue.empty();
m_queue.push_back ( item );
if ( was_empty ) {
pthread_cond_signal ( &m_cond );
}
pthread_mutex_unlock ( &m_mutex );
return true;
}
#endif // __equeue_unix_impl_h__
#endif // !defined(__WXMSW__)
|