/* * Copyright 2001-2014 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Unknown? Eric? * Axel Dörfler, axeld@pinc-software.de */ // Queue for holding BMessages #include #include #include BMessageQueue::BMessageQueue() : fHead(NULL), fTail(NULL), fMessageCount(0), fLock("BMessageQueue Lock") { } BMessageQueue::~BMessageQueue() { if (!Lock()) return; BMessage* message = fHead; while (message != NULL) { BMessage* next = message->fQueueLink; delete message; message = next; } } void BMessageQueue::AddMessage(BMessage* message) { if (message == NULL) return; BAutolock _(fLock); if (!IsLocked()) return; // The message passed in will be the last message on the queue so its // link member should be set to null. message->fQueueLink = NULL; fMessageCount++; if (fTail == NULL) { // there are no messages in the queue yet fHead = fTail = message; } else { // just add it after the tail fTail->fQueueLink = message; fTail = message; } } void BMessageQueue::RemoveMessage(BMessage* message) { if (message == NULL) return; BAutolock _(fLock); if (!IsLocked()) return; BMessage* last = NULL; for (BMessage* entry = fHead; entry != NULL; entry = entry->fQueueLink) { if (entry == message) { // remove this one if (entry == fHead) fHead = entry->fQueueLink; else last->fQueueLink = entry->fQueueLink; if (entry == fTail) fTail = last; fMessageCount--; return; } last = entry; } } int32 BMessageQueue::CountMessages() const { return fMessageCount; } bool BMessageQueue::IsEmpty() const { return fMessageCount == 0; } BMessage* BMessageQueue::FindMessage(int32 index) const { BAutolock _(fLock); if (!IsLocked()) return NULL; if (index < 0 || index >= fMessageCount) return NULL; for (BMessage* message = fHead; message != NULL; message = message->fQueueLink) { // If the index reaches zero, then we have found a match. if (index == 0) return message; index--; } return NULL; } BMessage* BMessageQueue::FindMessage(uint32 what, int32 index) const { BAutolock _(fLock); if (!IsLocked()) return NULL; if (index < 0 || index >= fMessageCount) return NULL; for (BMessage* message = fHead; message != NULL; message = message->fQueueLink) { if (message->what == what) { // If the index reaches zero, then we have found a match. if (index == 0) return message; index--; } } return NULL; } bool BMessageQueue::Lock() { return fLock.Lock(); } void BMessageQueue::Unlock() { fLock.Unlock(); } bool BMessageQueue::IsLocked() const { return fLock.IsLocked(); } BMessage* BMessageQueue::NextMessage() { BAutolock _(fLock); if (!IsLocked()) return NULL; // remove the head of the queue, if any, and return it BMessage* head = fHead; if (head == NULL) return NULL; fMessageCount--; fHead = head->fQueueLink; if (fHead == NULL) { // If the queue is empty after removing the front element, // we need to set the tail of the queue to NULL since the queue // is now empty. fTail = NULL; } return head; } bool BMessageQueue::IsNextMessage(const BMessage* message) const { BAutolock _(fLock); return fHead == message; } // This method is only here for R5 binary compatibility! // It should be dropped as soon as possible (it misses the const qualifier). bool BMessageQueue::IsLocked() { return fLock.IsLocked(); } void BMessageQueue::_ReservedMessageQueue1() {} void BMessageQueue::_ReservedMessageQueue2() {} void BMessageQueue::_ReservedMessageQueue3() {}