1//---------------------------------------------------------------------- 2// This software is part of the Haiku distribution and is covered 3// by the MIT License. 4//--------------------------------------------------------------------- 5 6#include <Message.h> 7 8#include "PriorityMessageQueue.h" 9 10// MessageInfo 11class PriorityMessageQueue::MessageInfo { 12public: 13 MessageInfo(BMessage *message, int32 priority) 14 : fMessage(message), 15 fPriority(priority) 16 { 17 } 18 19 BMessage *Message() const { return fMessage; } 20 int32 Priority() const { return fPriority; } 21 22private: 23 BMessage *fMessage; 24 int32 fPriority; 25}; 26 27 28// constructor 29PriorityMessageQueue::PriorityMessageQueue() 30 : fLock(), 31 fMessages(20, true) 32{ 33} 34 35// destructor 36PriorityMessageQueue::~PriorityMessageQueue() 37{ 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 42} 43 44// Lock 45bool 46PriorityMessageQueue::Lock() 47{ 48 return fLock.Lock(); 49} 50 51// Unlock 52void 53PriorityMessageQueue::Unlock() 54{ 55 fLock.Unlock(); 56} 57 58// PushMessage 59bool 60PriorityMessageQueue::PushMessage(BMessage *message, int32 priority) 61{ 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; 72 } 73 } else // no memory 74 result = false; 75 Unlock(); 76 } 77 return result; 78} 79 80// PopMessage 81BMessage * 82PriorityMessageQueue::PopMessage() 83{ 84 BMessage *result = NULL; 85 if (Lock()) { 86 if (MessageInfo *info = fMessages.RemoveItemAt(0)) { 87 result = info->Message(); 88 delete info; 89 } 90 Unlock(); 91 } 92 return result; 93} 94 95// CountMessages 96int32 97PriorityMessageQueue::CountMessages() const 98{ 99 int32 result = 0; 100 if (fLock.Lock()) { 101 result = fMessages.CountItems(); 102 fLock.Unlock(); 103 } 104 return result; 105} 106 107// IsEmpty 108bool 109PriorityMessageQueue::IsEmpty() const 110{ 111 return (CountMessages() == 0); 112} 113 114// _FindInsertionIndex 115int32 116PriorityMessageQueue::_FindInsertionIndex(int32 priority) 117{ 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; 127 } 128 return lower; 129} 130 131