vfs: check userland buffers before reading them.
[haiku.git] / src / servers / registrar / PriorityMessageQueue.cpp
blobc7542a355e9bf443c8372c9ffebdf35a38d73b4c
1 //----------------------------------------------------------------------
2 // This software is part of the OpenBeOS distribution and is covered
3 // by the MIT License.
4 //---------------------------------------------------------------------
6 #include <Message.h>
8 #include "PriorityMessageQueue.h"
10 // MessageInfo
11 class PriorityMessageQueue::MessageInfo {
12 public:
13 MessageInfo(BMessage *message, int32 priority)
14 : fMessage(message),
15 fPriority(priority)
19 BMessage *Message() const { return fMessage; }
20 int32 Priority() const { return fPriority; }
22 private:
23 BMessage *fMessage;
24 int32 fPriority;
28 // constructor
29 PriorityMessageQueue::PriorityMessageQueue()
30 : fLock(),
31 fMessages(20, true)
35 // destructor
36 PriorityMessageQueue::~PriorityMessageQueue()
38 // delete the messages
39 for (int32 i = 0; MessageInfo *info = fMessages.ItemAt(i); i++)
40 delete info->Message();
41 // the infos are deleted automatically
44 // Lock
45 bool
46 PriorityMessageQueue::Lock()
48 return fLock.Lock();
51 // Unlock
52 void
53 PriorityMessageQueue::Unlock()
55 fLock.Unlock();
58 // PushMessage
59 bool
60 PriorityMessageQueue::PushMessage(BMessage *message, int32 priority)
62 bool result = (message);
63 if (result)
64 result = Lock();
65 if (result) {
66 if (MessageInfo *info = new MessageInfo(message, priority)) {
67 // find the insertion index
68 int32 index = _FindInsertionIndex(priority);
69 if (!fMessages.AddItem(info, index)) {
70 result = false;
71 delete info;
73 } else // no memory
74 result = false;
75 Unlock();
77 return result;
80 // PopMessage
81 BMessage *
82 PriorityMessageQueue::PopMessage()
84 BMessage *result = NULL;
85 if (Lock()) {
86 if (MessageInfo *info = fMessages.RemoveItemAt(0)) {
87 result = info->Message();
88 delete info;
90 Unlock();
92 return result;
95 // CountMessages
96 int32
97 PriorityMessageQueue::CountMessages() const
99 int32 result = 0;
100 if (fLock.Lock()) {
101 result = fMessages.CountItems();
102 fLock.Unlock();
104 return result;
107 // IsEmpty
108 bool
109 PriorityMessageQueue::IsEmpty() const
111 return (CountMessages() == 0);
114 // _FindInsertionIndex
115 int32
116 PriorityMessageQueue::_FindInsertionIndex(int32 priority)
118 int32 lower = 0;
119 int32 upper = fMessages.CountItems();
120 while (lower < upper) {
121 int32 mid = (lower + upper) / 2;
122 MessageInfo *info = fMessages.ItemAt(mid);
123 if (info->Priority() >= priority)
124 lower = mid + 1;
125 else
126 upper = mid;
128 return lower;