3 // Copyright (c) 2004, Ingo Weinhold (bonefish@cs.tu-berlin.de)
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
28 #ifndef BLOCKING_QUEUE_H
29 #define BLOCKING_QUEUE_H
35 #include "AutoLocker.h"
39 typedef BLocker Locker
;
41 template<typename Element
>
42 class BlockingQueue
: public Locker
{
44 BlockingQueue(const char* name
= NULL
);
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
);
61 vector
<Element
*> fElements
;
62 sem_id fElementSemaphore
;
66 template<typename Element
>
67 BlockingQueue
<Element
>::BlockingQueue(const char* name
)
71 fElementSemaphore
= create_sem(0, (name
? name
: "blocking queue"));
75 template<typename Element
>
76 BlockingQueue
<Element
>::~BlockingQueue()
78 if (fElementSemaphore
>= 0)
79 delete_sem(fElementSemaphore
);
83 template<typename Element
>
85 BlockingQueue
<Element
>::InitCheck() const
87 return (fElementSemaphore
< 0 ? fElementSemaphore
: B_OK
);
91 template<typename Element
>
93 BlockingQueue
<Element
>::Close(bool deleteElements
,
94 const vector
<Element
*>** elements
)
96 AutoLocker
<Locker
> _(this);
97 status_t error
= delete_sem(fElementSemaphore
);
100 fElementSemaphore
= -1;
102 *elements
= &fElements
;
103 if (deleteElements
) {
104 int32 count
= fElements
.size();
105 for (int32 i
= 0; i
< count
; i
++)
112 template<typename Element
>
114 BlockingQueue
<Element
>::Push(Element
* element
)
116 AutoLocker
<Locker
> _(this);
117 if (fElementSemaphore
< 0)
120 fElements
.push_back(element
);
121 } catch (std::bad_alloc
) {
124 status_t error
= release_sem(fElementSemaphore
);
126 fElements
.erase(fElements
.begin() + fElements
.size() - 1);
131 template<typename Element
>
133 BlockingQueue
<Element
>::Pop(Element
** element
, bigtime_t timeout
)
135 status_t error
= acquire_sem_etc(fElementSemaphore
, 1, B_RELATIVE_TIMEOUT
,
139 AutoLocker
<Locker
> _(this);
140 if (fElementSemaphore
< 0)
142 int32 count
= fElements
.size();
145 *element
= fElements
[0];
146 fElements
.erase(fElements
.begin());
151 template<typename Element
>
153 BlockingQueue
<Element
>::Peek(Element
** element
)
155 AutoLocker
<Locker
> _(this);
156 if (fElementSemaphore
< 0)
158 int32 count
= fElements
.size();
160 return B_ENTRY_NOT_FOUND
;
161 *element
= fElements
[0];
166 template<typename Element
>
168 BlockingQueue
<Element
>::Remove(Element
* element
)
170 status_t error
= acquire_sem_etc(fElementSemaphore
, 1,
171 B_RELATIVE_TIMEOUT
, 0);
174 AutoLocker
<Locker
> _(this);
175 if (fElementSemaphore
< 0)
179 for (int32 i
= fElements
.size() - 1; i
>= 0; i
--) {
180 if (fElements
[i
] == element
) {
181 fElements
.erase(fElements
.begin() + i
);
186 release_sem(fElementSemaphore
);
187 return B_ENTRY_NOT_FOUND
;
191 ERROR(("ERROR: BlockingQueue::Remove(): Removed %ld elements!\n",
199 template<typename Element
>
201 BlockingQueue
<Element
>::Size()
203 AutoLocker
<Locker
> _(this);
204 return (fElements
.size());
207 #endif // BLOCKING_QUEUE_H