1 mike 1.2 //%2006////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
6 // IBM Corp.; EMC Corporation, The Open Group.
7 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
9 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
11 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 //
21 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 mike 1.2 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 // Author: Mike Day (mdday@us.ibm.com)
33 //
34 // Modified By: Amit K Arora, IBM (amita@in.ibm.com) for PEP#101
35 // Alagaraja Ramasubramanian (alags_raj@in.ibm.com) for Bug#1090
36 // Amit K Arora, IBM (amita@in.ibm.com) for Bug#2322
37 // David Dillard, VERITAS Software Corp.
38 // (david.dillard@veritas.com)
39 // Amit K Arora, IBM (amita@in.ibm.com) for Bug#2960
40 //
41 // Reworked By:
42 // Mike Brasher (m.brasher@inovadevelopment.com)
43 mike 1.2 //
44 //%/////////////////////////////////////////////////////////////////////////////
45
46 #ifndef Pegasus_AsyncQueue_h
47 #define Pegasus_AsyncQueue_h
48
49 #include <Pegasus/Common/Linkage.h>
50 #include <Pegasus/Common/List.h>
|
51 mike 1.3 #include <Pegasus/Common/Condition.h>
|
52 mike 1.2
53 PEGASUS_NAMESPACE_BEGIN
54
55 /** AsyncQueue implementation (formerly AsyncDQueue).
56 */
57 template<class ElemType>
58 class AsyncQueue
59 {
60 public:
61
|
62 mike 1.3 /** Constructor (zero means unlimited capacity).
|
63 mike 1.2 */
|
64 mike 1.3 AsyncQueue(size_t capacity = 0);
|
65 mike 1.2
66 /** Destructor.
67 */
68 virtual ~AsyncQueue();
69
|
70 mike 1.3 /** Close the queue so that subsequent enqueue() and dequeue() requests
71 result in ListClosed() exceptions.
|
72 mike 1.2 */
|
73 mike 1.3 void close();
|
74 mike 1.2
75 /** Enqueue an element at the back of queue.
76 */
77 void enqueue(ElemType *element);
78
|
79 mike 1.3 /** Enqueue an element at the back of queue (wait if the queue is full).
|
80 mike 1.2 */
81 void enqueue_wait(ElemType *element);
82
83 /** Dequeue an element from the front of the queue. Return null immediately
84 if queue is empty.
85 */
86 ElemType *dequeue();
87
|
88 mike 1.3 /** Dequeue an element from the front of the queue (wait if the queue is
89 empty).
|
90 mike 1.2 */
91 ElemType *dequeue_wait();
92
93 /** Discard all the elements on the list. The size becomes zero afterwards.
94 */
95 void clear();
96
97 /** Return number of element in queue.
98 */
|
99 mike 1.3 Uint32 count() const { return _size.get(); }
|
100 mike 1.2
|
101 mike 1.3 /** Get capacity.
|
102 mike 1.2 */
103 Uint32 capacity() const { return _capacity.get(); }
104
|
105 mike 1.3 /** Return number of element in queue.
|
106 mike 1.2 */
|
107 mike 1.3 Uint32 size() const { return _size.get(); }
|
108 mike 1.2
109 /** Return true is queue is empty (has zero elements).
110 */
|
111 mike 1.3 Boolean is_empty() const { return _size.get() == 0; }
|
112 mike 1.2
|
113 mike 1.3 /** Return true if the queue is full.
|
114 mike 1.2 */
|
115 mike 1.3 Boolean is_full() const { return _size.get() == _capacity.get(); }
|
116 mike 1.2
|
117 mike 1.3 /** Return true if the queue has been closed (in which case no new
118 elements may be enqueued).
|
119 mike 1.2 */
|
120 mike 1.3 Boolean is_closed() const { return _closed.get(); }
|
121 mike 1.2
122 private:
123
|
124 mike 1.3 Mutex _mutex;
125 Condition _not_empty;
126 Condition _not_full;
|
127 mike 1.2 AtomicInt _capacity;
|
128 mike 1.3 AtomicInt _size;
129 AtomicInt _closed;
|
130 mike 1.2 typedef List<ElemType,NullLock> Rep;
131 Rep _rep;
132 };
133
134 template<class ElemType>
|
135 mike 1.4 AsyncQueue<ElemType>::AsyncQueue(size_t capacity) :
136 _mutex(Mutex::NON_RECURSIVE), _capacity(capacity)
|
137 mike 1.2 {
|
138 mike 1.3 if (capacity == 0)
139 _capacity.set(0x7FFFFFFF);
|
140 mike 1.2 }
141
142 template<class ElemType>
143 AsyncQueue<ElemType>::~AsyncQueue()
144 {
145 }
146
147 template<class ElemType>
|
148 mike 1.3 void AsyncQueue<ElemType>::close()
|
149 mike 1.2 {
|
150 mike 1.3 AutoMutex auto_mutex(_mutex);
|
151 mike 1.2
|
152 mike 1.3 if (!is_closed())
|
153 mike 1.2 {
|
154 mike 1.3 _closed++;
155 _not_full.signal();
156 _not_empty.signal();
|
157 mike 1.2 }
158 }
159
160 template<class ElemType>
|
161 mike 1.3 void AsyncQueue<ElemType>::enqueue(ElemType *element)
|
162 mike 1.2 {
|
163 mike 1.3 if (element)
164 {
165 AutoMutex auto_mutex(_mutex);
166
167 if (is_closed())
168 throw ListClosed();
169
170 if (is_full())
171 throw ListFull(_capacity.get());
|
172 mike 1.2
|
173 mike 1.3 _rep.insert_back(element);
174 _size++;
175 _not_empty.signal();
|
176 mike 1.2 }
177 }
178
179 template<class ElemType>
|
180 mike 1.3 void AsyncQueue<ElemType>::enqueue_wait(ElemType *element)
|
181 mike 1.2 {
|
182 mike 1.3 if (element)
183 {
184 AutoMutex auto_mutex(_mutex);
|
185 mike 1.2
|
186 mike 1.3 while (is_full())
187 {
188 if (is_closed())
189 throw ListClosed();
|
190 mike 1.2
|
191 mike 1.3 _not_full.wait(_mutex);
192 }
|
193 mike 1.2
|
194 mike 1.3 if (is_closed())
195 throw ListClosed();
|
196 mike 1.2
|
197 mike 1.3 _rep.insert_back(element);
198 _size++;
199 _not_empty.signal();
|
200 mike 1.2 }
201 }
202
203 template<class ElemType>
|
204 mike 1.3 void AsyncQueue<ElemType>::clear()
|
205 mike 1.2 {
|
206 mike 1.3 AutoMutex auto_mutex(_mutex);
207 _rep.clear();
208 _size = 0;
209 _not_full.signal();
|
210 mike 1.2 }
211
212 template<class ElemType>
|
213 mike 1.3 ElemType* AsyncQueue<ElemType>::dequeue()
|
214 mike 1.2 {
|
215 mike 1.3 AutoMutex auto_mutex(_mutex);
216
217 if (is_closed())
|
218 mike 1.2 throw ListClosed();
219
|
220 mike 1.3 ElemType* p = _rep.remove_front();
|
221 mike 1.2
|
222 mike 1.3 if (p)
|
223 mike 1.2 {
|
224 mike 1.3 _size--;
225 _not_full.signal();
|
226 mike 1.2 }
|
227 mike 1.3
228 return p;
|
229 mike 1.2 }
230
231 template<class ElemType>
|
232 mike 1.3 ElemType* AsyncQueue<ElemType>::dequeue_wait()
|
233 mike 1.2 {
|
234 mike 1.3 AutoMutex auto_mutex(_mutex);
235
236 while (is_empty())
|
237 mike 1.2 {
|
238 mike 1.3 if (is_closed())
239 throw ListClosed();
|
240 mike 1.2
|
241 mike 1.3 _not_empty.wait(_mutex);
|
242 mike 1.2 }
243
|
244 mike 1.3 if (is_closed())
245 throw ListClosed();
|
246 mike 1.2
|
247 mike 1.3 ElemType* p = _rep.remove_front();
248 PEGASUS_DEBUG_ASSERT(p != 0);
249 _size--;
250 _not_full.signal();
|
251 mike 1.2
|
252 mike 1.3 return p;
|
253 mike 1.2 }
254
255 PEGASUS_NAMESPACE_END
256
257 #endif /* Pegasus_AsyncQueue_h */
|