1//------------------------------------------------------------------------------
2//	IsMessageWaitingTest.cpp
3//
4//------------------------------------------------------------------------------
5
6// Standard Includes -----------------------------------------------------------
7#include <iostream>
8#include <posix/string.h>
9
10// System Includes -------------------------------------------------------------
11#include <Looper.h>
12#include <Message.h>
13#include <MessageQueue.h>
14
15// Project Includes ------------------------------------------------------------
16
17// Local Includes --------------------------------------------------------------
18#include "IsMessageWaitingTest.h"
19
20// Local Defines ---------------------------------------------------------------
21
22// Globals ---------------------------------------------------------------------
23port_id _get_looper_port_(const BLooper* looper);
24
25//------------------------------------------------------------------------------
26/**
27	IsMessageWaiting()
28	@case		looper is unlocked and queue is empty
29	@results	IsMessageWaiting() returns false
30 */
31void TIsMessageWaitingTest::IsMessageWaiting1()
32{
33	DEBUGGER_ESCAPE;
34
35	BLooper Looper;
36	Looper.Unlock();
37	CPPUNIT_ASSERT(!Looper.IsMessageWaiting());
38}
39//------------------------------------------------------------------------------
40/**
41	IsMessageWaiting()
42	@case		looper is unlocked and queue is filled
43	@results	IsMessageWaiting() returns false
44 */
45void TIsMessageWaitingTest::IsMessageWaiting2()
46{
47	DEBUGGER_ESCAPE;
48
49	BLooper Looper;
50	Looper.Unlock();
51	Looper.PostMessage('1234');
52	CPPUNIT_ASSERT(!Looper.IsMessageWaiting());
53}
54//------------------------------------------------------------------------------
55/**
56	IsMessageWaiting()
57	@case		looper is locked and queue is empty
58	@results	IsMessageWaiting() returns false
59	@note		R5 will return true in this test.  The extra testing below
60				indicates that the R5 version probably returns != 0 from
61				port_buffer_size_etc(), resulting in an incorrect true in cases
62				where the operation would block.
63 */
64void TIsMessageWaitingTest::IsMessageWaiting3()
65{
66	BLooper Looper;
67	Looper.Lock();
68#ifndef TEST_R5
69	CPPUNIT_ASSERT(!Looper.IsMessageWaiting());
70#else
71#if 0
72	// Testing to figure out why we get false positives from the R5
73	// implementation of BLooper::IsMessageWaiting().  Basically, it tests for
74	// port_buffer_size_etc() != 0 -- which means that return values like
75	// B_WOULD_BLOCK make the function return true, which is just not correct.
76	CPPUNIT_ASSERT(Looper.IsLocked());
77	CPPUNIT_ASSERT(Looper.MessageQueue()->IsEmpty());
78
79	int32 count;
80	do
81	{
82		count = port_buffer_size_etc(_get_looper_port_(&Looper), B_TIMEOUT, 0);
83	} while (count == B_INTERRUPTED);
84
85	CPPUNIT_ASSERT(count < 0);
86	cout << endl << "port_buffer_size_etc: " << strerror(count) << endl;
87#endif
88	CPPUNIT_ASSERT(Looper.IsMessageWaiting());
89#endif
90}
91//------------------------------------------------------------------------------
92/**
93	IsMessageWaiting()
94	@case		looper is locked and queue is filled
95	@results	IsMessageWaiting() returns true.
96 */
97void TIsMessageWaitingTest::IsMessageWaiting4()
98{
99	BLooper Looper;
100	Looper.Lock();
101	Looper.PostMessage('1234');
102	CPPUNIT_ASSERT(Looper.IsMessageWaiting());
103}
104//------------------------------------------------------------------------------
105/**
106	IsMessageWaiting()
107	@case		looper is locked, message is posted, queue is empty
108	@results	IsMessageWaiting() returns true.
109	@note		The first assert always worked under R5 but only sometimes for
110				OBOS.  Answer: the OBOS implementation of BLooper was attempting
111				to lock itself prior to fetching the message from the queue.  I
112				moved the lock attempt after the fetch and it worked the same.
113				I realized that if the system was loaded heavily enough, the
114				assert might still fail simply because the looper would not have
115				had enough time to get to the fetch (thereby emptying the queue),
116				so the assert is no longer used.  If we do manage to call
117				IsMessageWaiting() before the fetch happens (which does happen
118				every once in a while), we still get a true result because the
119				port buffer is checked.  Later: it's finally dawned on me that
120				if the system is loaded *lightly* enough, the message will not
121				only get fetched, but popped off the queue as well.  Since R5
122				returns the bogus true, the second assert works even when the
123				message has been de-queued.  OBOS, of course, will (correctly)
124				fail the assert in that situation.  Unfortunately, that renders
125				this test completely unreliable.  It is pulled until a fully
126				reliable test can be devised.
127 */
128void TIsMessageWaitingTest::IsMessageWaiting5()
129{
130	BLooper* Looper = new BLooper(__PRETTY_FUNCTION__);
131	Looper->Run();
132
133	// Prevent a port read
134	Looper->Lock();
135	Looper->PostMessage('1234');
136//	CPPUNIT_ASSERT(Looper->MessageQueue()->IsEmpty());
137	CPPUNIT_ASSERT(Looper->IsMessageWaiting());
138
139#if 0
140	ssize_t count;
141	do
142	{
143		count = port_buffer_size_etc(_get_looper_port_(Looper), B_TIMEOUT, 0);
144	} while (count == B_INTERRUPTED);
145
146	cout << endl << "port_buffer_size_etc: ";
147	if (count < 0)
148	{
149		cout << strerror(count);
150	}
151	else
152	{
153		cout << count << endl;
154		char* buffer = new char[count];
155		int32 code;
156		read_port(_get_looper_port_(Looper), &code, (void*)buffer, count);
157		cout << "code: " << code << endl;
158		cout << "buffer: ";
159		for (int32 i = 0; i < count; ++i)
160		{
161			cout << buffer[i];
162		}
163		cout << endl;
164	}
165	cout << endl;
166#endif
167}
168//------------------------------------------------------------------------------
169Test* TIsMessageWaitingTest::Suite()
170{
171	TestSuite* suite = new TestSuite("BLooper::IsMessageWaiting()");
172
173	ADD_TEST4(BLooper, suite, TIsMessageWaitingTest, IsMessageWaiting1);
174	ADD_TEST4(BLooper, suite, TIsMessageWaitingTest, IsMessageWaiting2);
175	ADD_TEST4(BLooper, suite, TIsMessageWaitingTest, IsMessageWaiting3);
176	ADD_TEST4(BLooper, suite, TIsMessageWaitingTest, IsMessageWaiting4);
177
178	// See note for test
179//	ADD_TEST4(BLooper, suite, TIsMessageWaitingTest, IsMessageWaiting5);
180
181	return suite;
182}
183//------------------------------------------------------------------------------
184
185/*
186 * $Log $
187 *
188 * $Id  $
189 *
190 */
191
192
193