#include <iostream>
#include <posix/string.h>
#include <Looper.h>
#include <Message.h>
#include <MessageQueue.h>
#include "IsMessageWaitingTest.h"
port_id _get_looper_port_(const BLooper* looper);
IsMessageWaiting()
@case looper is unlocked and queue is empty
@results IsMessageWaiting() returns false
*/
void TIsMessageWaitingTest::IsMessageWaiting1()
{
DEBUGGER_ESCAPE;
BLooper Looper;
Looper.Unlock();
CPPUNIT_ASSERT(!Looper.IsMessageWaiting());
}
IsMessageWaiting()
@case looper is unlocked and queue is filled
@results IsMessageWaiting() returns false
*/
void TIsMessageWaitingTest::IsMessageWaiting2()
{
DEBUGGER_ESCAPE;
BLooper Looper;
Looper.Unlock();
Looper.PostMessage('1234');
CPPUNIT_ASSERT(!Looper.IsMessageWaiting());
}
IsMessageWaiting()
@case looper is locked and queue is empty
@results IsMessageWaiting() returns false
@note R5 will return true in this test. The extra testing below
indicates that the R5 version probably returns != 0 from
port_buffer_size_etc(), resulting in an incorrect true in cases
where the operation would block.
*/
void TIsMessageWaitingTest::IsMessageWaiting3()
{
BLooper Looper;
Looper.Lock();
#ifndef TEST_R5
CPPUNIT_ASSERT(!Looper.IsMessageWaiting());
#else
#if 0
CPPUNIT_ASSERT(Looper.IsLocked());
CPPUNIT_ASSERT(Looper.MessageQueue()->IsEmpty());
int32 count;
do
{
count = port_buffer_size_etc(_get_looper_port_(&Looper), B_TIMEOUT, 0);
} while (count == B_INTERRUPTED);
CPPUNIT_ASSERT(count < 0);
cout << endl << "port_buffer_size_etc: " << strerror(count) << endl;
#endif
CPPUNIT_ASSERT(Looper.IsMessageWaiting());
#endif
}
IsMessageWaiting()
@case looper is locked and queue is filled
@results IsMessageWaiting() returns true.
*/
void TIsMessageWaitingTest::IsMessageWaiting4()
{
BLooper Looper;
Looper.Lock();
Looper.PostMessage('1234');
CPPUNIT_ASSERT(Looper.IsMessageWaiting());
}
IsMessageWaiting()
@case looper is locked, message is posted, queue is empty
@results IsMessageWaiting() returns true.
@note The first assert always worked under R5 but only sometimes for
Haiku. Answer: the Haiku implementation of BLooper was attempting
to lock itself prior to fetching the message from the queue. I
moved the lock attempt after the fetch and it worked the same.
I realized that if the system was loaded heavily enough, the
assert might still fail simply because the looper would not have
had enough time to get to the fetch (thereby emptying the queue),
so the assert is no longer used. If we do manage to call
IsMessageWaiting() before the fetch happens (which does happen
every once in a while), we still get a true result because the
port buffer is checked. Later: it's finally dawned on me that
if the system is loaded *lightly* enough, the message will not
only get fetched, but popped off the queue as well. Since R5
returns the bogus true, the second assert works even when the
message has been de-queued. Haiku, of course, will (correctly)
fail the assert in that situation. Unfortunately, that renders
this test completely unreliable. It is pulled until a fully
reliable test can be devised.
*/
void TIsMessageWaitingTest::IsMessageWaiting5()
{
BLooper* Looper = new BLooper(__PRETTY_FUNCTION__);
Looper->Run();
Looper->Lock();
Looper->PostMessage('1234');
CPPUNIT_ASSERT(Looper->IsMessageWaiting());
#if 0
ssize_t count;
do
{
count = port_buffer_size_etc(_get_looper_port_(Looper), B_TIMEOUT, 0);
} while (count == B_INTERRUPTED);
cout << endl << "port_buffer_size_etc: ";
if (count < 0)
{
cout << strerror(count);
}
else
{
cout << count << endl;
char* buffer = new char[count];
int32 code;
read_port(_get_looper_port_(Looper), &code, (void*)buffer, count);
cout << "code: " << code << endl;
cout << "buffer: ";
for (int32 i = 0; i < count; ++i)
{
cout << buffer[i];
}
cout << endl;
}
cout << endl;
#endif
}
Test* TIsMessageWaitingTest::Suite()
{
TestSuite* suite = new TestSuite("BLooper::IsMessageWaiting()");
ADD_TEST4(BLooper, suite, TIsMessageWaitingTest, IsMessageWaiting1);
ADD_TEST4(BLooper, suite, TIsMessageWaitingTest, IsMessageWaiting2);
ADD_TEST4(BLooper, suite, TIsMessageWaitingTest, IsMessageWaiting3);
ADD_TEST4(BLooper, suite, TIsMessageWaitingTest, IsMessageWaiting4);
return suite;
}
* $Log $
*
* $Id $
*
*/