xref: /haiku/src/servers/media/Queue.cpp (revision 68ea01249e1e2088933cb12f9c28d4e5c5d1c9ef)
1 /*
2  * Copyright 2002, Marcus Overhagen. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 /*!	This is a simple multi thread save queue.
8 
9 	One thread calls AddItem() to add items, and when it is finished doing
10 	so, it calls Terminate(). Another thread calls RemoveItem() to remove
11 	items from the queue. RemoveItem() blocks when no items are available.
12 	As soon as Terminate() is called and the queue is empty, RemoveItem()
13 	returns NULL.
14 */
15 
16 
17 #include "Queue.h"
18 
19 #include <Autolock.h>
20 #include <OS.h>
21 
22 
23 Queue::Queue()
24 	:
25 	BLocker("queue locker"),
26 	fSem(create_sem(0, "queue sem"))
27 {
28 }
29 
30 
31 Queue::~Queue()
32 {
33 	if (fSem >= 0)
34 		delete_sem(fSem);
35 }
36 
37 
38 status_t
39 Queue::Terminate()
40 {
41 	BAutolock _(this);
42 
43 	if (fSem < 0)
44 		return B_ERROR;
45 
46 	delete_sem(fSem);
47 	fSem = -1;
48 	return B_OK;
49 }
50 
51 
52 status_t
53 Queue::AddItem(void* item)
54 {
55 	BAutolock _(this);
56 
57 	if (fSem < 0)
58 		return B_ERROR;
59 
60 	if (!fList.AddItem(item))
61 		return B_NO_MEMORY;
62 
63 	release_sem(fSem);
64 	return B_OK;
65 }
66 
67 
68 void*
69 Queue::RemoveItem()
70 {
71 	// if the semaphore is deleted by Terminate(),
72 	// this will no longer block
73 	while (acquire_sem(fSem) == B_INTERRUPTED)
74 		;
75 
76 	BAutolock _(this);
77 
78 	// if the list is empty, which can only happen after
79 	// Terminate() was called, item will be NULL
80 	return fList.RemoveItem((int32)0);
81 }
82