IBR-DTNSuite
0.12
Main Page
Namespaces
Classes
Files
File List
File Members
IBR-DTNSuite
Namespaces
Classes
Files
File List
daemon
ibrcommon
ibrcommon
data
link
net
ssl
thread
AtomicCounter.cpp
AtomicCounter.h
Conditional.cpp
Conditional.h
Mutex.cpp
Mutex.h
MutexLock.cpp
MutexLock.h
Queue.h
RWLock.cpp
RWLock.h
RWMutex.cpp
RWMutex.h
Semaphore.cpp
Semaphore.h
SharedReference.h
SignalHandler.cpp
SignalHandler.h
Thread.cpp
Thread.h
ThreadsafeReference.h
ThreadsafeState.h
Timer.cpp
Timer.h
xml
appstreambuf.cpp
appstreambuf.h
config.h
Exceptions.h
ibrcommon.h
Iterator.h
Logger.cpp
Logger.h
MonotonicClock.cpp
MonotonicClock.h
refcnt_ptr.h
SyslogStream.cpp
SyslogStream.h
TimeMeasurement.cpp
TimeMeasurement.h
TLSExceptions.h
ibrdtn
tools
File Members
Queue.h
Go to the documentation of this file.
1
/*
2
* Queue.h
3
*
4
* Copyright (C) 2011 IBR, TU Braunschweig
5
*
6
* Written-by: Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
7
*
8
* Licensed under the Apache License, Version 2.0 (the "License");
9
* you may not use this file except in compliance with the License.
10
* You may obtain a copy of the License at
11
*
12
* http://www.apache.org/licenses/LICENSE-2.0
13
*
14
* Unless required by applicable law or agreed to in writing, software
15
* distributed under the License is distributed on an "AS IS" BASIS,
16
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
* See the License for the specific language governing permissions and
18
* limitations under the License.
19
*
20
*/
21
22
#ifndef IBRCOMMON_QUEUE_H_
23
#define IBRCOMMON_QUEUE_H_
24
25
#include "
ibrcommon/thread/MutexLock.h
"
26
#include "
ibrcommon/thread/Conditional.h
"
27
#include "
ibrcommon/Exceptions.h
"
28
#include "
ibrcommon/thread/Semaphore.h
"
29
#include "
ibrcommon/thread/Thread.h
"
30
#include <queue>
31
#include <iostream>
32
33
namespace
ibrcommon
34
{
35
class
QueueUnblockedException
:
public
ibrcommon::Exception
36
{
37
public
:
38
enum
type_t
39
{
40
QUEUE_ABORT
= 0,
41
QUEUE_ERROR
= 1,
42
QUEUE_TIMEOUT
= 2
43
};
44
45
QueueUnblockedException
(
const
type_t
r,
string
what
=
"Queue is unblocked."
) throw() : ibrcommon::
Exception
(
what
),
reason
(r)
46
{
47
};
48
49
QueueUnblockedException
(
const
ibrcommon::Conditional::ConditionalAbortException
&ex,
string
what
=
"Queue is unblocked."
) throw() : ibrcommon::
Exception
(
what
)
50
{
51
switch
(ex.
reason
)
52
{
53
case
ibrcommon::Conditional::ConditionalAbortException::COND_ABORT
:
54
reason
=
QUEUE_ABORT
;
55
_what
=
"queue function aborted in "
+
what
;
56
break
;
57
58
case
ibrcommon::Conditional::ConditionalAbortException::COND_ERROR
:
59
reason
=
QUEUE_ERROR
;
60
_what
=
"queue function error in "
+
what
;
61
break
;
62
63
case
ibrcommon::Conditional::ConditionalAbortException::COND_TIMEOUT
:
64
reason
=
QUEUE_TIMEOUT
;
65
_what
=
"queue function timeout in "
+
what
;
66
break
;
67
}
68
};
69
70
type_t
reason
;
71
};
72
73
template
<
class
T>
74
class
Queue
75
{
76
ibrcommon::Conditional
_cond;
77
std::queue<T> _queue;
78
ibrcommon::Semaphore
_sem;
79
bool
_limit;
80
81
public
:
82
Queue
(
unsigned
int
max = 0) : _sem(max), _limit(max > 0)
83
{};
84
85
virtual
~Queue
()
86
{
87
abort
();
88
};
89
90
/* Test whether container is empty (public member function) */
91
bool
empty
( )
92
{
93
ibrcommon::MutexLock
l(_cond);
94
return
_queue.empty();
95
}
96
97
/* Return size (public member function) */
98
size_t
size
( )
const
99
{
100
return
_queue.size();
101
}
102
103
/* Access next element (public member function) */
104
T&
front
( )
105
{
106
ibrcommon::MutexLock
l(_cond);
107
return
_queue.front();
108
}
109
110
const
T&
front
( )
const
111
{
112
ibrcommon::MutexLock
l(_cond);
113
return
_queue.front();
114
}
115
116
/* Access last element (public member function) */
117
T&
back
( )
118
{
119
ibrcommon::MutexLock
l(_cond);
120
return
_queue.back();
121
}
122
123
const
T&
back
( )
const
124
{
125
ibrcommon::MutexLock
l(_cond);
126
return
_queue.back();
127
}
128
129
/* Insert element (public member function) */
130
void
push
(
const
T& x )
131
{
132
if
(_limit) _sem.
wait
();
133
134
ibrcommon::MutexLock
l(_cond);
135
_queue.push(x);
136
_cond.
signal
(
true
);
137
}
138
139
/* Delete next element (public member function) */
140
void
pop
()
141
{
142
ibrcommon::MutexLock
l(_cond);
143
__pop
();
144
}
145
146
T
get
(
bool
blocking =
false
,
size_t
timeout = 0)
throw
(
QueueUnblockedException
)
147
{
148
try
{
149
ibrcommon::MutexLock
l(_cond);
150
if
(_queue.empty())
151
{
152
if
(blocking)
153
{
154
if
(timeout == 0)
155
{
156
__wait
(
QUEUE_NOT_EMPTY
);
157
}
158
else
159
{
160
__wait
(
QUEUE_NOT_EMPTY
, timeout);
161
}
162
}
163
else
164
{
165
throw
QueueUnblockedException
(
QueueUnblockedException::QUEUE_ABORT
,
"getnpop(): queue is empty!"
);
166
}
167
}
168
169
return
_queue.front();
170
}
catch
(
const
ibrcommon::Conditional::ConditionalAbortException
&ex) {
171
throw
QueueUnblockedException
(ex,
"getnpop()"
);
172
}
173
}
174
175
T
getnpop
(
bool
blocking =
false
,
size_t
timeout = 0) throw (
QueueUnblockedException
)
176
{
177
try
{
178
ibrcommon::MutexLock
l(_cond);
179
if
(_queue.empty())
180
{
181
if
(blocking)
182
{
183
if
(timeout == 0)
184
{
185
__wait
(
QUEUE_NOT_EMPTY
);
186
}
187
else
188
{
189
__wait
(
QUEUE_NOT_EMPTY
, timeout);
190
}
191
}
192
else
193
{
194
throw
QueueUnblockedException(
QueueUnblockedException::QUEUE_ABORT
,
"getnpop(): queue is empty!"
);
195
}
196
}
197
198
T ret = _queue.front();
199
__pop
();
200
return
ret;
201
}
catch
(
const
ibrcommon::Conditional::ConditionalAbortException
&ex) {
202
throw
QueueUnblockedException(ex,
"getnpop()"
);
203
}
204
}
205
206
void
abort
() throw ()
207
{
208
ibrcommon::MutexLock
l(_cond);
209
_cond.
abort
();
210
}
211
212
void
reset
() throw ()
213
{
214
_cond.
reset
();
215
}
216
217
enum
WAIT_MODES
218
{
219
QUEUE_NOT_EMPTY
= 0,
220
QUEUE_EMPTY
= 1
221
};
222
223
void
wait
(
WAIT_MODES
mode,
const
size_t
timeout = 0) throw (
QueueUnblockedException
)
224
{
225
ibrcommon::MutexLock
l(_cond);
226
if
(timeout == 0)
227
{
228
__wait
(mode);
229
}
230
else
231
{
232
__wait
(mode, timeout);
233
}
234
}
235
236
class
Locked
237
{
238
public
:
239
Locked
(
Queue<T>
&queue)
240
: _queue(queue), _lock(queue._cond), _changed(false)
241
{
242
};
243
244
virtual
~Locked
()
245
{
246
if
(_changed) _queue._cond.signal(
true
);
247
};
248
249
void
wait
(
WAIT_MODES
mode,
const
size_t
timeout = 0) throw (
QueueUnblockedException
)
250
{
251
if
(timeout == 0)
252
{
253
_queue.__wait(mode);
254
}
255
else
256
{
257
_queue.__wait(mode, timeout);
258
}
259
}
260
261
void
pop
()
262
{
263
_queue.__pop();
264
}
265
266
const
T&
front
()
const
267
{
268
return
_queue._queue.front();
269
}
270
271
T&
front
()
272
{
273
return
_queue._queue.front();
274
}
275
276
bool
empty
()
277
{
278
return
_queue._queue.empty();
279
}
280
281
size_t
size
()
282
{
283
return
_queue._queue.size();
284
}
285
286
void
push
(
const
T &p)
287
{
288
_queue._queue.push(p);
289
_changed =
true
;
290
}
291
292
private
:
293
Queue<T>
&_queue;
294
ibrcommon::MutexLock
_lock;
295
bool
_changed;
296
};
297
298
typename
Queue<T>::Locked
exclusive
()
299
{
300
return
typename
Queue<T>::Locked
(*
this
);
301
}
302
303
protected
:
304
void
__push
(
const
T& x )
305
{
306
_queue.push(x);
307
_cond.
signal
(
true
);
308
}
309
310
void
__pop
()
311
{
312
if
(!_queue.empty())
313
{
314
_queue.pop();
315
if
(_limit) _sem.
post
();
316
_cond.
signal
(
true
);
317
}
318
}
319
320
void
__wait
(
const
WAIT_MODES
mode)
throw
(
QueueUnblockedException
)
321
{
322
try
{
323
switch
(mode)
324
{
325
case
QUEUE_NOT_EMPTY
:
326
{
327
while
(_queue.empty())
328
{
329
_cond.
wait
();
330
}
331
break
;
332
}
333
334
case
QUEUE_EMPTY
:
335
{
336
while
(!_queue.empty())
337
{
338
_cond.
wait
();
339
}
340
break
;
341
}
342
}
343
}
catch
(
const
ibrcommon::Conditional::ConditionalAbortException
&ex) {
344
switch
(ex.
reason
)
345
{
346
case
ibrcommon::Conditional::ConditionalAbortException::COND_ABORT
:
347
_cond.
reset
();
348
break
;
349
350
default
:
351
break
;
352
}
353
354
throw
QueueUnblockedException
(ex,
"__wait()"
);
355
}
356
}
357
358
void
__wait
(
const
WAIT_MODES
mode,
const
size_t
timeout)
throw
(
QueueUnblockedException
)
359
{
360
try
{
361
struct
timespec ts;
362
Conditional::gettimeout
(timeout, &ts);
363
364
switch
(mode)
365
{
366
case
QUEUE_NOT_EMPTY
:
367
{
368
while
(_queue.empty())
369
{
370
_cond.
wait
(&ts);
371
}
372
break
;
373
}
374
375
case
QUEUE_EMPTY
:
376
{
377
while
(!_queue.empty())
378
{
379
_cond.
wait
(&ts);
380
}
381
break
;
382
}
383
}
384
}
catch
(
const
ibrcommon::Conditional::ConditionalAbortException
&ex) {
385
switch
(ex.
reason
)
386
{
387
case
ibrcommon::Conditional::ConditionalAbortException::COND_ABORT
:
388
_cond.
reset
();
389
break
;
390
391
default
:
392
break
;
393
}
394
395
throw
QueueUnblockedException
(ex,
"__wait()"
);
396
}
397
}
398
};
399
}
400
401
#endif
/* IBRCOMMON_QUEUE_H_ */
ibrcommon
ibrcommon
thread
Queue.h
Generated on Thu Mar 27 2014 09:26:21 for IBR-DTNSuite by
1.8.4