xref: /haiku/src/kits/app/MessageQueue.cpp (revision 76441bab6ebb9132d0bb0ab623087bd2b9e861e0)
1*76441babSDarkWyrm //------------------------------------------------------------------------------
2*76441babSDarkWyrm //	Copyright (c) 2001-2002, OpenBeOS
352a38012Sejakowatz //
4*76441babSDarkWyrm //	Permission is hereby granted, free of charge, to any person obtaining a
5*76441babSDarkWyrm //	copy of this software and associated documentation files (the "Software"),
6*76441babSDarkWyrm //	to deal in the Software without restriction, including without limitation
7*76441babSDarkWyrm //	the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*76441babSDarkWyrm //	and/or sell copies of the Software, and to permit persons to whom the
9*76441babSDarkWyrm //	Software is furnished to do so, subject to the following conditions:
1052a38012Sejakowatz //
11*76441babSDarkWyrm //	The above copyright notice and this permission notice shall be included in
12*76441babSDarkWyrm //	all copies or substantial portions of the Software.
1352a38012Sejakowatz //
14*76441babSDarkWyrm //	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*76441babSDarkWyrm //	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*76441babSDarkWyrm //	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17*76441babSDarkWyrm //	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18*76441babSDarkWyrm //	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19*76441babSDarkWyrm //	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20*76441babSDarkWyrm //	DEALINGS IN THE SOFTWARE.
21*76441babSDarkWyrm //
22*76441babSDarkWyrm //	File Name:		MessageQueue.cpp
23*76441babSDarkWyrm //	Author(s):		unknown
24*76441babSDarkWyrm //
25*76441babSDarkWyrm //	Description:	Queue for holding BMessages
26*76441babSDarkWyrm //
27*76441babSDarkWyrm //------------------------------------------------------------------------------
2852a38012Sejakowatz 
2930fd5147Shaydentech #include <MessageQueue.h>
3030fd5147Shaydentech #include <Autolock.h>
3130fd5147Shaydentech #include <Message.h>
3252a38012Sejakowatz 
3352a38012Sejakowatz #ifdef USE_OPENBEOS_NAMESPACE
3452a38012Sejakowatz namespace OpenBeOS {
3552a38012Sejakowatz #endif
3652a38012Sejakowatz 
3752a38012Sejakowatz 
3852a38012Sejakowatz /*
3952a38012Sejakowatz  *  Method: BMessageQueue::BMessageQueue()
4052a38012Sejakowatz  *   Descr: This method is the only constructor for a BMessageQueue.  Once the
4152a38012Sejakowatz  *          constructor completes, the BMessageQueue is created with no BMessages
4252a38012Sejakowatz  *          in it.
4352a38012Sejakowatz  *
4452a38012Sejakowatz  */
4552a38012Sejakowatz BMessageQueue::BMessageQueue() :
4652a38012Sejakowatz 	fTheQueue(NULL), fQueueTail(NULL), fMessageCount(0)
4752a38012Sejakowatz {
4852a38012Sejakowatz }
4952a38012Sejakowatz 
5052a38012Sejakowatz 
5152a38012Sejakowatz /*
5252a38012Sejakowatz  *  Method: BMessageQueue::~BMessageQueue()
5352a38012Sejakowatz  *   Descr: This is the desctructor for the BMessageQueue.  It iterates over
5452a38012Sejakowatz  *          any messages left on the queue and deletes them.
5552a38012Sejakowatz  *
5652a38012Sejakowatz  *		    The implementation is careful not to release the lock when the
5752a38012Sejakowatz  *          BMessageQueue is deconstructed.  If the lock is released, it is
5852a38012Sejakowatz  *          possible another thread will start an AddMessage() operation before
5952a38012Sejakowatz  *          the BLocker is deleted.  The safe thing to do is not to unlock the
6052a38012Sejakowatz  *          BLocker from the destructor once it is acquired. That way, any thread
6152a38012Sejakowatz  *          waiting to do a AddMessage() will fail to acquire the lock since the
6252a38012Sejakowatz  *          BLocker will be deleted before they can acquire it.
6352a38012Sejakowatz  *
6452a38012Sejakowatz  */
6552a38012Sejakowatz BMessageQueue::~BMessageQueue()
6652a38012Sejakowatz {
6752a38012Sejakowatz 	if (fLocker.Lock()) {
6852a38012Sejakowatz 		BMessage *theMessage = fTheQueue;
6952a38012Sejakowatz 		while (theMessage != NULL) {
7052a38012Sejakowatz 			BMessage *messageToDelete = theMessage;
7152a38012Sejakowatz 			theMessage = theMessage->link;
7252a38012Sejakowatz 			delete messageToDelete;
7352a38012Sejakowatz 		}
7452a38012Sejakowatz 	}
7552a38012Sejakowatz }
7652a38012Sejakowatz 
7752a38012Sejakowatz 
7852a38012Sejakowatz /*
7952a38012Sejakowatz  *  Method: BMessageQueue::AddMessage()
8052a38012Sejakowatz  *   Descr: This method adds a BMessage to the queue.  It makes a couple of
8152a38012Sejakowatz  *          assumptions:
8252a38012Sejakowatz  *             - The BMessage was allocated on the heap with new.  Since the
8352a38012Sejakowatz  *               destructor delete's BMessages left on the queue, this must be
8452a38012Sejakowatz  *               true.  The same assumption is made with Be's implementation.
8552a38012Sejakowatz  *             - The BMessage is not already on this or any other BMessageQueue.
8652a38012Sejakowatz  *               If it is, the queue it is already on will be corrupted.  Be's
8752a38012Sejakowatz  *               implementation makes this assumption also and does corrupt
8852a38012Sejakowatz  *               BMessageQueues where this is violated.
8952a38012Sejakowatz  *
9052a38012Sejakowatz  */
9152a38012Sejakowatz void
9252a38012Sejakowatz BMessageQueue::AddMessage(BMessage *message)
9352a38012Sejakowatz {
9452a38012Sejakowatz 	if (message == NULL) {
9552a38012Sejakowatz 		return;
9652a38012Sejakowatz 	}
9752a38012Sejakowatz 
9852a38012Sejakowatz 	// The Be implementation does not seem to check that the lock acquisition
9952a38012Sejakowatz 	// was successful.  This will specifically cause problems when the
10052a38012Sejakowatz 	// message queue is deleted.  On delete, any thread waiting for the lock
10152a38012Sejakowatz 	// will be notified that the lock failed.  Be's implementation, because
10252a38012Sejakowatz 	// they do not check proceeds with the operation, potentially corrupting
10352a38012Sejakowatz 	// memory.  This implementation is different, but I can't imagine that
10452a38012Sejakowatz 	// Be's implementation is worth emulating.
10552a38012Sejakowatz 	//
10652a38012Sejakowatz 	BAutolock theAutoLocker(fLocker);
10752a38012Sejakowatz 
10852a38012Sejakowatz 	if (theAutoLocker.IsLocked()) {
10952a38012Sejakowatz 
11052a38012Sejakowatz 		// The message passed in will be the last message on the queue so its
11152a38012Sejakowatz 		// link member should be set to null.
11252a38012Sejakowatz 		message->link = NULL;
11352a38012Sejakowatz 
11452a38012Sejakowatz 		// We now have one more BMessage on the queue.
11552a38012Sejakowatz 		fMessageCount++;
11652a38012Sejakowatz 
11752a38012Sejakowatz 		// If there are no BMessages on the queue.
11852a38012Sejakowatz 		if (fQueueTail == NULL) {
11952a38012Sejakowatz 			// Then this message is both the start and the end of the queue.
12052a38012Sejakowatz 			fTheQueue = message;
12152a38012Sejakowatz 			fQueueTail = message;
12252a38012Sejakowatz 		} else {
12352a38012Sejakowatz 			// If there are already messages on the queue, then the put this
12452a38012Sejakowatz 			// BMessage at the end.  The last BMessage prior to this AddMessage()
12552a38012Sejakowatz 			// is fQueueTail.  The BMessage at fQueueTail needs to point to the
12652a38012Sejakowatz 			// new last message, the one being added.
12752a38012Sejakowatz 			fQueueTail->link = message;
12852a38012Sejakowatz 
12952a38012Sejakowatz 			// Now update the fQueueTail to point to this new last message.
13052a38012Sejakowatz 			fQueueTail = message;
13152a38012Sejakowatz 		}
13252a38012Sejakowatz 	}
13352a38012Sejakowatz }
13452a38012Sejakowatz 
13552a38012Sejakowatz 
13652a38012Sejakowatz /*
13752a38012Sejakowatz  *  Method: BMessageQueue::RemoveMessage()
13852a38012Sejakowatz  *   Descr: This method searches the queue for a particular BMessage.  If
13952a38012Sejakowatz  *          it is found, it is removed from the queue.
14052a38012Sejakowatz  *
14152a38012Sejakowatz  */
14252a38012Sejakowatz void
14352a38012Sejakowatz BMessageQueue::RemoveMessage(BMessage *message)
14452a38012Sejakowatz {
14552a38012Sejakowatz 	if (message == NULL) {
14652a38012Sejakowatz 		return;
14752a38012Sejakowatz 	}
14852a38012Sejakowatz 
14952a38012Sejakowatz 	BAutolock theAutoLocker(fLocker);
15052a38012Sejakowatz 
15152a38012Sejakowatz 	// The Be implementation does not seem to check that the lock acquisition
15252a38012Sejakowatz 	// was successful.  This will specifically cause problems when the
15352a38012Sejakowatz 	// message queue is deleted.  On delete, any thread waiting for the lock
15452a38012Sejakowatz 	// will be notified that the lock failed.  Be's implementation, because
15552a38012Sejakowatz 	// they do not check proceeds with the operation, potentially corrupting
15652a38012Sejakowatz 	// memory.  This implementation is different, but I can't imagine that
15752a38012Sejakowatz 	// Be's implementation is worth emulating.
15852a38012Sejakowatz 	//
15952a38012Sejakowatz 	if (theAutoLocker.IsLocked()) {
16052a38012Sejakowatz 
16152a38012Sejakowatz 		// If the message to be removed is at the front of the queue.
16252a38012Sejakowatz 		if (fTheQueue == message) {
16352a38012Sejakowatz 			// We need to special case the handling of removing the first element.
16452a38012Sejakowatz 			// First, the new front element will be the next one.
16552a38012Sejakowatz 			fTheQueue = fTheQueue->link;
16652a38012Sejakowatz 
16752a38012Sejakowatz 			// Must decrement the count of elements since the front one is being
16852a38012Sejakowatz 			// removed.
16952a38012Sejakowatz 			fMessageCount--;
17052a38012Sejakowatz 
17152a38012Sejakowatz 			// If the new front element is NULL, then that means that the queue
17252a38012Sejakowatz 			// is now empty.  That means that fQueueTail must be set to NULL.
17352a38012Sejakowatz 			if (fTheQueue == NULL) {
17452a38012Sejakowatz 				fQueueTail = NULL;
17552a38012Sejakowatz 			}
17652a38012Sejakowatz 
17752a38012Sejakowatz 			// We have found the message and removed it in this case.  We can
17852a38012Sejakowatz 			// bail out now.  The autolocker will take care of releasing the
17952a38012Sejakowatz 			// lock for us.
18052a38012Sejakowatz 			return;
18152a38012Sejakowatz 		}
18252a38012Sejakowatz 
18352a38012Sejakowatz 		// The message to remove is not the first one, so we need to scan the
18452a38012Sejakowatz 		// queue.  Get a message iterator and set it to the first element.
18552a38012Sejakowatz 		BMessage *messageIter = fTheQueue;
18652a38012Sejakowatz 
18752a38012Sejakowatz 		// While we are not at the end of the list.
18852a38012Sejakowatz 		while (messageIter != NULL) {
18952a38012Sejakowatz 			// If the next message after this (ie second, then third etc) is
19052a38012Sejakowatz 			// the one we are looking for.
19152a38012Sejakowatz 			if (messageIter->link == message) {
19252a38012Sejakowatz 				// At this point, this is what we have:
19352a38012Sejakowatz 				//    messageIter - the BMessage in the queue just before the
19452a38012Sejakowatz 				//                  match
19552a38012Sejakowatz 				//    messageIter->link - the BMessage which matches message
19652a38012Sejakowatz 				//    message - the same as messageIter->link
19752a38012Sejakowatz 				//    message->link - the element after the match
19852a38012Sejakowatz 				//
19952a38012Sejakowatz 				// The next step is to link the BMessage just before the match
20052a38012Sejakowatz 				// to the one just after the match.  This removes the match from
20152a38012Sejakowatz 				// the queue.
20252a38012Sejakowatz 				messageIter->link = message->link;
20352a38012Sejakowatz 
20452a38012Sejakowatz 				// One less element on the queue.
20552a38012Sejakowatz 				fMessageCount--;
20652a38012Sejakowatz 
20752a38012Sejakowatz 				// If there is no BMessage after the match is the
20852a38012Sejakowatz 				if (message->link == NULL) {
20952a38012Sejakowatz 					// That means that we just removed the last element from the
21052a38012Sejakowatz 					// queue.  The new last element then must be messageIter.
21152a38012Sejakowatz 					fQueueTail = messageIter;
21252a38012Sejakowatz 				}
21352a38012Sejakowatz 
21452a38012Sejakowatz 				// We can return now because we have a match and removed it.
21552a38012Sejakowatz 				return;
21652a38012Sejakowatz 			}
21752a38012Sejakowatz 
21852a38012Sejakowatz 			// No match yet, go to the next element in the list.
21952a38012Sejakowatz 			messageIter = messageIter->link;
22052a38012Sejakowatz 		}
22152a38012Sejakowatz 	}
22252a38012Sejakowatz }
22352a38012Sejakowatz 
22452a38012Sejakowatz 
22552a38012Sejakowatz /*
22652a38012Sejakowatz  *  Method: BMessageQueue::CountMessages()
22752a38012Sejakowatz  *   Descr: This method just returns the number of BMessages on the queue.
22852a38012Sejakowatz  */
22952a38012Sejakowatz int32
23052a38012Sejakowatz BMessageQueue::CountMessages(void) const
23152a38012Sejakowatz {
23252a38012Sejakowatz     return fMessageCount;
23352a38012Sejakowatz }
23452a38012Sejakowatz 
23552a38012Sejakowatz 
23652a38012Sejakowatz /*
23752a38012Sejakowatz  *  Method: BMessageQueue::IsEmpty()
23852a38012Sejakowatz  *   Descr: This method just returns true if there are no BMessages on the queue.
23952a38012Sejakowatz  */
24052a38012Sejakowatz bool
24152a38012Sejakowatz BMessageQueue::IsEmpty(void) const
24252a38012Sejakowatz {
24352a38012Sejakowatz     return (fMessageCount == 0);
24452a38012Sejakowatz }
24552a38012Sejakowatz 
24652a38012Sejakowatz 
24752a38012Sejakowatz /*
24852a38012Sejakowatz  *  Method: BMessageQueue::FindMessage()
24952a38012Sejakowatz  *   Descr: This method searches the queue for the index'th BMessage.  The first
25052a38012Sejakowatz  *          BMessage is at index 0, the second at index 1 etc.  The BMessage
25152a38012Sejakowatz  *          is returned if it is found.  If no BMessage exists at that index
25252a38012Sejakowatz  *          (ie the queue is not that long or the index is invalid) NULL is
25352a38012Sejakowatz  *          returned.
25452a38012Sejakowatz  *
25552a38012Sejakowatz  *          This method does not lock the BMessageQueue so there is risk that
25652a38012Sejakowatz  *          the queue could change in the course of the search.  Be's
25752a38012Sejakowatz  *          implementation must do the same, unless they do some funky casting.
25852a38012Sejakowatz  *          The method is declared const which means it cannot modify the data
25952a38012Sejakowatz  *          members.  Because it cannot modify the data members, it cannot
26052a38012Sejakowatz  *          acquire a lock.  So unless they are casting away the const-ness
26152a38012Sejakowatz  *          of the this pointer, this member in Be's implementation does no
26252a38012Sejakowatz  *          locking either.
26352a38012Sejakowatz  */
26452a38012Sejakowatz BMessage *
26552a38012Sejakowatz BMessageQueue::FindMessage(int32 index) const
26652a38012Sejakowatz {
26752a38012Sejakowatz 	// If the index is negative or larger than the number of messages on the
26852a38012Sejakowatz 	// queue.
26952a38012Sejakowatz 	if ((index < 0) || (index >= fMessageCount)) {
27052a38012Sejakowatz 		// No match is possible, bail out now.
27152a38012Sejakowatz 		return NULL;
27252a38012Sejakowatz 	}
27352a38012Sejakowatz 
27452a38012Sejakowatz 	// Get a message iterator and initialize it to the start of the queue.
27552a38012Sejakowatz 	BMessage *messageIter = fTheQueue;
27652a38012Sejakowatz 
27752a38012Sejakowatz 	// While this is not the end of the queue.
27852a38012Sejakowatz 	while (messageIter != NULL) {
27952a38012Sejakowatz 		// If the index reaches zero, then we have found a match.
28052a38012Sejakowatz 		if (index == 0) {
28152a38012Sejakowatz 			// Because this is a match, break out of the while loop so we can
28252a38012Sejakowatz 			// return the message pointed to messageIter.
28352a38012Sejakowatz 			break;
28452a38012Sejakowatz 		}
28552a38012Sejakowatz 
28652a38012Sejakowatz 		// No match yet, decrement the index.  We will have a match once index
28752a38012Sejakowatz 		// reaches zero.
28852a38012Sejakowatz 		index--;
28952a38012Sejakowatz 		// Increment the messageIter to the next BMessage on the queue.
29052a38012Sejakowatz 		messageIter = messageIter->link;
29152a38012Sejakowatz 	}
29252a38012Sejakowatz 
29352a38012Sejakowatz 	// If no match was found, messageIter will be NULL since that is the only
29452a38012Sejakowatz 	// way out of the loop.  If a match was found, the messageIter will point
29552a38012Sejakowatz 	// to that match.
29652a38012Sejakowatz     return messageIter;
29752a38012Sejakowatz }
29852a38012Sejakowatz 
29952a38012Sejakowatz 
30052a38012Sejakowatz /*
30152a38012Sejakowatz  *  Method: BMessageQueue::FindMessage()
30252a38012Sejakowatz  *   Descr: This method searches the queue for the index'th BMessage that has a
30352a38012Sejakowatz  *          particular what code.  The first BMessage with that what value is at
30452a38012Sejakowatz  *          index 0, the second at index 1 etc.  The BMessage is returned if it
30552a38012Sejakowatz  *          is found.  If no matching BMessage exists at that index NULL is
30652a38012Sejakowatz  *          returned.
30752a38012Sejakowatz  *
30852a38012Sejakowatz  *          This method does not lock the BMessageQueue so there is risk that
30952a38012Sejakowatz  *          the queue could change in the course of the search.  Be's
31052a38012Sejakowatz  *          implementation must do the same, unless they do some funky casting.
31152a38012Sejakowatz  *          The method is declared const which means it cannot modify the data
31252a38012Sejakowatz  *          members.  Because it cannot modify the data members, it cannot
31352a38012Sejakowatz  *          acquire a lock.  So unless they are casting away the const-ness
31452a38012Sejakowatz  *          of the this pointer, this member in Be's implementation does no
31552a38012Sejakowatz  *          locking either.
31652a38012Sejakowatz  */
31752a38012Sejakowatz BMessage *
31852a38012Sejakowatz BMessageQueue::FindMessage(uint32 what,
31952a38012Sejakowatz                            int32 index) const
32052a38012Sejakowatz {
32152a38012Sejakowatz 	// If the index is negative or larger than the number of messages on the
32252a38012Sejakowatz 	// queue.
32352a38012Sejakowatz 	if ((index < 0) || (index >= fMessageCount)) {
32452a38012Sejakowatz 		// No match is possible, bail out now.
32552a38012Sejakowatz 		return NULL;
32652a38012Sejakowatz 	}
32752a38012Sejakowatz 
32852a38012Sejakowatz 	// Get a message iterator and initialize it to the start of the queue.
32952a38012Sejakowatz 	BMessage *messageIter = fTheQueue;
33052a38012Sejakowatz 
33152a38012Sejakowatz 	// While this is not the end of the queue.
33252a38012Sejakowatz 	while (messageIter != NULL) {
33352a38012Sejakowatz 		// If the messageIter points to a BMessage with the what code we are
33452a38012Sejakowatz 		// looking for.
33552a38012Sejakowatz 		if (messageIter->what == what) {
33652a38012Sejakowatz 			// If the index reaches zero, then we have found a match.
33752a38012Sejakowatz 			if (index == 0) {
33852a38012Sejakowatz 				// Because this is a match, break out of the while loop so we can
33952a38012Sejakowatz 				// return the message pointed to messageIter.
34052a38012Sejakowatz 				break;
34152a38012Sejakowatz 			}
34252a38012Sejakowatz 			// No match yet, decrement the index.  We will have a match once index
34352a38012Sejakowatz 			// reaches zero.
34452a38012Sejakowatz 			index--;
34552a38012Sejakowatz 		}
34652a38012Sejakowatz 		// Increment the messageIter to the next BMessage on the queue.
34752a38012Sejakowatz 		messageIter = messageIter->link;
34852a38012Sejakowatz 	}
34952a38012Sejakowatz 
35052a38012Sejakowatz 	// If no match was found, messageIter will be NULL since that is the only
35152a38012Sejakowatz 	// way out of the loop.  If a match was found, the messageIter will point
35252a38012Sejakowatz 	// to that match.
35352a38012Sejakowatz     return messageIter;
35452a38012Sejakowatz }
35552a38012Sejakowatz 
35652a38012Sejakowatz 
35752a38012Sejakowatz /*
35852a38012Sejakowatz  *  Method: BMessageQueue::Lock()
35952a38012Sejakowatz  *   Descr: This member just locks the BMessageQueue so no other thread can acquire
36052a38012Sejakowatz  *          the lock nor make changes to the queue through members like
36152a38012Sejakowatz  *          AddMessage(), RemoveMessage(), NextMessage() or ~BMessageQueue().
36252a38012Sejakowatz  */
36352a38012Sejakowatz bool
36452a38012Sejakowatz BMessageQueue::Lock(void)
36552a38012Sejakowatz {
36652a38012Sejakowatz     return fLocker.Lock();
36752a38012Sejakowatz }
36852a38012Sejakowatz 
36952a38012Sejakowatz 
37052a38012Sejakowatz /*
37152a38012Sejakowatz  *  Method: BMessageQueue::Unlock()
37252a38012Sejakowatz  *   Descr: This member releases the lock which was acquired by Lock().
37352a38012Sejakowatz  */
37452a38012Sejakowatz void
37552a38012Sejakowatz BMessageQueue::Unlock(void)
37652a38012Sejakowatz {
37752a38012Sejakowatz 	fLocker.Unlock();
37852a38012Sejakowatz }
37952a38012Sejakowatz 
38052a38012Sejakowatz 
38152a38012Sejakowatz /*
38252a38012Sejakowatz  *  Method: BMessageQueue::IsLocked()
38352a38012Sejakowatz  *   Descr: This member returns whether or not the queue is locked
38452a38012Sejakowatz  */
38552a38012Sejakowatz bool
38652a38012Sejakowatz BMessageQueue::IsLocked(void)
38752a38012Sejakowatz {
38852a38012Sejakowatz 	return fLocker.IsLocked();
38952a38012Sejakowatz }
39052a38012Sejakowatz 
39152a38012Sejakowatz 
39252a38012Sejakowatz /*
39352a38012Sejakowatz  *  Method: BMessageQueue::NextMessage()
39452a38012Sejakowatz  *   Descr: This member removes the first BMessage on the queue and returns
39552a38012Sejakowatz  *          it to the caller.  If the queue is empty, NULL is returned.
39652a38012Sejakowatz  */
39752a38012Sejakowatz BMessage *
39852a38012Sejakowatz BMessageQueue::NextMessage(void)
39952a38012Sejakowatz {
40052a38012Sejakowatz 	// By default, we will assume that no BMessage is on the queue.
40152a38012Sejakowatz 	BMessage *result = NULL;
40252a38012Sejakowatz 	BAutolock theAutoLocker(fLocker);
40352a38012Sejakowatz 
40452a38012Sejakowatz 	// The Be implementation does not seem to check that the lock acquisition
40552a38012Sejakowatz 	// was successful.  This will specifically cause problems when the
40652a38012Sejakowatz 	// message queue is deleted.  On delete, any thread waiting for the lock
40752a38012Sejakowatz 	// will be notified that the lock failed.  Be's implementation, because
40852a38012Sejakowatz 	// they do not check proceeds with the operation, potentially corrupting
40952a38012Sejakowatz 	// memory.  This implementation is different, but I can't imagine that
41052a38012Sejakowatz 	// Be's implementation is worth emulating.
41152a38012Sejakowatz 	//
41252a38012Sejakowatz 	if (theAutoLocker.IsLocked()) {
41352a38012Sejakowatz 		// Store the first BMessage in the queue in result.
41452a38012Sejakowatz 		result = fTheQueue;
41552a38012Sejakowatz 
41652a38012Sejakowatz 		// If the queue is not empty.
41752a38012Sejakowatz 		if (fTheQueue != NULL) {
41852a38012Sejakowatz 			// Decrement the message count since we are removing an element.
41952a38012Sejakowatz 			fMessageCount--;
42052a38012Sejakowatz 			// The new front of the list is moved forward thereby removing the
42152a38012Sejakowatz 			// first element from the queue.
42252a38012Sejakowatz 			fTheQueue = fTheQueue->link;
42352a38012Sejakowatz 			// If the queue is empty after removing the front element.
42452a38012Sejakowatz 			if (fTheQueue == NULL) {
42552a38012Sejakowatz 				// We need to set the tail of the queue to NULL since the queue
42652a38012Sejakowatz 				// is now empty.
42752a38012Sejakowatz 				fQueueTail = NULL;
42852a38012Sejakowatz 			}
42952a38012Sejakowatz 		}
43052a38012Sejakowatz 	}
43152a38012Sejakowatz     return result;
43252a38012Sejakowatz }
43352a38012Sejakowatz 
43452a38012Sejakowatz 
43552a38012Sejakowatz void
43652a38012Sejakowatz BMessageQueue::_ReservedMessageQueue1(void)
43752a38012Sejakowatz {
43852a38012Sejakowatz }
43952a38012Sejakowatz 
44052a38012Sejakowatz 
44152a38012Sejakowatz void
44252a38012Sejakowatz BMessageQueue::_ReservedMessageQueue2(void)
44352a38012Sejakowatz {
44452a38012Sejakowatz }
44552a38012Sejakowatz 
44652a38012Sejakowatz 
44752a38012Sejakowatz void
44852a38012Sejakowatz BMessageQueue::_ReservedMessageQueue3(void)
44952a38012Sejakowatz {
45052a38012Sejakowatz }
45152a38012Sejakowatz 
45252a38012Sejakowatz #ifdef USE_OPENBEOS_NAMESPACE
45352a38012Sejakowatz }
45452a38012Sejakowatz #endif
455