1*dace24c6SIngo Weinhold // MessageRunnerTestHelpers.cpp
2*dace24c6SIngo Weinhold
3*dace24c6SIngo Weinhold #include <stdio.h>
4*dace24c6SIngo Weinhold
5*dace24c6SIngo Weinhold #include <Autolock.h>
6*dace24c6SIngo Weinhold
7*dace24c6SIngo Weinhold #include "MessageRunnerTestHelpers.h"
8*dace24c6SIngo Weinhold
9*dace24c6SIngo Weinhold enum {
10*dace24c6SIngo Weinhold JITTER = 10000,
11*dace24c6SIngo Weinhold };
12*dace24c6SIngo Weinhold
13*dace24c6SIngo Weinhold // constructor
MessageRunnerTestHandler()14*dace24c6SIngo Weinhold MessageRunnerTestHandler::MessageRunnerTestHandler()
15*dace24c6SIngo Weinhold : BHandler("message runner test handler"),
16*dace24c6SIngo Weinhold fReplyCount()
17*dace24c6SIngo Weinhold {
18*dace24c6SIngo Weinhold }
19*dace24c6SIngo Weinhold
20*dace24c6SIngo Weinhold // destructor
~MessageRunnerTestHandler()21*dace24c6SIngo Weinhold MessageRunnerTestHandler::~MessageRunnerTestHandler()
22*dace24c6SIngo Weinhold {
23*dace24c6SIngo Weinhold }
24*dace24c6SIngo Weinhold
25*dace24c6SIngo Weinhold // MessageReceived
26*dace24c6SIngo Weinhold void
MessageReceived(BMessage * message)27*dace24c6SIngo Weinhold MessageRunnerTestHandler::MessageReceived(BMessage *message)
28*dace24c6SIngo Weinhold {
29*dace24c6SIngo Weinhold switch (message->what) {
30*dace24c6SIngo Weinhold case MSG_REPLY:
31*dace24c6SIngo Weinhold fReplyCount++;
32*dace24c6SIngo Weinhold break;
33*dace24c6SIngo Weinhold }
34*dace24c6SIngo Weinhold }
35*dace24c6SIngo Weinhold
36*dace24c6SIngo Weinhold
37*dace24c6SIngo Weinhold ///////////////////////////
38*dace24c6SIngo Weinhold // MessageRunnerTestLooper
39*dace24c6SIngo Weinhold
40*dace24c6SIngo Weinhold struct MessageRunnerTestLooper::MessageInfo {
41*dace24c6SIngo Weinhold bigtime_t time;
42*dace24c6SIngo Weinhold };
43*dace24c6SIngo Weinhold
44*dace24c6SIngo Weinhold // constructor
MessageRunnerTestLooper()45*dace24c6SIngo Weinhold MessageRunnerTestLooper::MessageRunnerTestLooper()
46*dace24c6SIngo Weinhold : BLooper(),
47*dace24c6SIngo Weinhold fMessageInfos()
48*dace24c6SIngo Weinhold {
49*dace24c6SIngo Weinhold }
50*dace24c6SIngo Weinhold
51*dace24c6SIngo Weinhold // destructor
~MessageRunnerTestLooper()52*dace24c6SIngo Weinhold MessageRunnerTestLooper::~MessageRunnerTestLooper()
53*dace24c6SIngo Weinhold {
54*dace24c6SIngo Weinhold for (int32 i = 0; MessageInfo *info = MessageInfoAt(i); i++)
55*dace24c6SIngo Weinhold delete info;
56*dace24c6SIngo Weinhold }
57*dace24c6SIngo Weinhold
58*dace24c6SIngo Weinhold // MessageReceived
59*dace24c6SIngo Weinhold void
MessageReceived(BMessage * message)60*dace24c6SIngo Weinhold MessageRunnerTestLooper::MessageReceived(BMessage *message)
61*dace24c6SIngo Weinhold {
62*dace24c6SIngo Weinhold switch (message->what) {
63*dace24c6SIngo Weinhold case MSG_RUNNER_MESSAGE:
64*dace24c6SIngo Weinhold {
65*dace24c6SIngo Weinhold MessageInfo *info = new MessageInfo;
66*dace24c6SIngo Weinhold info->time = system_time();
67*dace24c6SIngo Weinhold fMessageInfos.AddItem(info);
68*dace24c6SIngo Weinhold message->SendReply(MSG_REPLY);
69*dace24c6SIngo Weinhold break;
70*dace24c6SIngo Weinhold }
71*dace24c6SIngo Weinhold }
72*dace24c6SIngo Weinhold }
73*dace24c6SIngo Weinhold
74*dace24c6SIngo Weinhold // CheckMessages
75*dace24c6SIngo Weinhold bool
CheckMessages(bigtime_t startTime,bigtime_t interval,int32 count)76*dace24c6SIngo Weinhold MessageRunnerTestLooper::CheckMessages(bigtime_t startTime, bigtime_t interval,
77*dace24c6SIngo Weinhold int32 count)
78*dace24c6SIngo Weinhold {
79*dace24c6SIngo Weinhold return CheckMessages(0, startTime, interval, count);
80*dace24c6SIngo Weinhold }
81*dace24c6SIngo Weinhold
82*dace24c6SIngo Weinhold // CheckMessages
83*dace24c6SIngo Weinhold bool
CheckMessages(int32 skip,bigtime_t startTime,bigtime_t interval,int32 count)84*dace24c6SIngo Weinhold MessageRunnerTestLooper::CheckMessages(int32 skip, bigtime_t startTime,
85*dace24c6SIngo Weinhold bigtime_t interval, int32 count)
86*dace24c6SIngo Weinhold {
87*dace24c6SIngo Weinhold BAutolock _lock(this);
88*dace24c6SIngo Weinhold bool result = (fMessageInfos.CountItems() == count + skip);
89*dace24c6SIngo Weinhold if (!result) {
90*dace24c6SIngo Weinhold printf("message counts don't match: %ld vs. %ld\n", fMessageInfos.CountItems(),
91*dace24c6SIngo Weinhold count + skip);
92*dace24c6SIngo Weinhold }
93*dace24c6SIngo Weinhold for (int32 i = 0; result && i < count; i++) {
94*dace24c6SIngo Weinhold MessageInfo *info = MessageInfoAt(i + skip);
95*dace24c6SIngo Weinhold bigtime_t expectedTime = startTime + (i + 1) * interval;
96*dace24c6SIngo Weinhold result = (expectedTime - JITTER < info->time
97*dace24c6SIngo Weinhold && info->time < expectedTime + JITTER);
98*dace24c6SIngo Weinhold if (!result)
99*dace24c6SIngo Weinhold printf("message out of time: %lld vs. %lld\n", info->time, expectedTime);
100*dace24c6SIngo Weinhold }
101*dace24c6SIngo Weinhold return result;
102*dace24c6SIngo Weinhold }
103*dace24c6SIngo Weinhold
104*dace24c6SIngo Weinhold // MessageInfoAt
105*dace24c6SIngo Weinhold MessageRunnerTestLooper::MessageInfo*
MessageInfoAt(int32 index) const106*dace24c6SIngo Weinhold MessageRunnerTestLooper::MessageInfoAt(int32 index) const
107*dace24c6SIngo Weinhold {
108*dace24c6SIngo Weinhold return static_cast<MessageInfo*>(fMessageInfos.ItemAt(index));
109*dace24c6SIngo Weinhold }
110*dace24c6SIngo Weinhold
111*dace24c6SIngo Weinhold
112*dace24c6SIngo Weinhold ////////////////////////
113*dace24c6SIngo Weinhold // MessageRunnerTestApp
114*dace24c6SIngo Weinhold
115*dace24c6SIngo Weinhold // constructor
MessageRunnerTestApp(const char * signature)116*dace24c6SIngo Weinhold MessageRunnerTestApp::MessageRunnerTestApp(const char *signature)
117*dace24c6SIngo Weinhold : BApplication(signature),
118*dace24c6SIngo Weinhold fThread(-1),
119*dace24c6SIngo Weinhold fReplyCount(0),
120*dace24c6SIngo Weinhold fLooper(NULL),
121*dace24c6SIngo Weinhold fHandler(NULL)
122*dace24c6SIngo Weinhold {
123*dace24c6SIngo Weinhold // create a looper
124*dace24c6SIngo Weinhold fLooper = new MessageRunnerTestLooper;
125*dace24c6SIngo Weinhold fLooper->Run();
126*dace24c6SIngo Weinhold // create a handler
127*dace24c6SIngo Weinhold fHandler = new MessageRunnerTestHandler;
128*dace24c6SIngo Weinhold AddHandler(fHandler);
129*dace24c6SIngo Weinhold // start out message loop in a different thread
130*dace24c6SIngo Weinhold Unlock();
131*dace24c6SIngo Weinhold fThread = spawn_thread(_ThreadEntry, "message runner app thread",
132*dace24c6SIngo Weinhold B_NORMAL_PRIORITY, this);
133*dace24c6SIngo Weinhold resume_thread(fThread);
134*dace24c6SIngo Weinhold }
135*dace24c6SIngo Weinhold
136*dace24c6SIngo Weinhold // destructor
~MessageRunnerTestApp()137*dace24c6SIngo Weinhold MessageRunnerTestApp::~MessageRunnerTestApp()
138*dace24c6SIngo Weinhold {
139*dace24c6SIngo Weinhold // quit the looper
140*dace24c6SIngo Weinhold fLooper->Lock();
141*dace24c6SIngo Weinhold fLooper->Quit();
142*dace24c6SIngo Weinhold // shut down our message loop
143*dace24c6SIngo Weinhold BMessage reply;
144*dace24c6SIngo Weinhold PostMessage(B_QUIT_REQUESTED);
145*dace24c6SIngo Weinhold int32 dummy;
146*dace24c6SIngo Weinhold wait_for_thread(fThread, &dummy);
147*dace24c6SIngo Weinhold // delete the handler
148*dace24c6SIngo Weinhold Lock();
149*dace24c6SIngo Weinhold RemoveHandler(fHandler);
150*dace24c6SIngo Weinhold delete fHandler;
151*dace24c6SIngo Weinhold }
152*dace24c6SIngo Weinhold
153*dace24c6SIngo Weinhold // MessageReceived
154*dace24c6SIngo Weinhold void
MessageReceived(BMessage * message)155*dace24c6SIngo Weinhold MessageRunnerTestApp::MessageReceived(BMessage *message)
156*dace24c6SIngo Weinhold {
157*dace24c6SIngo Weinhold switch (message->what) {
158*dace24c6SIngo Weinhold case MSG_REPLY:
159*dace24c6SIngo Weinhold fReplyCount++;
160*dace24c6SIngo Weinhold break;
161*dace24c6SIngo Weinhold }
162*dace24c6SIngo Weinhold }
163*dace24c6SIngo Weinhold
164*dace24c6SIngo Weinhold // QuitRequested
165*dace24c6SIngo Weinhold bool
QuitRequested()166*dace24c6SIngo Weinhold MessageRunnerTestApp::QuitRequested()
167*dace24c6SIngo Weinhold {
168*dace24c6SIngo Weinhold return true;
169*dace24c6SIngo Weinhold }
170*dace24c6SIngo Weinhold
171*dace24c6SIngo Weinhold // _ThreadEntry
172*dace24c6SIngo Weinhold int32
_ThreadEntry(void * data)173*dace24c6SIngo Weinhold MessageRunnerTestApp::_ThreadEntry(void *data)
174*dace24c6SIngo Weinhold {
175*dace24c6SIngo Weinhold MessageRunnerTestApp *app = static_cast<MessageRunnerTestApp*>(data);
176*dace24c6SIngo Weinhold app->Lock();
177*dace24c6SIngo Weinhold app->Run();
178*dace24c6SIngo Weinhold return 0;
179*dace24c6SIngo Weinhold }
180*dace24c6SIngo Weinhold
181