11ba67cc8SAxel Dörfler /*
2*be902ac4SJohn Scipione * Copyright 2001-2014 Haiku, Inc. All rights reserved.
31ba67cc8SAxel Dörfler * Distributed under the terms of the MIT License.
41ba67cc8SAxel Dörfler *
51ba67cc8SAxel Dörfler * Authors:
61ba67cc8SAxel Dörfler * Unknown? Eric?
71ba67cc8SAxel Dörfler * Axel Dörfler, axeld@pinc-software.de
81ba67cc8SAxel Dörfler */
91ba67cc8SAxel Dörfler
10*be902ac4SJohn Scipione
11*be902ac4SJohn Scipione // Queue for holding BMessages
121ba67cc8SAxel Dörfler
1352a38012Sejakowatz
1430fd5147Shaydentech #include <MessageQueue.h>
1530fd5147Shaydentech #include <Autolock.h>
1630fd5147Shaydentech #include <Message.h>
1752a38012Sejakowatz
1852a38012Sejakowatz
BMessageQueue()1989bdf573SMarcus Overhagen BMessageQueue::BMessageQueue()
201ba67cc8SAxel Dörfler :
211ba67cc8SAxel Dörfler fHead(NULL),
221ba67cc8SAxel Dörfler fTail(NULL),
2389bdf573SMarcus Overhagen fMessageCount(0),
241ba67cc8SAxel Dörfler fLock("BMessageQueue Lock")
2552a38012Sejakowatz {
2652a38012Sejakowatz }
2752a38012Sejakowatz
2852a38012Sejakowatz
~BMessageQueue()2952a38012Sejakowatz BMessageQueue::~BMessageQueue()
3052a38012Sejakowatz {
311ba67cc8SAxel Dörfler if (!Lock())
321ba67cc8SAxel Dörfler return;
331ba67cc8SAxel Dörfler
341ba67cc8SAxel Dörfler BMessage* message = fHead;
351ba67cc8SAxel Dörfler while (message != NULL) {
361ba67cc8SAxel Dörfler BMessage* next = message->fQueueLink;
371ba67cc8SAxel Dörfler
381ba67cc8SAxel Dörfler delete message;
391ba67cc8SAxel Dörfler message = next;
4052a38012Sejakowatz }
4152a38012Sejakowatz }
4252a38012Sejakowatz
4352a38012Sejakowatz
4452a38012Sejakowatz void
AddMessage(BMessage * message)4552a38012Sejakowatz BMessageQueue::AddMessage(BMessage* message)
4652a38012Sejakowatz {
471ba67cc8SAxel Dörfler if (message == NULL)
4852a38012Sejakowatz return;
4952a38012Sejakowatz
501ba67cc8SAxel Dörfler BAutolock _(fLock);
511ba67cc8SAxel Dörfler if (!IsLocked())
521ba67cc8SAxel Dörfler return;
5352a38012Sejakowatz
5452a38012Sejakowatz // The message passed in will be the last message on the queue so its
5552a38012Sejakowatz // link member should be set to null.
56cf10934eSMichael Lotz message->fQueueLink = NULL;
5752a38012Sejakowatz
5852a38012Sejakowatz fMessageCount++;
5952a38012Sejakowatz
601ba67cc8SAxel Dörfler if (fTail == NULL) {
611ba67cc8SAxel Dörfler // there are no messages in the queue yet
621ba67cc8SAxel Dörfler fHead = fTail = message;
6352a38012Sejakowatz } else {
641ba67cc8SAxel Dörfler // just add it after the tail
651ba67cc8SAxel Dörfler fTail->fQueueLink = message;
661ba67cc8SAxel Dörfler fTail = message;
6752a38012Sejakowatz }
6852a38012Sejakowatz }
6952a38012Sejakowatz
7052a38012Sejakowatz
7152a38012Sejakowatz void
RemoveMessage(BMessage * message)7252a38012Sejakowatz BMessageQueue::RemoveMessage(BMessage* message)
7352a38012Sejakowatz {
741ba67cc8SAxel Dörfler if (message == NULL)
7552a38012Sejakowatz return;
7652a38012Sejakowatz
771ba67cc8SAxel Dörfler BAutolock _(fLock);
781ba67cc8SAxel Dörfler if (!IsLocked())
791ba67cc8SAxel Dörfler return;
8052a38012Sejakowatz
811ba67cc8SAxel Dörfler BMessage* last = NULL;
821ba67cc8SAxel Dörfler for (BMessage* entry = fHead; entry != NULL; entry = entry->fQueueLink) {
831ba67cc8SAxel Dörfler if (entry == message) {
841ba67cc8SAxel Dörfler // remove this one
851ba67cc8SAxel Dörfler if (entry == fHead)
861ba67cc8SAxel Dörfler fHead = entry->fQueueLink;
876338e9daSAxel Dörfler else
886338e9daSAxel Dörfler last->fQueueLink = entry->fQueueLink;
896338e9daSAxel Dörfler
901ba67cc8SAxel Dörfler if (entry == fTail)
911ba67cc8SAxel Dörfler fTail = last;
9252a38012Sejakowatz
9352a38012Sejakowatz fMessageCount--;
9452a38012Sejakowatz return;
9552a38012Sejakowatz }
961ba67cc8SAxel Dörfler last = entry;
9752a38012Sejakowatz }
9852a38012Sejakowatz }
9952a38012Sejakowatz
10052a38012Sejakowatz
10152a38012Sejakowatz int32
CountMessages() const1021ba67cc8SAxel Dörfler BMessageQueue::CountMessages() const
10352a38012Sejakowatz {
10452a38012Sejakowatz return fMessageCount;
10552a38012Sejakowatz }
10652a38012Sejakowatz
10752a38012Sejakowatz
10852a38012Sejakowatz bool
IsEmpty() const1091ba67cc8SAxel Dörfler BMessageQueue::IsEmpty() const
11052a38012Sejakowatz {
1111ba67cc8SAxel Dörfler return fMessageCount == 0;
11252a38012Sejakowatz }
11352a38012Sejakowatz
11452a38012Sejakowatz
11552a38012Sejakowatz BMessage*
FindMessage(int32 index) const11652a38012Sejakowatz BMessageQueue::FindMessage(int32 index) const
11752a38012Sejakowatz {
1181ba67cc8SAxel Dörfler BAutolock _(fLock);
1191ba67cc8SAxel Dörfler if (!IsLocked())
1201ba67cc8SAxel Dörfler return NULL;
1211ba67cc8SAxel Dörfler
1221ba67cc8SAxel Dörfler if (index < 0 || index >= fMessageCount)
1231ba67cc8SAxel Dörfler return NULL;
1241ba67cc8SAxel Dörfler
1251ba67cc8SAxel Dörfler for (BMessage* message = fHead; message != NULL; message = message->fQueueLink) {
1261ba67cc8SAxel Dörfler // If the index reaches zero, then we have found a match.
1271ba67cc8SAxel Dörfler if (index == 0)
1281ba67cc8SAxel Dörfler return message;
1291ba67cc8SAxel Dörfler
1301ba67cc8SAxel Dörfler index--;
1311ba67cc8SAxel Dörfler }
1321ba67cc8SAxel Dörfler
13352a38012Sejakowatz return NULL;
13452a38012Sejakowatz }
13552a38012Sejakowatz
13652a38012Sejakowatz
13752a38012Sejakowatz BMessage*
FindMessage(uint32 what,int32 index) const1381ba67cc8SAxel Dörfler BMessageQueue::FindMessage(uint32 what, int32 index) const
13952a38012Sejakowatz {
1401ba67cc8SAxel Dörfler BAutolock _(fLock);
1411ba67cc8SAxel Dörfler if (!IsLocked())
1421ba67cc8SAxel Dörfler return NULL;
1431ba67cc8SAxel Dörfler
1441ba67cc8SAxel Dörfler if (index < 0 || index >= fMessageCount)
1451ba67cc8SAxel Dörfler return NULL;
1461ba67cc8SAxel Dörfler
1471ba67cc8SAxel Dörfler for (BMessage* message = fHead; message != NULL; message = message->fQueueLink) {
1481ba67cc8SAxel Dörfler if (message->what == what) {
1491ba67cc8SAxel Dörfler // If the index reaches zero, then we have found a match.
1501ba67cc8SAxel Dörfler if (index == 0)
1511ba67cc8SAxel Dörfler return message;
1521ba67cc8SAxel Dörfler
1531ba67cc8SAxel Dörfler index--;
1541ba67cc8SAxel Dörfler }
1551ba67cc8SAxel Dörfler }
1561ba67cc8SAxel Dörfler
15752a38012Sejakowatz return NULL;
15852a38012Sejakowatz }
15952a38012Sejakowatz
16052a38012Sejakowatz
16152a38012Sejakowatz bool
Lock()1621ba67cc8SAxel Dörfler BMessageQueue::Lock()
16352a38012Sejakowatz {
1641ba67cc8SAxel Dörfler return fLock.Lock();
16552a38012Sejakowatz }
16652a38012Sejakowatz
16752a38012Sejakowatz
16852a38012Sejakowatz void
Unlock()1691ba67cc8SAxel Dörfler BMessageQueue::Unlock()
17052a38012Sejakowatz {
1711ba67cc8SAxel Dörfler fLock.Unlock();
17252a38012Sejakowatz }
17352a38012Sejakowatz
17452a38012Sejakowatz
17552a38012Sejakowatz bool
IsLocked() const1761ba67cc8SAxel Dörfler BMessageQueue::IsLocked() const
17752a38012Sejakowatz {
1781ba67cc8SAxel Dörfler return fLock.IsLocked();
17952a38012Sejakowatz }
18052a38012Sejakowatz
18152a38012Sejakowatz
18252a38012Sejakowatz BMessage*
NextMessage()1831ba67cc8SAxel Dörfler BMessageQueue::NextMessage()
18452a38012Sejakowatz {
1851ba67cc8SAxel Dörfler BAutolock _(fLock);
1861ba67cc8SAxel Dörfler if (!IsLocked())
1871ba67cc8SAxel Dörfler return NULL;
18852a38012Sejakowatz
1891ba67cc8SAxel Dörfler // remove the head of the queue, if any, and return it
19052a38012Sejakowatz
1911ba67cc8SAxel Dörfler BMessage* head = fHead;
1921ba67cc8SAxel Dörfler if (head == NULL)
1931ba67cc8SAxel Dörfler return NULL;
1941ba67cc8SAxel Dörfler
19552a38012Sejakowatz fMessageCount--;
1961ba67cc8SAxel Dörfler fHead = head->fQueueLink;
1971ba67cc8SAxel Dörfler
1981ba67cc8SAxel Dörfler if (fHead == NULL) {
1991ba67cc8SAxel Dörfler // If the queue is empty after removing the front element,
2001ba67cc8SAxel Dörfler // we need to set the tail of the queue to NULL since the queue
20152a38012Sejakowatz // is now empty.
2021ba67cc8SAxel Dörfler fTail = NULL;
20352a38012Sejakowatz }
2041ba67cc8SAxel Dörfler
2051ba67cc8SAxel Dörfler return head;
20652a38012Sejakowatz }
20752a38012Sejakowatz
20852a38012Sejakowatz
209ca9b9188SAxel Dörfler bool
IsNextMessage(const BMessage * message) const210ca9b9188SAxel Dörfler BMessageQueue::IsNextMessage(const BMessage* message) const
211ca9b9188SAxel Dörfler {
212ca9b9188SAxel Dörfler BAutolock _(fLock);
213ca9b9188SAxel Dörfler return fHead == message;
214ca9b9188SAxel Dörfler }
215ca9b9188SAxel Dörfler
216ca9b9188SAxel Dörfler
217*be902ac4SJohn Scipione // This method is only here for R5 binary compatibility!
218*be902ac4SJohn Scipione // It should be dropped as soon as possible (it misses the const qualifier).
2191ba67cc8SAxel Dörfler bool
IsLocked()2201ba67cc8SAxel Dörfler BMessageQueue::IsLocked()
22152a38012Sejakowatz {
2221ba67cc8SAxel Dörfler return fLock.IsLocked();
22352a38012Sejakowatz }
22452a38012Sejakowatz
22552a38012Sejakowatz
_ReservedMessageQueue1()2261ba67cc8SAxel Dörfler void BMessageQueue::_ReservedMessageQueue1() {}
_ReservedMessageQueue2()2271ba67cc8SAxel Dörfler void BMessageQueue::_ReservedMessageQueue2() {}
_ReservedMessageQueue3()2281ba67cc8SAxel Dörfler void BMessageQueue::_ReservedMessageQueue3() {}
22952a38012Sejakowatz
230