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 14 MessageRunnerTestHandler::MessageRunnerTestHandler() 15 : BHandler("message runner test handler"), 16 fReplyCount() 17 { 18 } 19 20 // destructor 21 MessageRunnerTestHandler::~MessageRunnerTestHandler() 22 { 23 } 24 25 // MessageReceived 26 void 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 45 MessageRunnerTestLooper::MessageRunnerTestLooper() 46 : BLooper(), 47 fMessageInfos() 48 { 49 } 50 51 // destructor 52 MessageRunnerTestLooper::~MessageRunnerTestLooper() 53 { 54 for (int32 i = 0; MessageInfo *info = MessageInfoAt(i); i++) 55 delete info; 56 } 57 58 // MessageReceived 59 void 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 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 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* 106 MessageRunnerTestLooper::MessageInfoAt(int32 index) const 107 { 108 return static_cast<MessageInfo*>(fMessageInfos.ItemAt(index)); 109 } 110 111 112 //////////////////////// 113 // MessageRunnerTestApp 114 115 // constructor 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 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 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 166 MessageRunnerTestApp::QuitRequested() 167 { 168 return true; 169 } 170 171 // _ThreadEntry 172 int32 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