forest-net
an overlay networks for large-scale virtual worlds
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator
Queue.cpp
Go to the documentation of this file.
1 
9 #include "Queue.h"
10 
11 namespace forest {
12 
13 
14 Queue::Queue(int qMax1) {
15  qMax = qMax1;
16  count = head = tail = 0;
17  buf = new int[qMax];
18 }
19 
20 Queue::~Queue() {
21  delete [] buf;
22  pthread_mutex_destroy(&lock);
23  pthread_cond_destroy(&emptyQ);
24  pthread_cond_destroy(&fullQ);
25 }
26 
30 void Queue::reset() {
31  pthread_mutex_lock(&lock);
32  count = tail = head = 0;
33  pthread_mutex_unlock(&lock);
34 }
35 
36 bool Queue::init() {
37  int status = pthread_mutex_init(&lock,NULL);
38  if (status != 0) return false;
39  status = (pthread_cond_init(&emptyQ,NULL) == 0) &&
40  (pthread_cond_init(&fullQ,NULL) == 0);
41  return status;
42 }
43 
48 void Queue::enq(int i) {
49  pthread_mutex_lock(&lock);
50  while (count == qMax) {
51  pthread_cond_wait(&fullQ,&lock);
52  }
53 
54  buf[tail] = i;
55  count++;
56  tail = (tail + 1) % qMax;
57 
58  pthread_mutex_unlock(&lock);
59  if (pthread_cond_signal(&emptyQ) != 0)
60  cerr << "pthread_cond_signal on emptyQ failed";
61 }
62 
67 int Queue::deq() {
68  pthread_mutex_lock(&lock);
69  while (count == 0) {
70  pthread_cond_wait(&emptyQ,&lock);
71  }
72 
73  int value = buf[head];
74  count--;
75  head = (head + 1) % qMax;
76 
77  pthread_mutex_unlock(&lock);
78  pthread_cond_signal(&fullQ);
79  return value;
80 }
81 
89 int Queue::deq(uint32_t timeout) {
90  pthread_mutex_lock(&lock);
91 
92  // determine when timeout should expire
93  timeval now;
94  gettimeofday(&now,NULL);
95  timespec targetTime;
96  targetTime.tv_sec = now.tv_sec;
97  targetTime.tv_nsec = 1000 * now.tv_usec;
98  int dsec = timeout/1000000000;
99  int dnsec = timeout%1000000000;
100  targetTime.tv_sec += dsec;
101  targetTime.tv_nsec += dnsec;
102  if (targetTime.tv_nsec > 1000000000) {
103  targetTime.tv_sec++; targetTime.tv_nsec -= 1000000000;
104  }
105 
106  int status = 0;
107  while (count == 0 && status != ETIMEDOUT) {
108  status = pthread_cond_timedwait(&emptyQ,&lock,&targetTime);
109  }
110  int retVal;
111  if (status == ETIMEDOUT) {
112  retVal = Queue::TIMEOUT;
113  } else {
114  retVal = buf[head];
115  count--;
116  head = (head + 1) % qMax;
117  }
118  pthread_mutex_unlock(&lock);
119  pthread_cond_signal(&fullQ);
120  return retVal;
121 }
122 
123 } // ends namespace
124