Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Side by Side Diff: runtime/vm/message_handler_test.cc

Issue 9924015: Use the ThreadPool for all isolates and native ports. Previously, (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 #include "vm/message_handler.h"
6 #include "vm/unit_test.h"
7
8 namespace dart {
9
10 class MessageHandlerTestPeer {
11 public:
12 explicit MessageHandlerTestPeer(MessageHandler* handler)
13 : handler_(handler) {}
14
15 void PostMessage(Message* message) { handler_->PostMessage(message); }
16 void ClosePort(Dart_Port port) { handler_->ClosePort(port); }
17 void CloseAllPorts() { handler_->CloseAllPorts(); }
18
19 void increment_live_ports() { handler_->increment_live_ports(); }
20 void decrement_live_ports() { handler_->decrement_live_ports(); }
21
22 MessageQueue* queue() const { return handler_->queue_; }
23 MessageQueue* oob_queue() const { return handler_->oob_queue_; }
24
25 private:
26 MessageHandler* handler_;
27
28 DISALLOW_COPY_AND_ASSIGN(MessageHandlerTestPeer);
29 };
30
31
32 class TestMessageHandler : public MessageHandler {
33 public:
34 TestMessageHandler()
35 : port_buffer_(strdup("")),
36 notify_count_(0),
37 message_count_(0),
38 result_(true) {}
39
40 ~TestMessageHandler() {
41 free(port_buffer_);
42 }
43
44 void MessageNotify(Message::Priority priority) {
45 notify_count_++;
46 }
47
48 bool HandleMessage(Message* message) {
49 // For testing purposes, keep a string with a list of the ports
50 // for all messages we receive.
51 intptr_t len =
52 OS::SNPrint(NULL, 0, "%s %d", port_buffer_, message->dest_port()) + 1;
53 char* buffer = reinterpret_cast<char*>(malloc(len));
54 OS::SNPrint(buffer, len, "%s %d", port_buffer_, message->dest_port());
55 free(port_buffer_);
56 port_buffer_ = buffer;
57 delete message;
58 message_count_++;
59 return result_;
60 }
61
62
63 bool Start() {
64 intptr_t len =
65 OS::SNPrint(NULL, 0, "%s start", port_buffer_) + 1;
66 char* buffer = reinterpret_cast<char*>(malloc(len));
67 OS::SNPrint(buffer, len, "%s start", port_buffer_);
68 free(port_buffer_);
69 port_buffer_ = buffer;
70 return true;
71 }
72
73
74 void End() {
75 intptr_t len =
76 OS::SNPrint(NULL, 0, "%s end", port_buffer_) + 1;
77 char* buffer = reinterpret_cast<char*>(malloc(len));
78 OS::SNPrint(buffer, len, "%s end", port_buffer_);
79 free(port_buffer_);
80 port_buffer_ = buffer;
81 }
82
83
84 const char* port_buffer() const { return port_buffer_; }
85 int notify_count() const { return notify_count_; }
86 int message_count() const { return message_count_; }
87
88 void set_result(bool result) { result_ = result; }
89
90 private:
91 char* port_buffer_;
92 int notify_count_;
93 int message_count_;
94 bool result_;
95
96 DISALLOW_COPY_AND_ASSIGN(TestMessageHandler);
97 };
98
99
100 bool TestStartFunction(uword data) {
101 return (reinterpret_cast<TestMessageHandler*>(data))->Start();
102 }
103
104
105 void TestEndFunction(uword data) {
106 return (reinterpret_cast<TestMessageHandler*>(data))->End();
107 }
108
109
110 UNIT_TEST_CASE(MessageHandler_PostMessage) {
111 TestMessageHandler handler;
112 MessageHandlerTestPeer handler_peer(&handler);
113 EXPECT_EQ(0, handler.notify_count());
114
115 // Post a message.
116 Message* message = new Message(0, 0, NULL, Message::kNormalPriority);
117 handler_peer.PostMessage(message);
118
119 // The notify callback is called.
120 EXPECT_EQ(1, handler.notify_count());
121
122 // The message has been added to the correct queue.
123 EXPECT(message == handler_peer.queue()->Dequeue());
124 EXPECT(NULL == handler_peer.oob_queue()->Dequeue());
125 delete message;
126
127 // Post an oob message.
128 message = new Message(0, 0, NULL, Message::kOOBPriority);
129 handler_peer.PostMessage(message);
130
131 // The notify callback is called.
132 EXPECT_EQ(2, handler.notify_count());
133
134 // The message has been added to the correct queue.
135 EXPECT(message == handler_peer.oob_queue()->Dequeue());
136 EXPECT(NULL == handler_peer.queue()->Dequeue());
137 delete message;
138 }
139
140
141 UNIT_TEST_CASE(MessageHandler_ClosePort) {
142 TestMessageHandler handler;
143 MessageHandlerTestPeer handler_peer(&handler);
144 Message* message1 = new Message(1, 0, NULL, Message::kNormalPriority);
145 handler_peer.PostMessage(message1);
146 Message* message2 = new Message(2, 0, NULL, Message::kNormalPriority);
147 handler_peer.PostMessage(message2);
148
149 handler_peer.ClosePort(1);
150
151 // The message on port 1 is dropped from the queue.
152 EXPECT(message2 == handler_peer.queue()->Dequeue());
153 EXPECT(NULL == handler_peer.queue()->Dequeue());
154 delete message2;
155 }
156
157
158 UNIT_TEST_CASE(MessageHandler_CloseAllPorts) {
159 TestMessageHandler handler;
160 MessageHandlerTestPeer handler_peer(&handler);
161 Message* message1 = new Message(1, 0, NULL, Message::kNormalPriority);
162 handler_peer.PostMessage(message1);
163 Message* message2 = new Message(2, 0, NULL, Message::kNormalPriority);
164 handler_peer.PostMessage(message2);
165
166 handler_peer.CloseAllPorts();
167
168 // All messages are dropped from the queue.
169 EXPECT(NULL == handler_peer.queue()->Dequeue());
170 }
171
172
173 UNIT_TEST_CASE(MessageHandler_HandleNextMessage) {
174 TestMessageHandler handler;
175 MessageHandlerTestPeer handler_peer(&handler);
176 Message* message1 = new Message(1, 0, NULL, Message::kNormalPriority);
177 handler_peer.PostMessage(message1);
178 Message* oob_message1 = new Message(3, 0, NULL, Message::kOOBPriority);
179 handler_peer.PostMessage(oob_message1);
180 Message* message2 = new Message(2, 0, NULL, Message::kNormalPriority);
181 handler_peer.PostMessage(message2);
182 Message* oob_message2 = new Message(4, 0, NULL, Message::kOOBPriority);
183 handler_peer.PostMessage(oob_message2);
184
185 // We handle both oob messages and a single normal message.
186 EXPECT(handler.HandleNextMessage());
187 EXPECT_STREQ(" 3 4 1", handler.port_buffer());
188 handler_peer.CloseAllPorts();
189 }
190
191
192 UNIT_TEST_CASE(MessageHandler_HandleOOBMessages) {
193 TestMessageHandler handler;
194 MessageHandlerTestPeer handler_peer(&handler);
195 Message* message1 = new Message(1, 0, NULL, Message::kNormalPriority);
196 handler_peer.PostMessage(message1);
197 Message* message2 = new Message(2, 0, NULL, Message::kNormalPriority);
198 handler_peer.PostMessage(message2);
199 Message* oob_message1 = new Message(3, 0, NULL, Message::kOOBPriority);
200 handler_peer.PostMessage(oob_message1);
201 Message* oob_message2 = new Message(4, 0, NULL, Message::kOOBPriority);
202 handler_peer.PostMessage(oob_message2);
203
204 // We handle both oob messages but no normal messages.
205 EXPECT(handler.HandleOOBMessages());
206 EXPECT_STREQ(" 3 4", handler.port_buffer());
207 handler_peer.CloseAllPorts();
208 }
209
210
211 struct ThreadStartInfo {
212 MessageHandler* handler;
213 int count;
214 };
215
216
217 static void SendMessages(uword param) {
218 ThreadStartInfo* info = reinterpret_cast<ThreadStartInfo*>(param);
219 MessageHandler* handler = info->handler;
220 MessageHandlerTestPeer handler_peer(handler);
221 for (int i = 0; i < info->count; i++) {
222 Message* message = new Message(i + 1, 0, NULL, Message::kNormalPriority);
223 handler_peer.PostMessage(message);
224 }
225 }
226
227
228 UNIT_TEST_CASE(MessageHandler_Run) {
229 ThreadPool pool;
230 TestMessageHandler handler;
231 MessageHandlerTestPeer handler_peer(&handler);
232
233 EXPECT(!handler.HasLivePorts());
234 handler_peer.increment_live_ports();
235
236 handler.Run(&pool,
237 TestStartFunction,
238 TestEndFunction,
239 reinterpret_cast<uword>(&handler));
240 Message* message = new Message(100, 0, NULL, Message::kNormalPriority);
241 handler_peer.PostMessage(message);
242
243 // Wait for the first message to be handled.
244 while (handler.message_count() < 1) {
245 OS::Sleep(10);
246 }
247 EXPECT_STREQ(" start 100", handler.port_buffer());
248
249 // Start a thread which sends more messages.
250 ThreadStartInfo info;
251 info.handler = &handler;
252 info.count = 10;
253 Thread::Start(SendMessages, reinterpret_cast<uword>(&info));
254 while (handler.message_count() < 11) {
255 OS::Sleep(10);
256 }
siva 2012/04/18 22:05:00 if there is a bug this test will hang forever, do
turnidge 2012/04/19 19:46:55 I've added code to limit the test to about 20 seco
257 EXPECT_STREQ(" start 100 1 2 3 4 5 6 7 8 9 10", handler.port_buffer());
258
259 handler_peer.decrement_live_ports();
260 EXPECT(!handler.HasLivePorts());
261 }
262
263 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698