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

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

Issue 9570046: Make the message queue private in the message handler. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 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
« no previous file with comments | « runtime/vm/message.cc ('k') | runtime/vm/native_message_handler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "platform/assert.h" 5 #include "platform/assert.h"
6 #include "vm/message.h" 6 #include "vm/message.h"
7 #include "vm/unit_test.h" 7 #include "vm/unit_test.h"
8 8
9 namespace dart { 9 namespace dart {
10 10
11 11
12 // Provide access to private members of MessageQueue for testing. 12 // Provide access to private members of MessageQueue for testing.
13 class MessageQueueTestPeer { 13 class MessageQueueTestPeer {
14 public: 14 public:
15 explicit MessageQueueTestPeer(MessageQueue* queue) : queue_(queue) {} 15 explicit MessageQueueTestPeer(MessageQueue* queue) : queue_(queue) {}
16 16
17 bool HasMessage() const { 17 bool HasMessage() const {
18 // We don't really need to grab the monitor during the unit test,
19 // but it doesn't hurt.
20 queue_->monitor_.Enter();
21 bool result = (queue_->head_[Message::kNormalPriority] != NULL || 18 bool result = (queue_->head_[Message::kNormalPriority] != NULL ||
22 queue_->head_[Message::kOOBPriority] != NULL); 19 queue_->head_[Message::kOOBPriority] != NULL);
23 queue_->monitor_.Exit();
24 return result; 20 return result;
25 } 21 }
26 22
27 private: 23 private:
28 MessageQueue* queue_; 24 MessageQueue* queue_;
29 }; 25 };
30 26
31 27
28 class MessageHandlerTestPeer {
29 public:
30 explicit MessageHandlerTestPeer(MessageHandler* handler)
31 : handler_(handler) {}
32
33 MessageQueue* queue() { return handler_->queue_; }
34
35 private:
36 MessageHandler* handler_;
37 };
38
39
32 static uint8_t* AllocMsg(const char* str) { 40 static uint8_t* AllocMsg(const char* str) {
33 return reinterpret_cast<uint8_t*>(strdup(str)); 41 return reinterpret_cast<uint8_t*>(strdup(str));
34 } 42 }
35 43
36 44
37 TEST_CASE(MessageQueue_BasicOperations) { 45 TEST_CASE(MessageQueue_BasicOperations) {
38 MessageQueue queue; 46 MessageQueue queue;
39 MessageQueueTestPeer queue_peer(&queue); 47 MessageQueueTestPeer queue_peer(&queue);
40 EXPECT(!queue_peer.HasMessage()); 48 EXPECT(!queue_peer.HasMessage());
41 49
42 Dart_Port port = 1; 50 Dart_Port port = 1;
43 51
44 // Add two messages. 52 // Add two messages.
45 Message* msg1 = 53 Message* msg1 =
46 new Message(port, 0, AllocMsg("msg1"), Message::kNormalPriority); 54 new Message(port, 0, AllocMsg("msg1"), Message::kNormalPriority);
47 queue.Enqueue(msg1); 55 queue.Enqueue(msg1);
48 EXPECT(queue_peer.HasMessage()); 56 EXPECT(queue_peer.HasMessage());
49 57
50 Message* msg2 = 58 Message* msg2 =
51 new Message(port, 0, AllocMsg("msg2"), Message::kNormalPriority); 59 new Message(port, 0, AllocMsg("msg2"), Message::kNormalPriority);
52 60
53 queue.Enqueue(msg2); 61 queue.Enqueue(msg2);
54 EXPECT(queue_peer.HasMessage()); 62 EXPECT(queue_peer.HasMessage());
55 63
56 // Remove two messages. 64 // Remove two messages.
57 Message* msg = queue.Dequeue(0); 65 Message* msg = queue.Dequeue();
58 EXPECT(msg != NULL); 66 EXPECT(msg != NULL);
59 EXPECT_STREQ("msg1", reinterpret_cast<char*>(msg->data())); 67 EXPECT_STREQ("msg1", reinterpret_cast<char*>(msg->data()));
60 EXPECT(queue_peer.HasMessage()); 68 EXPECT(queue_peer.HasMessage());
61 69
62 msg = queue.Dequeue(0); 70 msg = queue.Dequeue();
63 EXPECT(msg != NULL); 71 EXPECT(msg != NULL);
64 EXPECT_STREQ("msg2", reinterpret_cast<char*>(msg->data())); 72 EXPECT_STREQ("msg2", reinterpret_cast<char*>(msg->data()));
65 EXPECT(!queue_peer.HasMessage()); 73 EXPECT(!queue_peer.HasMessage());
66 74
67 delete msg1; 75 delete msg1;
68 delete msg2; 76 delete msg2;
69 } 77 }
70 78
71 79
72 TEST_CASE(MessageQueue_Priorities) { 80 TEST_CASE(MessageQueue_Priorities) {
73 MessageQueue queue; 81 MessageQueue queue;
74 MessageQueueTestPeer queue_peer(&queue); 82 MessageQueueTestPeer queue_peer(&queue);
75 EXPECT(!queue_peer.HasMessage()); 83 EXPECT(!queue_peer.HasMessage());
76 84
77 Dart_Port port = 1; 85 Dart_Port port = 1;
78 86
79 // Add two messages. 87 // Add two messages.
80 Message* msg1 = 88 Message* msg1 =
81 new Message(port, 0, AllocMsg("msg1"), Message::kNormalPriority); 89 new Message(port, 0, AllocMsg("msg1"), Message::kNormalPriority);
82 queue.Enqueue(msg1); 90 queue.Enqueue(msg1);
83 EXPECT(queue_peer.HasMessage()); 91 EXPECT(queue_peer.HasMessage());
84 92
85 Message* msg2 = 93 Message* msg2 =
86 new Message(port, 0, AllocMsg("msg2"), Message::kOOBPriority); 94 new Message(port, 0, AllocMsg("msg2"), Message::kOOBPriority);
87 95
88 queue.Enqueue(msg2); 96 queue.Enqueue(msg2);
89 EXPECT(queue_peer.HasMessage()); 97 EXPECT(queue_peer.HasMessage());
90 98
91 // The higher priority message is delivered first. 99 // The higher priority message is delivered first.
92 Message* msg = queue.Dequeue(0); 100 Message* msg = queue.Dequeue();
93 EXPECT(msg != NULL); 101 EXPECT(msg != NULL);
94 EXPECT_STREQ("msg2", reinterpret_cast<char*>(msg->data())); 102 EXPECT_STREQ("msg2", reinterpret_cast<char*>(msg->data()));
95 EXPECT(queue_peer.HasMessage()); 103 EXPECT(queue_peer.HasMessage());
96 104
97 msg = queue.Dequeue(0); 105 msg = queue.Dequeue();
98 EXPECT(msg != NULL); 106 EXPECT(msg != NULL);
99 EXPECT_STREQ("msg1", reinterpret_cast<char*>(msg->data())); 107 EXPECT_STREQ("msg1", reinterpret_cast<char*>(msg->data()));
100 EXPECT(!queue_peer.HasMessage()); 108 EXPECT(!queue_peer.HasMessage());
101 109
102 delete msg1; 110 delete msg1;
103 delete msg2; 111 delete msg2;
104 } 112 }
105 113
106 114
107 // A thread which receives an expected sequence of messages. 115 // A thread which receives an expected sequence of messages.
108 static Monitor* sync = NULL; 116 static Monitor* sync = NULL;
109 static MessageQueue* shared_queue = NULL; 117 static MessageHandler* shared_handler = NULL;
110 void MessageReceiver_start(uword unused) { 118 void MessageReceiver_start(uword unused) {
111 // We only need an isolate here because the MonitorLocker in the 119 // We only need an isolate here because the MonitorLocker in the
112 // MessageQueue expects it, we don't need to initialize the isolate 120 // MessageQueue expects it, we don't need to initialize the isolate
113 // as it does not run any dart code. 121 // as it does not run any dart code.
114 Dart::CreateIsolate(NULL); 122 Dart::CreateIsolate(NULL);
115 123
116 // Create a message queue and share it. 124 // Create a message handler and share it.
117 MessageQueue* queue = new MessageQueue(); 125 MessageHandler* handler = new MessageHandler();
118 MessageQueueTestPeer peer(queue); 126 MessageHandlerTestPeer handler_peer(handler);
119 shared_queue = queue; 127 MessageQueueTestPeer queue_peer(handler_peer.queue());
128 shared_handler = handler;
120 129
121 // Tell the other thread that the shared queue is ready. 130 // Tell the other thread that the shared queue is ready.
122 { 131 {
123 MonitorLocker ml(sync); 132 MonitorLocker ml(sync);
124 ml.Notify(); 133 ml.Notify();
125 } 134 }
126 135
127 // Wait for the other thread to fill the queue a bit. 136 // Wait for the other thread to fill the queue a bit.
128 while (!peer.HasMessage()) { 137 while (!queue_peer.HasMessage()) {
129 MonitorLocker ml(sync); 138 MonitorLocker ml(sync);
130 ml.Wait(5); 139 ml.Wait(5);
131 } 140 }
132 141
133 for (int i = 0; i < 3; i++) { 142 for (int i = 0; i < 3; i++) {
134 Message* msg = queue->Dequeue(0); 143 Message* msg = handler->Dequeue(0);
135 EXPECT(msg != NULL); 144 EXPECT(msg != NULL);
136 EXPECT_EQ(i + 10, msg->dest_port()); 145 EXPECT_EQ(i + 10, msg->dest_port());
137 EXPECT_EQ(i + 100, msg->reply_port()); 146 EXPECT_EQ(i + 100, msg->reply_port());
138 EXPECT_EQ(i + 1000, *(reinterpret_cast<int*>(msg->data()))); 147 EXPECT_EQ(i + 1000, *(reinterpret_cast<int*>(msg->data())));
139 delete msg; 148 delete msg;
140 } 149 }
141 for (int i = 0; i < 3; i++) { 150 for (int i = 0; i < 3; i++) {
142 Message* msg = queue->Dequeue(0); 151 Message* msg = handler->Dequeue(0);
143 EXPECT(msg != NULL); 152 EXPECT(msg != NULL);
144 EXPECT_EQ(i + 20, msg->dest_port()); 153 EXPECT_EQ(i + 20, msg->dest_port());
145 EXPECT_EQ(i + 200, msg->reply_port()); 154 EXPECT_EQ(i + 200, msg->reply_port());
146 EXPECT_EQ(i + 2000, *(reinterpret_cast<int*>(msg->data()))); 155 EXPECT_EQ(i + 2000, *(reinterpret_cast<int*>(msg->data())));
147 delete msg; 156 delete msg;
148 } 157 }
149 shared_queue = NULL; 158 shared_handler = NULL;
150 delete queue; 159 delete handler;
151 Dart::ShutdownIsolate(); 160 Dart::ShutdownIsolate();
152 } 161 }
153 162
154 163
155 TEST_CASE(MessageQueue_WaitNotify) { 164 TEST_CASE(MessageHandler_WaitNotify) {
156 sync = new Monitor(); 165 sync = new Monitor();
157 166
158 int result = Thread::Start(MessageReceiver_start, 0); 167 int result = Thread::Start(MessageReceiver_start, 0);
159 EXPECT_EQ(0, result); 168 EXPECT_EQ(0, result);
160 169
161 // Wait for the shared queue to be created. 170 // Wait for the shared handler to be created.
162 while (shared_queue == NULL) { 171 while (shared_handler == NULL) {
163 MonitorLocker ml(sync); 172 MonitorLocker ml(sync);
164 ml.Wait(5); 173 ml.Wait(5);
165 } 174 }
166 ASSERT(shared_queue != NULL); 175 ASSERT(shared_handler != NULL);
167 176
168 // Pile up three messages before the other thread runs. 177 // Pile up three messages before the other thread runs.
169 for (int i = 0; i < 3; i++) { 178 for (int i = 0; i < 3; i++) {
170 int* data = reinterpret_cast<int*>(malloc(sizeof(*data))); 179 int* data = reinterpret_cast<int*>(malloc(sizeof(*data)));
171 *data = i + 1000; 180 *data = i + 1000;
172 Message* msg = 181 Message* msg =
173 new Message(i + 10, i + 100, reinterpret_cast<uint8_t*>(data), 182 new Message(i + 10, i + 100, reinterpret_cast<uint8_t*>(data),
174 Message::kNormalPriority); 183 Message::kNormalPriority);
175 shared_queue->Enqueue(msg); 184 shared_handler->PostMessage(msg);
176 } 185 }
177 186
178 // Wake the other thread and have it start consuming messages. 187 // Wake the other thread and have it start consuming messages.
179 { 188 {
180 MonitorLocker ml(sync); 189 MonitorLocker ml(sync);
181 ml.Notify(); 190 ml.Notify();
182 } 191 }
183 192
184 // Add a few more messages after sleeping to allow the other thread 193 // Add a few more messages after sleeping to allow the other thread
185 // to potentially exercise the blocking code path in Dequeue. 194 // to potentially exercise the blocking code path in Dequeue.
186 OS::Sleep(5); 195 OS::Sleep(5);
187 for (int i = 0; i < 3; i++) { 196 for (int i = 0; i < 3; i++) {
188 int* data = reinterpret_cast<int*>(malloc(sizeof(*data))); 197 int* data = reinterpret_cast<int*>(malloc(sizeof(*data)));
189 *data = i + 2000; 198 *data = i + 2000;
190 Message* msg = 199 Message* msg =
191 new Message(i + 20, i + 200, reinterpret_cast<uint8_t*>(data), 200 new Message(i + 20, i + 200, reinterpret_cast<uint8_t*>(data),
192 Message::kNormalPriority); 201 Message::kNormalPriority);
193 shared_queue->Enqueue(msg); 202 shared_handler->PostMessage(msg);
194 } 203 }
195 204
196 sync = NULL; 205 sync = NULL;
197 delete sync; 206 delete sync;
198 207
199 // Give the spawned thread enough time to properly exit. 208 // Give the spawned thread enough time to properly exit.
200 OS::Sleep(20); 209 OS::Sleep(20);
201 } 210 }
202 211
203 212
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 queue.Enqueue(msg1); 244 queue.Enqueue(msg1);
236 Message* msg2 = 245 Message* msg2 =
237 new Message(port2, 0, AllocMsg("msg2"), Message::kNormalPriority); 246 new Message(port2, 0, AllocMsg("msg2"), Message::kNormalPriority);
238 queue.Enqueue(msg2); 247 queue.Enqueue(msg2);
239 EXPECT(queue_peer.HasMessage()); 248 EXPECT(queue_peer.HasMessage());
240 249
241 queue.Flush(port1); 250 queue.Flush(port1);
242 251
243 // One message is left in the queue. 252 // One message is left in the queue.
244 EXPECT(queue_peer.HasMessage()); 253 EXPECT(queue_peer.HasMessage());
245 Message* msg = queue.Dequeue(0); 254 Message* msg = queue.Dequeue();
246 EXPECT(msg != NULL); 255 EXPECT(msg != NULL);
247 EXPECT_STREQ("msg2", reinterpret_cast<char*>(msg->data())); 256 EXPECT_STREQ("msg2", reinterpret_cast<char*>(msg->data()));
248 257
249 EXPECT(!queue_peer.HasMessage()); 258 EXPECT(!queue_peer.HasMessage());
250 259
251 // msg1 is already deleted by Flush. 260 // msg1 is already deleted by Flush.
252 delete msg2; 261 delete msg2;
253 } 262 }
254 263
255 264
(...skipping 24 matching lines...) Expand all
280 Dart_Port port1 = 1; 289 Dart_Port port1 = 1;
281 290
282 EXPECT(!queue_peer.HasMessage()); 291 EXPECT(!queue_peer.HasMessage());
283 queue.Flush(port1); 292 queue.Flush(port1);
284 293
285 // Queue is still empty. 294 // Queue is still empty.
286 EXPECT(!queue_peer.HasMessage()); 295 EXPECT(!queue_peer.HasMessage());
287 } 296 }
288 297
289 } // namespace dart 298 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/message.cc ('k') | runtime/vm/native_message_handler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698