btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / apps / installer / BlockingQueue.h
blob56a9d53ddbe76106d4972611c254bc8e66851505
1 // BlockingQueue.h
2 //
3 // Copyright (c) 2004, Ingo Weinhold (bonefish@cs.tu-berlin.de)
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a
6 // copy of this software and associated documentation files (the "Software"),
7 // to deal in the Software without restriction, including without limitation
8 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 // and/or sell copies of the Software, and to permit persons to whom the
10 // Software is furnished to do so, subject to the following conditions:
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 // DEALINGS IN THE SOFTWARE.
23 // Except as contained in this notice, the name of a copyright holder shall
24 // not be used in advertising or otherwise to promote the sale, use or other
25 // dealings in this Software without prior written authorization of the
26 // copyright holder.
28 #ifndef BLOCKING_QUEUE_H
29 #define BLOCKING_QUEUE_H
31 #include <vector>
33 #include <Locker.h>
35 #include "AutoLocker.h"
37 using std::vector;
39 typedef BLocker Locker;
41 template<typename Element>
42 class BlockingQueue : public Locker {
43 public:
44 BlockingQueue(const char* name = NULL);
45 ~BlockingQueue();
47 status_t InitCheck() const;
49 status_t Close(bool deleteElements,
50 const vector<Element*>** elements = NULL);
52 status_t Push(Element* element);
53 status_t Pop(Element** element,
54 bigtime_t timeout = B_INFINITE_TIMEOUT);
55 status_t Peek(Element** element);
56 status_t Remove(Element* element);
58 int32 Size();
60 private:
61 vector<Element*> fElements;
62 sem_id fElementSemaphore;
65 // constructor
66 template<typename Element>
67 BlockingQueue<Element>::BlockingQueue(const char* name)
68 : fElements(),
69 fElementSemaphore(-1)
71 fElementSemaphore = create_sem(0, (name ? name : "blocking queue"));
74 // destructor
75 template<typename Element>
76 BlockingQueue<Element>::~BlockingQueue()
78 if (fElementSemaphore >= 0)
79 delete_sem(fElementSemaphore);
82 // InitCheck
83 template<typename Element>
84 status_t
85 BlockingQueue<Element>::InitCheck() const
87 return (fElementSemaphore < 0 ? fElementSemaphore : B_OK);
90 // Close
91 template<typename Element>
92 status_t
93 BlockingQueue<Element>::Close(bool deleteElements,
94 const vector<Element*>** elements)
96 AutoLocker<Locker> _(this);
97 status_t error = delete_sem(fElementSemaphore);
98 if (error != B_OK)
99 return error;
100 fElementSemaphore = -1;
101 if (elements)
102 *elements = &fElements;
103 if (deleteElements) {
104 int32 count = fElements.size();
105 for (int32 i = 0; i < count; i++)
106 delete fElements[i];
108 return error;
111 // Push
112 template<typename Element>
113 status_t
114 BlockingQueue<Element>::Push(Element* element)
116 AutoLocker<Locker> _(this);
117 if (fElementSemaphore < 0)
118 return B_NO_INIT;
119 try {
120 fElements.push_back(element);
121 } catch (std::bad_alloc) {
122 return B_NO_MEMORY;
124 status_t error = release_sem(fElementSemaphore);
125 if (error != B_OK)
126 fElements.erase(fElements.begin() + fElements.size() - 1);
127 return error;
130 // Pop
131 template<typename Element>
132 status_t
133 BlockingQueue<Element>::Pop(Element** element, bigtime_t timeout)
135 status_t error = acquire_sem_etc(fElementSemaphore, 1, B_RELATIVE_TIMEOUT,
136 timeout);
137 if (error != B_OK)
138 return error;
139 AutoLocker<Locker> _(this);
140 if (fElementSemaphore < 0)
141 return B_NO_INIT;
142 int32 count = fElements.size();
143 if (count == 0)
144 return B_ERROR;
145 *element = fElements[0];
146 fElements.erase(fElements.begin());
147 return B_OK;
150 // Peek
151 template<typename Element>
152 status_t
153 BlockingQueue<Element>::Peek(Element** element)
155 AutoLocker<Locker> _(this);
156 if (fElementSemaphore < 0)
157 return B_NO_INIT;
158 int32 count = fElements.size();
159 if (count == 0)
160 return B_ENTRY_NOT_FOUND;
161 *element = fElements[0];
162 return B_OK;
165 // Remove
166 template<typename Element>
167 status_t
168 BlockingQueue<Element>::Remove(Element* element)
170 status_t error = acquire_sem_etc(fElementSemaphore, 1,
171 B_RELATIVE_TIMEOUT, 0);
172 if (error != B_OK)
173 return error;
174 AutoLocker<Locker> _(this);
175 if (fElementSemaphore < 0)
176 return B_NO_INIT;
178 int32 count = 0;
179 for (int32 i = fElements.size() - 1; i >= 0; i--) {
180 if (fElements[i] == element) {
181 fElements.erase(fElements.begin() + i);
182 count++;
185 if (count == 0) {
186 release_sem(fElementSemaphore);
187 return B_ENTRY_NOT_FOUND;
189 #if 0
190 if (count > 1) {
191 ERROR(("ERROR: BlockingQueue::Remove(): Removed %ld elements!\n",
192 count));
194 #endif
195 return error;
198 // Size
199 template<typename Element>
200 int32
201 BlockingQueue<Element>::Size()
203 AutoLocker<Locker> _(this);
204 return (fElements.size());
207 #endif // BLOCKING_QUEUE_H