OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/logging.h" | 5 #include "base/logging.h" |
6 #include "base/message_loop.h" | 6 #include "base/message_loop.h" |
7 #include "base/platform_thread.h" | 7 #include "base/platform_thread.h" |
8 #include "base/ref_counted.h" | 8 #include "base/ref_counted.h" |
9 #include "base/thread.h" | 9 #include "base/thread.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
(...skipping 1038 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1049 EXPECT_EQ(order[ 4], TaskItem(ORDERERD, 4, false)); | 1049 EXPECT_EQ(order[ 4], TaskItem(ORDERERD, 4, false)); |
1050 EXPECT_EQ(order[ 5], TaskItem(PUMPS, 1, false)); | 1050 EXPECT_EQ(order[ 5], TaskItem(PUMPS, 1, false)); |
1051 EXPECT_EQ(order[ 6], TaskItem(ORDERERD, 2, true)); | 1051 EXPECT_EQ(order[ 6], TaskItem(ORDERERD, 2, true)); |
1052 EXPECT_EQ(order[ 7], TaskItem(ORDERERD, 2, false)); | 1052 EXPECT_EQ(order[ 7], TaskItem(ORDERERD, 2, false)); |
1053 EXPECT_EQ(order[ 8], TaskItem(QUITMESSAGELOOP, 5, true)); | 1053 EXPECT_EQ(order[ 8], TaskItem(QUITMESSAGELOOP, 5, true)); |
1054 EXPECT_EQ(order[ 9], TaskItem(QUITMESSAGELOOP, 5, false)); | 1054 EXPECT_EQ(order[ 9], TaskItem(QUITMESSAGELOOP, 5, false)); |
1055 } | 1055 } |
1056 | 1056 |
1057 #if defined(OS_WIN) | 1057 #if defined(OS_WIN) |
1058 | 1058 |
1059 class AutoresetWatcher : public MessageLoopForIO::Watcher { | |
1060 public: | |
1061 explicit AutoresetWatcher(HANDLE signal) : signal_(signal) { | |
1062 } | |
1063 virtual void OnObjectSignaled(HANDLE object); | |
1064 private: | |
1065 HANDLE signal_; | |
1066 }; | |
1067 | |
1068 void AutoresetWatcher::OnObjectSignaled(HANDLE object) { | |
1069 MessageLoopForIO::current()->WatchObject(object, NULL); | |
1070 ASSERT_TRUE(SetEvent(signal_)); | |
1071 } | |
1072 | |
1073 class AutoresetTask : public Task { | |
1074 public: | |
1075 AutoresetTask(HANDLE object, MessageLoopForIO::Watcher* watcher) | |
1076 : object_(object), watcher_(watcher) {} | |
1077 virtual void Run() { | |
1078 MessageLoopForIO::current()->WatchObject(object_, watcher_); | |
1079 } | |
1080 | |
1081 private: | |
1082 HANDLE object_; | |
1083 MessageLoopForIO::Watcher* watcher_; | |
1084 }; | |
1085 | |
1086 void RunTest_AutoresetEvents(MessageLoop::Type message_loop_type) { | |
1087 MessageLoop loop(message_loop_type); | |
1088 | |
1089 SECURITY_ATTRIBUTES attributes; | |
1090 attributes.nLength = sizeof(attributes); | |
1091 attributes.bInheritHandle = false; | |
1092 attributes.lpSecurityDescriptor = NULL; | |
1093 | |
1094 // Init an autoreset and a manual reset events. | |
1095 HANDLE autoreset = CreateEvent(&attributes, FALSE, FALSE, NULL); | |
1096 HANDLE callback_called = CreateEvent(&attributes, TRUE, FALSE, NULL); | |
1097 ASSERT_TRUE(NULL != autoreset); | |
1098 ASSERT_TRUE(NULL != callback_called); | |
1099 | |
1100 Thread thread("Autoreset test"); | |
1101 Thread::Options options; | |
1102 options.message_loop_type = message_loop_type; | |
1103 ASSERT_TRUE(thread.StartWithOptions(options)); | |
1104 | |
1105 MessageLoop* thread_loop = thread.message_loop(); | |
1106 ASSERT_TRUE(NULL != thread_loop); | |
1107 | |
1108 AutoresetWatcher watcher(callback_called); | |
1109 AutoresetTask* task = new AutoresetTask(autoreset, &watcher); | |
1110 thread_loop->PostTask(FROM_HERE, task); | |
1111 Sleep(100); // Make sure the thread runs and sleeps for lack of work. | |
1112 | |
1113 ASSERT_TRUE(SetEvent(autoreset)); | |
1114 | |
1115 DWORD result = WaitForSingleObject(callback_called, 1000); | |
1116 EXPECT_EQ(WAIT_OBJECT_0, result); | |
1117 | |
1118 thread.Stop(); | |
1119 } | |
1120 | |
1121 class DispatcherImpl : public MessageLoopForUI::Dispatcher { | 1059 class DispatcherImpl : public MessageLoopForUI::Dispatcher { |
1122 public: | 1060 public: |
1123 DispatcherImpl() : dispatch_count_(0) {} | 1061 DispatcherImpl() : dispatch_count_(0) {} |
1124 | 1062 |
1125 virtual bool Dispatch(const MSG& msg) { | 1063 virtual bool Dispatch(const MSG& msg) { |
1126 ::TranslateMessage(&msg); | 1064 ::TranslateMessage(&msg); |
1127 ::DispatchMessage(&msg); | 1065 ::DispatchMessage(&msg); |
1128 return (++dispatch_count_ != 2); | 1066 return (++dispatch_count_ != 2); |
1129 } | 1067 } |
1130 | 1068 |
(...skipping 12 matching lines...) Expand all Loading... |
1143 }; | 1081 }; |
1144 Task* task = new MyTask(); | 1082 Task* task = new MyTask(); |
1145 MessageLoop::current()->PostDelayedTask(FROM_HERE, task, 100); | 1083 MessageLoop::current()->PostDelayedTask(FROM_HERE, task, 100); |
1146 DispatcherImpl dispatcher; | 1084 DispatcherImpl dispatcher; |
1147 MessageLoopForUI::current()->Run(&dispatcher); | 1085 MessageLoopForUI::current()->Run(&dispatcher); |
1148 ASSERT_EQ(2, dispatcher.dispatch_count_); | 1086 ASSERT_EQ(2, dispatcher.dispatch_count_); |
1149 } | 1087 } |
1150 | 1088 |
1151 class TestIOHandler : public MessageLoopForIO::IOHandler { | 1089 class TestIOHandler : public MessageLoopForIO::IOHandler { |
1152 public: | 1090 public: |
1153 TestIOHandler(const wchar_t* name, HANDLE signal); | 1091 TestIOHandler(const wchar_t* name, HANDLE signal, bool wait); |
1154 | 1092 |
1155 virtual void OnIOCompleted(OVERLAPPED* context, DWORD bytes_transfered, | 1093 virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, |
1156 DWORD error); | 1094 DWORD bytes_transfered, DWORD error); |
1157 | 1095 |
1158 HANDLE file() { return file_.Get(); } | 1096 void Init(); |
1159 void* buffer() { return buffer_; } | 1097 void WaitForIO(); |
1160 OVERLAPPED* context() { return &context_; } | 1098 OVERLAPPED* context() { return &context_.overlapped; } |
1161 DWORD size() { return sizeof(buffer_); } | 1099 DWORD size() { return sizeof(buffer_); } |
1162 | 1100 |
1163 private: | 1101 private: |
1164 char buffer_[48]; | 1102 char buffer_[48]; |
1165 OVERLAPPED context_; | 1103 MessageLoopForIO::IOContext context_; |
1166 HANDLE signal_; | 1104 HANDLE signal_; |
1167 ScopedHandle file_; | 1105 ScopedHandle file_; |
1168 ScopedHandle event_; | 1106 bool wait_; |
1169 }; | 1107 }; |
1170 | 1108 |
1171 TestIOHandler::TestIOHandler(const wchar_t* name, HANDLE signal) | 1109 TestIOHandler::TestIOHandler(const wchar_t* name, HANDLE signal, bool wait) |
1172 : signal_(signal) { | 1110 : signal_(signal), wait_(wait) { |
1173 memset(buffer_, 0, sizeof(buffer_)); | 1111 memset(buffer_, 0, sizeof(buffer_)); |
1174 memset(&context_, 0, sizeof(context_)); | 1112 memset(&context_, 0, sizeof(context_)); |
1175 | 1113 context_.handler = this; |
1176 event_.Set(CreateEvent(NULL, TRUE, FALSE, NULL)); | |
1177 EXPECT_TRUE(event_.IsValid()); | |
1178 context_.hEvent = event_.Get(); | |
1179 | 1114 |
1180 file_.Set(CreateFile(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, | 1115 file_.Set(CreateFile(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, |
1181 FILE_FLAG_OVERLAPPED, NULL)); | 1116 FILE_FLAG_OVERLAPPED, NULL)); |
1182 EXPECT_TRUE(file_.IsValid()); | 1117 EXPECT_TRUE(file_.IsValid()); |
1183 } | 1118 } |
1184 | 1119 |
1185 void TestIOHandler::OnIOCompleted(OVERLAPPED* context, DWORD bytes_transfered, | 1120 void TestIOHandler::Init() { |
1186 DWORD error) { | 1121 MessageLoopForIO::current()->RegisterIOHandler(file_, this); |
| 1122 |
| 1123 DWORD read; |
| 1124 EXPECT_FALSE(ReadFile(file_, buffer_, size(), &read, context())); |
| 1125 EXPECT_EQ(ERROR_IO_PENDING, GetLastError()); |
| 1126 if (wait_) |
| 1127 WaitForIO(); |
| 1128 } |
| 1129 |
| 1130 void TestIOHandler::OnIOCompleted(MessageLoopForIO::IOContext* context, |
| 1131 DWORD bytes_transfered, DWORD error) { |
1187 ASSERT_TRUE(context == &context_); | 1132 ASSERT_TRUE(context == &context_); |
1188 MessageLoopForIO::current()->RegisterIOContext(context, NULL); | |
1189 ASSERT_TRUE(SetEvent(signal_)); | 1133 ASSERT_TRUE(SetEvent(signal_)); |
1190 } | 1134 } |
1191 | 1135 |
| 1136 void TestIOHandler::WaitForIO() { |
| 1137 EXPECT_TRUE(MessageLoopForIO::current()->WaitForIOCompletion(300, this)); |
| 1138 EXPECT_TRUE(MessageLoopForIO::current()->WaitForIOCompletion(400, this)); |
| 1139 } |
| 1140 |
1192 class IOHandlerTask : public Task { | 1141 class IOHandlerTask : public Task { |
1193 public: | 1142 public: |
1194 explicit IOHandlerTask(TestIOHandler* handler) : handler_(handler) {} | 1143 explicit IOHandlerTask(TestIOHandler* handler) : handler_(handler) {} |
1195 virtual void Run(); | 1144 virtual void Run() { |
| 1145 handler_->Init(); |
| 1146 } |
1196 | 1147 |
1197 private: | 1148 private: |
1198 TestIOHandler* handler_; | 1149 TestIOHandler* handler_; |
1199 }; | 1150 }; |
1200 | 1151 |
1201 void IOHandlerTask::Run() { | |
1202 MessageLoopForIO::current()->RegisterIOHandler(handler_->file(), handler_); | |
1203 MessageLoopForIO::current()->RegisterIOContext(handler_->context(), handler_); | |
1204 | |
1205 DWORD read; | |
1206 EXPECT_FALSE(ReadFile(handler_->file(), handler_->buffer(), handler_->size(), | |
1207 &read, handler_->context())); | |
1208 EXPECT_EQ(ERROR_IO_PENDING, GetLastError()); | |
1209 } | |
1210 | |
1211 void RunTest_IOHandler() { | 1152 void RunTest_IOHandler() { |
1212 // This test requires an IO loop. | |
1213 MessageLoop loop(MessageLoop::TYPE_IO); | |
1214 | |
1215 ScopedHandle callback_called(CreateEvent(NULL, TRUE, FALSE, NULL)); | 1153 ScopedHandle callback_called(CreateEvent(NULL, TRUE, FALSE, NULL)); |
1216 ASSERT_TRUE(callback_called.IsValid()); | 1154 ASSERT_TRUE(callback_called.IsValid()); |
1217 | 1155 |
1218 const wchar_t* kPipeName = L"\\\\.\\pipe\\iohandler_pipe"; | 1156 const wchar_t* kPipeName = L"\\\\.\\pipe\\iohandler_pipe"; |
1219 ScopedHandle server(CreateNamedPipe(kPipeName, PIPE_ACCESS_OUTBOUND, 0, 1, | 1157 ScopedHandle server(CreateNamedPipe(kPipeName, PIPE_ACCESS_OUTBOUND, 0, 1, |
1220 0, 0, 0, NULL)); | 1158 0, 0, 0, NULL)); |
1221 ASSERT_TRUE(server.IsValid()); | 1159 ASSERT_TRUE(server.IsValid()); |
1222 | 1160 |
1223 Thread thread("IOHandler test"); | 1161 Thread thread("IOHandler test"); |
1224 Thread::Options options; | 1162 Thread::Options options; |
1225 options.message_loop_type = MessageLoop::TYPE_IO; | 1163 options.message_loop_type = MessageLoop::TYPE_IO; |
1226 ASSERT_TRUE(thread.StartWithOptions(options)); | 1164 ASSERT_TRUE(thread.StartWithOptions(options)); |
1227 | 1165 |
1228 MessageLoop* thread_loop = thread.message_loop(); | 1166 MessageLoop* thread_loop = thread.message_loop(); |
1229 ASSERT_TRUE(NULL != thread_loop); | 1167 ASSERT_TRUE(NULL != thread_loop); |
1230 | 1168 |
1231 TestIOHandler handler(kPipeName, callback_called); | 1169 TestIOHandler handler(kPipeName, callback_called, false); |
1232 IOHandlerTask* task = new IOHandlerTask(&handler); | 1170 IOHandlerTask* task = new IOHandlerTask(&handler); |
1233 thread_loop->PostTask(FROM_HERE, task); | 1171 thread_loop->PostTask(FROM_HERE, task); |
1234 Sleep(100); // Make sure the thread runs and sleeps for lack of work. | 1172 Sleep(100); // Make sure the thread runs and sleeps for lack of work. |
1235 | 1173 |
1236 const char buffer[] = "Hello there!"; | 1174 const char buffer[] = "Hello there!"; |
1237 DWORD written; | 1175 DWORD written; |
1238 EXPECT_TRUE(WriteFile(server, buffer, sizeof(buffer), &written, NULL)); | 1176 EXPECT_TRUE(WriteFile(server, buffer, sizeof(buffer), &written, NULL)); |
1239 | 1177 |
1240 DWORD result = WaitForSingleObject(callback_called, 1000); | 1178 DWORD result = WaitForSingleObject(callback_called, 1000); |
1241 EXPECT_EQ(WAIT_OBJECT_0, result); | 1179 EXPECT_EQ(WAIT_OBJECT_0, result); |
1242 | 1180 |
1243 thread.Stop(); | 1181 thread.Stop(); |
1244 } | 1182 } |
1245 | 1183 |
| 1184 void RunTest_WaitForIO() { |
| 1185 ScopedHandle callback1_called(CreateEvent(NULL, TRUE, FALSE, NULL)); |
| 1186 ScopedHandle callback2_called(CreateEvent(NULL, TRUE, FALSE, NULL)); |
| 1187 ASSERT_TRUE(callback1_called.IsValid()); |
| 1188 ASSERT_TRUE(callback2_called.IsValid()); |
| 1189 |
| 1190 const wchar_t* kPipeName1 = L"\\\\.\\pipe\\iohandler_pipe1"; |
| 1191 const wchar_t* kPipeName2 = L"\\\\.\\pipe\\iohandler_pipe2"; |
| 1192 ScopedHandle server1(CreateNamedPipe(kPipeName1, PIPE_ACCESS_OUTBOUND, 0, 1, |
| 1193 0, 0, 0, NULL)); |
| 1194 ScopedHandle server2(CreateNamedPipe(kPipeName2, PIPE_ACCESS_OUTBOUND, 0, 1, |
| 1195 0, 0, 0, NULL)); |
| 1196 ASSERT_TRUE(server1.IsValid()); |
| 1197 ASSERT_TRUE(server2.IsValid()); |
| 1198 |
| 1199 Thread thread("IOHandler test"); |
| 1200 Thread::Options options; |
| 1201 options.message_loop_type = MessageLoop::TYPE_IO; |
| 1202 ASSERT_TRUE(thread.StartWithOptions(options)); |
| 1203 |
| 1204 MessageLoop* thread_loop = thread.message_loop(); |
| 1205 ASSERT_TRUE(NULL != thread_loop); |
| 1206 |
| 1207 TestIOHandler handler1(kPipeName1, callback1_called, false); |
| 1208 TestIOHandler handler2(kPipeName2, callback2_called, true); |
| 1209 IOHandlerTask* task1 = new IOHandlerTask(&handler1); |
| 1210 IOHandlerTask* task2 = new IOHandlerTask(&handler2); |
| 1211 thread_loop->PostTask(FROM_HERE, task1); |
| 1212 Sleep(100); // Make sure the thread runs and sleeps for lack of work. |
| 1213 thread_loop->PostTask(FROM_HERE, task2); |
| 1214 Sleep(100); |
| 1215 |
| 1216 // At this time handler1 is waiting to be called, and the thread is waiting |
| 1217 // on the Init method of handler2, filtering only handler2 callbacks. |
| 1218 |
| 1219 const char buffer[] = "Hello there!"; |
| 1220 DWORD written; |
| 1221 EXPECT_TRUE(WriteFile(server1, buffer, sizeof(buffer), &written, NULL)); |
| 1222 Sleep(200); |
| 1223 EXPECT_EQ(WAIT_TIMEOUT, WaitForSingleObject(callback1_called, 0)) << |
| 1224 "handler1 has not been called"; |
| 1225 |
| 1226 EXPECT_TRUE(WriteFile(server2, buffer, sizeof(buffer), &written, NULL)); |
| 1227 |
| 1228 HANDLE objects[2] = { callback1_called.Get(), callback2_called.Get() }; |
| 1229 DWORD result = WaitForMultipleObjects(2, objects, TRUE, 1000); |
| 1230 EXPECT_EQ(WAIT_OBJECT_0, result); |
| 1231 |
| 1232 thread.Stop(); |
| 1233 } |
| 1234 |
1246 #endif // defined(OS_WIN) | 1235 #endif // defined(OS_WIN) |
1247 | 1236 |
1248 } // namespace | 1237 } // namespace |
1249 | 1238 |
1250 //----------------------------------------------------------------------------- | 1239 //----------------------------------------------------------------------------- |
1251 // Each test is run against each type of MessageLoop. That way we are sure | 1240 // Each test is run against each type of MessageLoop. That way we are sure |
1252 // that message loops work properly in all configurations. Of course, in some | 1241 // that message loops work properly in all configurations. Of course, in some |
1253 // cases, a unit test may only be for a particular type of loop. | 1242 // cases, a unit test may only be for a particular type of loop. |
1254 | 1243 |
1255 TEST(MessageLoopTest, PostTask) { | 1244 TEST(MessageLoopTest, PostTask) { |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1372 RunTest_NonNestableWithNoNesting(MessageLoop::TYPE_IO); | 1361 RunTest_NonNestableWithNoNesting(MessageLoop::TYPE_IO); |
1373 } | 1362 } |
1374 | 1363 |
1375 TEST(MessageLoopTest, NonNestableInNestedLoop) { | 1364 TEST(MessageLoopTest, NonNestableInNestedLoop) { |
1376 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_DEFAULT); | 1365 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_DEFAULT); |
1377 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_UI); | 1366 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_UI); |
1378 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_IO); | 1367 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_IO); |
1379 } | 1368 } |
1380 | 1369 |
1381 #if defined(OS_WIN) | 1370 #if defined(OS_WIN) |
1382 TEST(MessageLoopTest, AutoresetEvents) { | |
1383 // This test requires an IO loop | |
1384 RunTest_AutoresetEvents(MessageLoop::TYPE_IO); | |
1385 } | |
1386 | |
1387 TEST(MessageLoopTest, Dispatcher) { | 1371 TEST(MessageLoopTest, Dispatcher) { |
1388 // This test requires a UI loop | 1372 // This test requires a UI loop |
1389 RunTest_Dispatcher(MessageLoop::TYPE_UI); | 1373 RunTest_Dispatcher(MessageLoop::TYPE_UI); |
1390 } | 1374 } |
1391 | 1375 |
1392 TEST(MessageLoopTest, IOHandler) { | 1376 TEST(MessageLoopTest, IOHandler) { |
1393 RunTest_IOHandler(); | 1377 RunTest_IOHandler(); |
1394 } | 1378 } |
| 1379 |
| 1380 TEST(MessageLoopTest, WaitForIO) { |
| 1381 RunTest_WaitForIO(); |
| 1382 } |
1395 #endif // defined(OS_WIN) | 1383 #endif // defined(OS_WIN) |
OLD | NEW |