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 */ 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 */ 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 */ 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 */ 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 */ 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 //------------------------------------------------------------------------------ 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