-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathg_blocking_queue.h
122 lines (109 loc) · 5.38 KB
/
g_blocking_queue.h
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// ============================================================================
// Copyright (c) 2009-2010 Faustino Frechilla
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. The name of the author may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
/// @file q_blocking_queue.h
/// @brief Definition of a thread-safe queue based on glib system calls
/// It internally contains a std::queue which is protected from concurrent
/// access by glib mutextes and conditional variables
///
/// @author Faustino Frechilla
/// @history
/// Ref Who When What
/// Faustino Frechilla 04-May-2009 Original development (based on pthreads)
/// Faustino Frechilla 19-May-2010 Ported to glib. Removed pthread dependency
/// @endhistory
///
// ============================================================================
#ifndef _GBLOCKINGQUEUE_H_
#define _GBLOCKINGQUEUE_H_
#include <glib.h>
#include <queue>
#include <limits> // std::numeric_limits<>::max
#define BLOCKING_QUEUE_DEFAULT_MAX_SIZE std::numeric_limits<std::size_t >::max()
/// @brief blocking thread-safe queue
/// It uses a mutex+condition variables to protect the internal queue
/// implementation. Inserting or reading elements use the same mutex
template <typename T>
class BlockingQueue
{
public:
BlockingQueue(std::size_t a_maxSize = BLOCKING_QUEUE_DEFAULT_MAX_SIZE);
~BlockingQueue();
/// @brief Check if the queue is empty
/// This call can block if another thread owns the lock that protects the
/// queue
/// @return true if the queue is empty. False otherwise
bool IsEmpty();
/// @brief inserts an element into queue queue
/// This call can block if another thread owns the lock that protects the
/// queue. If the queue is full The thread will be blocked in this queue
/// until someone else gets an element from the queue
/// @param element to insert into the queue
/// @return True if the elem was successfully inserted into the queue.
/// False otherwise
bool Push(const T &a_elem);
/// @brief inserts an element into queue queue
/// This call can block if another thread owns the lock that protects the
/// queue. If the queue is full The call will return false and the element
/// won't be inserted
/// @param element to insert into the queue
/// @return True if the elem was successfully inserted into the queue.
/// False otherwise
bool TryPush(const T &a_elem);
/// @brief extracts an element from the queue (and deletes it from the q)
/// If the queue is empty this call will block the thread until there is
/// something in the queue to be extracted
/// @param a reference where the element from the queue will be saved to
void Pop(T &out_data);
/// @brief extracts an element from the queue (and deletes it from the q)
/// This call gets the block that protects the queue. It will extract the
/// element from the queue only if there are elements in it
/// @param reference to the variable where the result will be saved
/// @return True if the element was retrieved from the queue.
/// False if the queue was empty
bool TryPop(T &out_data);
/// @brief extracts an element from the queue (and deletes it from the q)
/// If the queue is empty this call will block the thread until there
/// is something in the queue to be extracted or until the timer
/// (2nd parameter) expires
/// @param reference to the variable where the result will be saved
/// @param microsecondsto wait before returning if the queue was empty
/// @return True if the element was retrieved from the queue.
/// False if the timeout was reached
bool TimedWaitPop(T &data, glong microsecs);
protected:
std::queue<T> m_theQueue;
/// maximum number of elements for the queue
std::size_t m_maximumSize;
/// Mutex to protect the queue
GMutex* m_mutex;
/// Conditional variable to wake up threads
GCond* m_cond;
};
// include the implementation file
#include "g_blocking_queue_impl.h"
#endif /* _GBLOCKINGQUEUE_H_ */