Finally figured out why the first assert in IsMessageWaiting5() always

worked under R5 but only sometimes for OBOS.  Answer: the OBOS
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 had
enough time to get to the fetch (thereby emptying the queue), making the
assert pretty useless.  Given that it was originally there as a probing
test (rather than as an integral part of the unit test), there is no real
need for it anyway, so it is no longer used.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@250 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
ejakowatz 2002-07-16 07:51:51 +00:00
parent c4786ea6c4
commit e3684651de
2 changed files with 67 additions and 28 deletions

View File

@ -283,11 +283,14 @@ bool BLooper::IsMessageWaiting() const
/**
@note: What we're doing here differs slightly from the R5 implementation.
It appears that they probably return count != 0, which gives a false
true (!) result when port_buffer_size_etc() would block -- which
indicates that the port's buffer is empty, so we should return false.
Since we don't actually care about what the error is, we just return
count > 0.
It appears that they probably return count != 0, which gives an
incorrect true result when port_buffer_size_etc() would block --
which indicates that the port's buffer is empty, so we should return
false. Since we don't actually care about what the error is, we
just return count > 0. This has some interesting consequences in
that we will correctly return 'false' if the port is empty
(B_WOULD_BLOCK), whereas R5 will return true. We call that a bug
where I come from. ;)
*/
int32 count;
do
@ -779,7 +782,7 @@ status_t BLooper::_PostMessage(BMessage* msg, BHandler* handler,
if (!err)
{
err = Messenger.SendMessage(msg, reply_to);
err = Messenger.SendMessage(msg, reply_to, 0);
}
return err;
@ -1062,7 +1065,8 @@ DBG(OUT("BLooper::ConvertToMessage()\n"));
if (raw != NULL)
{
if (bmsg->Unflatten((const char*)raw) != B_OK) {
if (bmsg->Unflatten((const char*)raw) != B_OK)
{
DBG(OUT("BLooper::ConvertToMessage(): unflattening message failed\n"));
delete bmsg;
bmsg = NULL;
@ -1085,6 +1089,7 @@ DBG(OUT("BLooper::task_looper()\n"));
while (!fTerminating)
{
DBG(OUT("LOOPER: outer loop\n"));
// TODO: timeout determination algo
// Read from message port (how do we determine what the timeout is?)
DBG(OUT("LOOPER: MessageFromPort()...\n"));
BMessage* msg = MessageFromPort();
@ -1108,25 +1113,31 @@ DBG(OUT("LOOPER: got no message\n"));
// We use zero as our timeout since we know there is stuff there
msg = MessageFromPort(0);
// Add messages to queue
fQueue->AddMessage(msg);
if (msg)
{
fQueue->AddMessage(msg);
}
}
// loop: As long as there are messages in the queue and the port is
// empty... and we are not terminating, of course.
bool dispatchNextMessage = true;
while (!fTerminating && dispatchNextMessage) {
while (!fTerminating && dispatchNextMessage)
{
DBG(OUT("LOOPER: inner loop\n"));
// Lock the looper
Lock();
// Get next message from queue (assign to fLastMessage)
fLastMessage = fQueue->NextMessage();
if (!fLastMessage) {
// Lock the looper
Lock();
if (!fLastMessage)
{
// No more messages: Unlock the looper and terminate the
// dispatch loop.
dispatchNextMessage = false;
Unlock();
} else {
}
else
{
DBG(OUT("LOOPER: fLastMessage: 0x%lx: %.4s\n", fLastMessage->what,
(char*)&fLastMessage->what));
DBG(fLastMessage->PrintToStream());
@ -1186,20 +1197,23 @@ DBG(OUT("LOOPER: top_level_filter(): %p\n", handler));
DispatchMessage(fLastMessage, handler);
}
}
}
// Unlock the looper
Unlock();
// Unlock the looper
Unlock();
// Delete the current message (fLastMessage)
// Delete the current message (fLastMessage)
if (fLastMessage)
{
delete fLastMessage;
fLastMessage = NULL;
}
// Are any messages on the port?
if (port_count(fMsgPort) > 0)
{
// Do outer loop
dispatchNextMessage = false;
}
// Are any messages on the port?
if (port_count(fMsgPort) > 0)
{
// Do outer loop
dispatchNextMessage = false;
}
}
}

View File

@ -54,7 +54,9 @@ void TIsMessageWaitingTest::IsMessageWaiting3()
#else
#if 0
// Testing to figure out why we get false positives from the R5
// implementation of BLooper::IsMessageWaiting().
// implementation of BLooper::IsMessageWaiting(). Basically, it tests for
// port_buffer_size_etc() != 0 -- which means that return values like
// B_WOULD_BLOCK make the function return true, which is just not correct.
CPPUNIT_ASSERT(Looper.IsLocked());
CPPUNIT_ASSERT(Looper.MessageQueue()->IsEmpty());
@ -89,10 +91,18 @@ void TIsMessageWaitingTest::IsMessageWaiting5()
// Prevent a port read
Looper->Lock();
Looper->PostMessage('1234');
CPPUNIT_ASSERT(Looper->MessageQueue()->IsEmpty());
// CPPUNIT_ASSERT(Looper->MessageQueue()->IsEmpty());
CPPUNIT_ASSERT(Looper->IsMessageWaiting());
int32 count;
// Tests to help figure out why the first assert above always worked under R5
// but only sometimes for OBOS. Answer: the OBOS 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 had enough time to get to the fetch
// (thereby emptying the queue), so the assert is no longer used.
#if 0
ssize_t count;
do
{
count = port_buffer_size_etc(_get_looper_port_(Looper), B_TIMEOUT, 0);
@ -100,10 +110,25 @@ void TIsMessageWaitingTest::IsMessageWaiting5()
cout << endl << "port_buffer_size_etc: ";
if (count < 0)
{
cout << strerror(count);
}
else
cout << count;
{
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()