#include <stdio.h>
#include <Autolock.h>
#include "MessageRunnerTestHelpers.h"
enum {
JITTER = 10000,
};
MessageRunnerTestHandler::MessageRunnerTestHandler()
: BHandler("message runner test handler"),
fReplyCount()
{
}
MessageRunnerTestHandler::~MessageRunnerTestHandler()
{
}
void
MessageRunnerTestHandler::MessageReceived(BMessage *message)
{
switch (message->what) {
case MSG_REPLY:
fReplyCount++;
break;
}
}
struct MessageRunnerTestLooper::MessageInfo {
bigtime_t time;
};
MessageRunnerTestLooper::MessageRunnerTestLooper()
: BLooper(),
fMessageInfos()
{
}
MessageRunnerTestLooper::~MessageRunnerTestLooper()
{
for (int32 i = 0; MessageInfo *info = MessageInfoAt(i); i++)
delete info;
}
void
MessageRunnerTestLooper::MessageReceived(BMessage *message)
{
switch (message->what) {
case MSG_RUNNER_MESSAGE:
{
MessageInfo *info = new MessageInfo;
info->time = system_time();
fMessageInfos.AddItem(info);
message->SendReply(MSG_REPLY);
break;
}
}
}
bool
MessageRunnerTestLooper::CheckMessages(bigtime_t startTime, bigtime_t interval,
int32 count)
{
return CheckMessages(0, startTime, interval, count);
}
bool
MessageRunnerTestLooper::CheckMessages(int32 skip, bigtime_t startTime,
bigtime_t interval, int32 count)
{
BAutolock _lock(this);
bool result = (fMessageInfos.CountItems() == count + skip);
if (!result) {
printf("message counts don't match: %ld vs. %ld\n", fMessageInfos.CountItems(),
count + skip);
}
for (int32 i = 0; result && i < count; i++) {
MessageInfo *info = MessageInfoAt(i + skip);
bigtime_t expectedTime = startTime + (i + 1) * interval;
result = (expectedTime - JITTER < info->time
&& info->time < expectedTime + JITTER);
if (!result)
printf("message out of time: %lld vs. %lld\n", info->time, expectedTime);
}
return result;
}
MessageRunnerTestLooper::MessageInfo*
MessageRunnerTestLooper::MessageInfoAt(int32 index) const
{
return static_cast<MessageInfo*>(fMessageInfos.ItemAt(index));
}
MessageRunnerTestApp::MessageRunnerTestApp(const char *signature)
: BApplication(signature),
fThread(-1),
fReplyCount(0),
fLooper(NULL),
fHandler(NULL)
{
fLooper = new MessageRunnerTestLooper;
fLooper->Run();
fHandler = new MessageRunnerTestHandler;
AddHandler(fHandler);
Unlock();
fThread = spawn_thread(_ThreadEntry, "message runner app thread",
B_NORMAL_PRIORITY, this);
resume_thread(fThread);
}
MessageRunnerTestApp::~MessageRunnerTestApp()
{
fLooper->Lock();
fLooper->Quit();
BMessage reply;
PostMessage(B_QUIT_REQUESTED);
int32 dummy;
wait_for_thread(fThread, &dummy);
Lock();
RemoveHandler(fHandler);
delete fHandler;
}
void
MessageRunnerTestApp::MessageReceived(BMessage *message)
{
switch (message->what) {
case MSG_REPLY:
fReplyCount++;
break;
}
}
bool
MessageRunnerTestApp::QuitRequested()
{
return true;
}
int32
MessageRunnerTestApp::_ThreadEntry(void *data)
{
MessageRunnerTestApp *app = static_cast<MessageRunnerTestApp*>(data);
app->Lock();
app->Run();
return 0;
}