fadf867232
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2642 a95241bf-73f2-0310-859d-f6bbb57e9c96
131 lines
2.4 KiB
C++
131 lines
2.4 KiB
C++
//----------------------------------------------------------------------
|
|
// This software is part of the OpenBeOS distribution and is covered
|
|
// by the OpenBeOS license.
|
|
//---------------------------------------------------------------------
|
|
|
|
#include <Message.h>
|
|
|
|
#include "PriorityMessageQueue.h"
|
|
|
|
// MessageInfo
|
|
class PriorityMessageQueue::MessageInfo {
|
|
public:
|
|
MessageInfo(BMessage *message, int32 priority)
|
|
: fMessage(message),
|
|
fPriority(priority)
|
|
{
|
|
}
|
|
|
|
BMessage *Message() const { return fMessage; }
|
|
int32 Priority() const { return fPriority; }
|
|
|
|
private:
|
|
BMessage *fMessage;
|
|
int32 fPriority;
|
|
};
|
|
|
|
|
|
// constructor
|
|
PriorityMessageQueue::PriorityMessageQueue()
|
|
: fLock(),
|
|
fMessages(20, true)
|
|
{
|
|
}
|
|
|
|
// destructor
|
|
PriorityMessageQueue::~PriorityMessageQueue()
|
|
{
|
|
// delete the messages
|
|
for (int32 i = 0; MessageInfo *info = fMessages.ItemAt(i); i++)
|
|
delete info->Message();
|
|
// the infos are deleted automatically
|
|
}
|
|
|
|
// Lock
|
|
bool
|
|
PriorityMessageQueue::Lock()
|
|
{
|
|
return fLock.Lock();
|
|
}
|
|
|
|
// Unlock
|
|
void
|
|
PriorityMessageQueue::Unlock()
|
|
{
|
|
fLock.Unlock();
|
|
}
|
|
|
|
// PushMessage
|
|
bool
|
|
PriorityMessageQueue::PushMessage(BMessage *message, int32 priority)
|
|
{
|
|
bool result = (message);
|
|
if (result)
|
|
result = Lock();
|
|
if (result) {
|
|
if (MessageInfo *info = new MessageInfo(message, priority)) {
|
|
// find the insertion index
|
|
int32 index = _FindInsertionIndex(priority);
|
|
if (!fMessages.AddItem(info, index)) {
|
|
result = false;
|
|
delete info;
|
|
}
|
|
} else // no memory
|
|
result = false;
|
|
Unlock();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// PopMessage
|
|
BMessage *
|
|
PriorityMessageQueue::PopMessage()
|
|
{
|
|
BMessage *result = NULL;
|
|
if (Lock()) {
|
|
if (MessageInfo *info = fMessages.RemoveItemAt(0)) {
|
|
result = info->Message();
|
|
delete info;
|
|
}
|
|
Unlock();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// CountMessages
|
|
int32
|
|
PriorityMessageQueue::CountMessages() const
|
|
{
|
|
int32 result = 0;
|
|
if (fLock.Lock()) {
|
|
result = fMessages.CountItems();
|
|
fLock.Unlock();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// IsEmpty
|
|
bool
|
|
PriorityMessageQueue::IsEmpty() const
|
|
{
|
|
return (CountMessages() == 0);
|
|
}
|
|
|
|
// _FindInsertionIndex
|
|
int32
|
|
PriorityMessageQueue::_FindInsertionIndex(int32 priority)
|
|
{
|
|
int32 lower = 0;
|
|
int32 upper = fMessages.CountItems();
|
|
while (lower < upper) {
|
|
int32 mid = (lower + upper) / 2;
|
|
MessageInfo *info = fMessages.ItemAt(mid);
|
|
if (info->Priority() >= priority)
|
|
lower = mid + 1;
|
|
else
|
|
upper = mid;
|
|
}
|
|
return lower;
|
|
}
|
|
|