vfs: check userland buffers before reading them.
[haiku.git] / src / kits / app / MessageQueue.cpp
blob6f481ed668c9ec853806ad14e369c18bc6ac1c36
1 /*
2 * Copyright 2001-2014 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Unknown? Eric?
7 * Axel Dörfler, axeld@pinc-software.de
8 */
11 // Queue for holding BMessages
14 #include <MessageQueue.h>
15 #include <Autolock.h>
16 #include <Message.h>
19 BMessageQueue::BMessageQueue()
21 fHead(NULL),
22 fTail(NULL),
23 fMessageCount(0),
24 fLock("BMessageQueue Lock")
29 BMessageQueue::~BMessageQueue()
31 if (!Lock())
32 return;
34 BMessage* message = fHead;
35 while (message != NULL) {
36 BMessage* next = message->fQueueLink;
38 delete message;
39 message = next;
44 void
45 BMessageQueue::AddMessage(BMessage* message)
47 if (message == NULL)
48 return;
50 BAutolock _(fLock);
51 if (!IsLocked())
52 return;
54 // The message passed in will be the last message on the queue so its
55 // link member should be set to null.
56 message->fQueueLink = NULL;
58 fMessageCount++;
60 if (fTail == NULL) {
61 // there are no messages in the queue yet
62 fHead = fTail = message;
63 } else {
64 // just add it after the tail
65 fTail->fQueueLink = message;
66 fTail = message;
71 void
72 BMessageQueue::RemoveMessage(BMessage* message)
74 if (message == NULL)
75 return;
77 BAutolock _(fLock);
78 if (!IsLocked())
79 return;
81 BMessage* last = NULL;
82 for (BMessage* entry = fHead; entry != NULL; entry = entry->fQueueLink) {
83 if (entry == message) {
84 // remove this one
85 if (entry == fHead)
86 fHead = entry->fQueueLink;
87 else
88 last->fQueueLink = entry->fQueueLink;
90 if (entry == fTail)
91 fTail = last;
93 fMessageCount--;
94 return;
96 last = entry;
101 int32
102 BMessageQueue::CountMessages() const
104 return fMessageCount;
108 bool
109 BMessageQueue::IsEmpty() const
111 return fMessageCount == 0;
115 BMessage*
116 BMessageQueue::FindMessage(int32 index) const
118 BAutolock _(fLock);
119 if (!IsLocked())
120 return NULL;
122 if (index < 0 || index >= fMessageCount)
123 return NULL;
125 for (BMessage* message = fHead; message != NULL; message = message->fQueueLink) {
126 // If the index reaches zero, then we have found a match.
127 if (index == 0)
128 return message;
130 index--;
133 return NULL;
137 BMessage*
138 BMessageQueue::FindMessage(uint32 what, int32 index) const
140 BAutolock _(fLock);
141 if (!IsLocked())
142 return NULL;
144 if (index < 0 || index >= fMessageCount)
145 return NULL;
147 for (BMessage* message = fHead; message != NULL; message = message->fQueueLink) {
148 if (message->what == what) {
149 // If the index reaches zero, then we have found a match.
150 if (index == 0)
151 return message;
153 index--;
157 return NULL;
161 bool
162 BMessageQueue::Lock()
164 return fLock.Lock();
168 void
169 BMessageQueue::Unlock()
171 fLock.Unlock();
175 bool
176 BMessageQueue::IsLocked() const
178 return fLock.IsLocked();
182 BMessage*
183 BMessageQueue::NextMessage()
185 BAutolock _(fLock);
186 if (!IsLocked())
187 return NULL;
189 // remove the head of the queue, if any, and return it
191 BMessage* head = fHead;
192 if (head == NULL)
193 return NULL;
195 fMessageCount--;
196 fHead = head->fQueueLink;
198 if (fHead == NULL) {
199 // If the queue is empty after removing the front element,
200 // we need to set the tail of the queue to NULL since the queue
201 // is now empty.
202 fTail = NULL;
205 return head;
209 bool
210 BMessageQueue::IsNextMessage(const BMessage* message) const
212 BAutolock _(fLock);
213 return fHead == message;
217 // This method is only here for R5 binary compatibility!
218 // It should be dropped as soon as possible (it misses the const qualifier).
219 bool
220 BMessageQueue::IsLocked()
222 return fLock.IsLocked();
226 void BMessageQueue::_ReservedMessageQueue1() {}
227 void BMessageQueue::_ReservedMessageQueue2() {}
228 void BMessageQueue::_ReservedMessageQueue3() {}