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 19 BMessageQueue::BMessageQueue() 20 : 21 fHead(NULL), 22 fTail(NULL), 23 fMessageCount(0), 24 fLock("BMessageQueue Lock") 25 { 26 } 27 28 29 BMessageQueue::~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 44 void 45 BMessageQueue::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 71 void 72 BMessageQueue::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 101 int32 102 BMessageQueue::CountMessages() const 103 { 104 return fMessageCount; 105 } 106 107 108 bool 109 BMessageQueue::IsEmpty() const 110 { 111 return fMessageCount == 0; 112 } 113 114 115 BMessage* 116 BMessageQueue::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 137 BMessage* 138 BMessageQueue::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 161 bool 162 BMessageQueue::Lock() 163 { 164 return fLock.Lock(); 165 } 166 167 168 void 169 BMessageQueue::Unlock() 170 { 171 fLock.Unlock(); 172 } 173 174 175 bool 176 BMessageQueue::IsLocked() const 177 { 178 return fLock.IsLocked(); 179 } 180 181 182 BMessage* 183 BMessageQueue::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 209 bool 210 BMessageQueue::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). 219 bool 220 BMessageQueue::IsLocked() 221 { 222 return fLock.IsLocked(); 223 } 224 225 226 void BMessageQueue::_ReservedMessageQueue1() {} 227 void BMessageQueue::_ReservedMessageQueue2() {} 228 void BMessageQueue::_ReservedMessageQueue3() {} 229 230