File: equeue_unix_impl.h

package info (click to toggle)
codelite 12.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 95,112 kB
  • sloc: cpp: 424,040; ansic: 18,284; php: 9,569; lex: 4,186; yacc: 2,820; python: 2,294; sh: 312; makefile: 51; xml: 13
file content (104 lines) | stat: -rw-r--r-- 2,126 bytes parent folder | download | duplicates (5)
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__)