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 ---------------------------------------------------------------------
23 port_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 */
IsMessageWaiting1()31 void 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 */
IsMessageWaiting2()45 void 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 */
IsMessageWaiting3()64 void 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 */
IsMessageWaiting4()97 void 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 Haiku. Answer: the Haiku 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. Haiku, 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 */
IsMessageWaiting5()128 void 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 //------------------------------------------------------------------------------
Suite()169 Test* 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