1 /* 2 * Copyright 2001-2007, 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 /** Queue for holding BMessages */ 11 12 13 #include <MessageQueue.h> 14 #include <Autolock.h> 15 #include <Message.h> 16 17 18 BMessageQueue::BMessageQueue() 19 : 20 fHead(NULL), 21 fTail(NULL), 22 fMessageCount(0), 23 fLock("BMessageQueue Lock") 24 { 25 } 26 27 28 BMessageQueue::~BMessageQueue() 29 { 30 if (!Lock()) 31 return; 32 33 BMessage* message = fHead; 34 while (message != NULL) { 35 BMessage *next = message->fQueueLink; 36 37 delete message; 38 message = next; 39 } 40 } 41 42 43 void 44 BMessageQueue::AddMessage(BMessage* message) 45 { 46 if (message == NULL) 47 return; 48 49 BAutolock _(fLock); 50 if (!IsLocked()) 51 return; 52 53 // The message passed in will be the last message on the queue so its 54 // link member should be set to null. 55 message->fQueueLink = NULL; 56 57 fMessageCount++; 58 59 if (fTail == NULL) { 60 // there are no messages in the queue yet 61 fHead = fTail = message; 62 } else { 63 // just add it after the tail 64 fTail->fQueueLink = message; 65 fTail = message; 66 } 67 } 68 69 70 void 71 BMessageQueue::RemoveMessage(BMessage* message) 72 { 73 if (message == NULL) 74 return; 75 76 BAutolock _(fLock); 77 if (!IsLocked()) 78 return; 79 80 BMessage* last = NULL; 81 for (BMessage* entry = fHead; entry != NULL; entry = entry->fQueueLink) { 82 if (entry == message) { 83 // remove this one 84 if (entry == fHead) 85 fHead = entry->fQueueLink; 86 else 87 last->fQueueLink = entry->fQueueLink; 88 89 if (entry == fTail) 90 fTail = last; 91 92 fMessageCount--; 93 return; 94 } 95 last = entry; 96 } 97 } 98 99 100 int32 101 BMessageQueue::CountMessages() const 102 { 103 return fMessageCount; 104 } 105 106 107 bool 108 BMessageQueue::IsEmpty() const 109 { 110 return fMessageCount == 0; 111 } 112 113 114 BMessage * 115 BMessageQueue::FindMessage(int32 index) const 116 { 117 BAutolock _(fLock); 118 if (!IsLocked()) 119 return NULL; 120 121 if (index < 0 || index >= fMessageCount) 122 return NULL; 123 124 for (BMessage* message = fHead; message != NULL; message = message->fQueueLink) { 125 // If the index reaches zero, then we have found a match. 126 if (index == 0) 127 return message; 128 129 index--; 130 } 131 132 return NULL; 133 } 134 135 136 BMessage * 137 BMessageQueue::FindMessage(uint32 what, int32 index) const 138 { 139 BAutolock _(fLock); 140 if (!IsLocked()) 141 return NULL; 142 143 if (index < 0 || index >= fMessageCount) 144 return NULL; 145 146 for (BMessage* message = fHead; message != NULL; message = message->fQueueLink) { 147 if (message->what == what) { 148 // If the index reaches zero, then we have found a match. 149 if (index == 0) 150 return message; 151 152 index--; 153 } 154 } 155 156 return NULL; 157 } 158 159 160 bool 161 BMessageQueue::Lock() 162 { 163 return fLock.Lock(); 164 } 165 166 167 void 168 BMessageQueue::Unlock() 169 { 170 fLock.Unlock(); 171 } 172 173 174 bool 175 BMessageQueue::IsLocked() const 176 { 177 return fLock.IsLocked(); 178 } 179 180 181 BMessage * 182 BMessageQueue::NextMessage() 183 { 184 BAutolock _(fLock); 185 if (!IsLocked()) 186 return NULL; 187 188 // remove the head of the queue, if any, and return it 189 190 BMessage* head = fHead; 191 if (head == NULL) 192 return NULL; 193 194 fMessageCount--; 195 fHead = head->fQueueLink; 196 197 if (fHead == NULL) { 198 // If the queue is empty after removing the front element, 199 // we need to set the tail of the queue to NULL since the queue 200 // is now empty. 201 fTail = NULL; 202 } 203 204 return head; 205 } 206 207 208 bool 209 BMessageQueue::IsNextMessage(const BMessage* message) const 210 { 211 BAutolock _(fLock); 212 return fHead == message; 213 } 214 215 216 /*! 217 \brief This method is only here for R5 binary compatibility! 218 It should be dropped as soon as possible (it misses the const qualifier). 219 */ 220 bool 221 BMessageQueue::IsLocked() 222 { 223 return fLock.IsLocked(); 224 } 225 226 227 void BMessageQueue::_ReservedMessageQueue1() {} 228 void BMessageQueue::_ReservedMessageQueue2() {} 229 void BMessageQueue::_ReservedMessageQueue3() {} 230 231