1/* 2 * Copyright 2001-2014 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Unknown? Eric? 7 * Axel Dörfler, axeld@pinc-software.de 8 */ 9 10 11// Queue for holding BMessages 12 13 14#include <MessageQueue.h> 15#include <Autolock.h> 16#include <Message.h> 17 18 19BMessageQueue::BMessageQueue() 20 : 21 fHead(NULL), 22 fTail(NULL), 23 fMessageCount(0), 24 fLock("BMessageQueue Lock") 25{ 26} 27 28 29BMessageQueue::~BMessageQueue() 30{ 31 if (!Lock()) 32 return; 33 34 BMessage* message = fHead; 35 while (message != NULL) { 36 BMessage* next = message->fQueueLink; 37 38 delete message; 39 message = next; 40 } 41} 42 43 44void 45BMessageQueue::AddMessage(BMessage* message) 46{ 47 if (message == NULL) 48 return; 49 50 BAutolock _(fLock); 51 if (!IsLocked()) 52 return; 53 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; 57 58 fMessageCount++; 59 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; 67 } 68} 69 70 71void 72BMessageQueue::RemoveMessage(BMessage* message) 73{ 74 if (message == NULL) 75 return; 76 77 BAutolock _(fLock); 78 if (!IsLocked()) 79 return; 80 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; 89 90 if (entry == fTail) 91 fTail = last; 92 93 fMessageCount--; 94 return; 95 } 96 last = entry; 97 } 98} 99 100 101int32 102BMessageQueue::CountMessages() const 103{ 104 return fMessageCount; 105} 106 107 108bool 109BMessageQueue::IsEmpty() const 110{ 111 return fMessageCount == 0; 112} 113 114 115BMessage* 116BMessageQueue::FindMessage(int32 index) const 117{ 118 BAutolock _(fLock); 119 if (!IsLocked()) 120 return NULL; 121 122 if (index < 0 || index >= fMessageCount) 123 return NULL; 124 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; 129 130 index--; 131 } 132 133 return NULL; 134} 135 136 137BMessage* 138BMessageQueue::FindMessage(uint32 what, int32 index) const 139{ 140 BAutolock _(fLock); 141 if (!IsLocked()) 142 return NULL; 143 144 if (index < 0 || index >= fMessageCount) 145 return NULL; 146 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; 152 153 index--; 154 } 155 } 156 157 return NULL; 158} 159 160 161bool 162BMessageQueue::Lock() 163{ 164 return fLock.Lock(); 165} 166 167 168void 169BMessageQueue::Unlock() 170{ 171 fLock.Unlock(); 172} 173 174 175bool 176BMessageQueue::IsLocked() const 177{ 178 return fLock.IsLocked(); 179} 180 181 182BMessage* 183BMessageQueue::NextMessage() 184{ 185 BAutolock _(fLock); 186 if (!IsLocked()) 187 return NULL; 188 189 // remove the head of the queue, if any, and return it 190 191 BMessage* head = fHead; 192 if (head == NULL) 193 return NULL; 194 195 fMessageCount--; 196 fHead = head->fQueueLink; 197 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; 203 } 204 205 return head; 206} 207 208 209bool 210BMessageQueue::IsNextMessage(const BMessage* message) const 211{ 212 BAutolock _(fLock); 213 return fHead == message; 214} 215 216 217// This method is only here for R5 binary compatibility! 218// It should be dropped as soon as possible (it misses the const qualifier). 219bool 220BMessageQueue::IsLocked() 221{ 222 return fLock.IsLocked(); 223} 224 225 226void BMessageQueue::_ReservedMessageQueue1() {} 227void BMessageQueue::_ReservedMessageQueue2() {} 228void BMessageQueue::_ReservedMessageQueue3() {} 229 230