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