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

Side by Side Diff: runtime/vm/port_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
« no previous file with comments | « runtime/vm/port.cc ('k') | runtime/vm/thread_pool.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_handler.h"
7 #include "vm/os.h" 7 #include "vm/os.h"
8 #include "vm/port.h" 8 #include "vm/port.h"
9 #include "vm/unit_test.h" 9 #include "vm/unit_test.h"
10 10
11 namespace dart { 11 namespace dart {
12 12
13 // Provides private access to PortMap for testing. 13 // Provides private access to PortMap for testing.
14 class PortMapTestPeer { 14 class PortMapTestPeer {
15 public: 15 public:
16 static bool IsActivePort(Dart_Port port) { 16 static bool IsActivePort(Dart_Port port) {
17 MutexLocker ml(PortMap::mutex_); 17 MutexLocker ml(PortMap::mutex_);
18 return (PortMap::FindPort(port) >= 0); 18 return (PortMap::FindPort(port) >= 0);
19 } 19 }
20 20
21 static bool IsLivePort(Dart_Port port) { 21 static bool IsLivePort(Dart_Port port) {
22 MutexLocker ml(PortMap::mutex_); 22 MutexLocker ml(PortMap::mutex_);
23 intptr_t index = PortMap::FindPort(port); 23 intptr_t index = PortMap::FindPort(port);
24 if (index < 0) { 24 if (index < 0) {
25 return false; 25 return false;
26 } 26 }
27 return PortMap::map_[index].live; 27 return PortMap::map_[index].live;
28 } 28 }
29 }; 29 };
30 30
31 31
32 class TestMessageHandler : public MessageHandler { 32 class PortTestMessageHandler : public MessageHandler {
33 public: 33 public:
34 TestMessageHandler() : notify_count(0) {} 34 PortTestMessageHandler() : notify_count(0) {}
35 35
36 void MessageNotify(Message::Priority priority) { 36 void MessageNotify(Message::Priority priority) {
37 notify_count++; 37 notify_count++;
38 } 38 }
39 39
40 bool HandleMessage(Message* message) { return true; }
41
40 int notify_count; 42 int notify_count;
41 }; 43 };
42 44
43 45
44 TEST_CASE(PortMap_CreateAndCloseOnePort) { 46 TEST_CASE(PortMap_CreateAndCloseOnePort) {
45 TestMessageHandler handler; 47 PortTestMessageHandler handler;
46 intptr_t port = PortMap::CreatePort(&handler); 48 intptr_t port = PortMap::CreatePort(&handler);
47 EXPECT_NE(0, port); 49 EXPECT_NE(0, port);
48 EXPECT(PortMapTestPeer::IsActivePort(port)); 50 EXPECT(PortMapTestPeer::IsActivePort(port));
49 51
50 PortMap::ClosePort(port); 52 PortMap::ClosePort(port);
51 EXPECT(!PortMapTestPeer::IsActivePort(port)); 53 EXPECT(!PortMapTestPeer::IsActivePort(port));
52 } 54 }
53 55
54 56
55 TEST_CASE(PortMap_CreateAndCloseTwoPorts) { 57 TEST_CASE(PortMap_CreateAndCloseTwoPorts) {
56 TestMessageHandler handler; 58 PortTestMessageHandler handler;
57 Dart_Port port1 = PortMap::CreatePort(&handler); 59 Dart_Port port1 = PortMap::CreatePort(&handler);
58 Dart_Port port2 = PortMap::CreatePort(&handler); 60 Dart_Port port2 = PortMap::CreatePort(&handler);
59 EXPECT(PortMapTestPeer::IsActivePort(port1)); 61 EXPECT(PortMapTestPeer::IsActivePort(port1));
60 EXPECT(PortMapTestPeer::IsActivePort(port2)); 62 EXPECT(PortMapTestPeer::IsActivePort(port2));
61 63
62 // Uniqueness. 64 // Uniqueness.
63 EXPECT_NE(port1, port2); 65 EXPECT_NE(port1, port2);
64 66
65 PortMap::ClosePort(port1); 67 PortMap::ClosePort(port1);
66 EXPECT(!PortMapTestPeer::IsActivePort(port1)); 68 EXPECT(!PortMapTestPeer::IsActivePort(port1));
67 EXPECT(PortMapTestPeer::IsActivePort(port2)); 69 EXPECT(PortMapTestPeer::IsActivePort(port2));
68 70
69 PortMap::ClosePort(port2); 71 PortMap::ClosePort(port2);
70 EXPECT(!PortMapTestPeer::IsActivePort(port1)); 72 EXPECT(!PortMapTestPeer::IsActivePort(port1));
71 EXPECT(!PortMapTestPeer::IsActivePort(port2)); 73 EXPECT(!PortMapTestPeer::IsActivePort(port2));
72 } 74 }
73 75
74 76
75 TEST_CASE(PortMap_ClosePorts) { 77 TEST_CASE(PortMap_ClosePorts) {
76 TestMessageHandler handler; 78 PortTestMessageHandler handler;
77 Dart_Port port1 = PortMap::CreatePort(&handler); 79 Dart_Port port1 = PortMap::CreatePort(&handler);
78 Dart_Port port2 = PortMap::CreatePort(&handler); 80 Dart_Port port2 = PortMap::CreatePort(&handler);
79 EXPECT(PortMapTestPeer::IsActivePort(port1)); 81 EXPECT(PortMapTestPeer::IsActivePort(port1));
80 EXPECT(PortMapTestPeer::IsActivePort(port2)); 82 EXPECT(PortMapTestPeer::IsActivePort(port2));
81 83
82 // Close all ports at once. 84 // Close all ports at once.
83 PortMap::ClosePorts(&handler); 85 PortMap::ClosePorts(&handler);
84 EXPECT(!PortMapTestPeer::IsActivePort(port1)); 86 EXPECT(!PortMapTestPeer::IsActivePort(port1));
85 EXPECT(!PortMapTestPeer::IsActivePort(port2)); 87 EXPECT(!PortMapTestPeer::IsActivePort(port2));
86 } 88 }
87 89
88 90
89 TEST_CASE(PortMap_CreateManyPorts) { 91 TEST_CASE(PortMap_CreateManyPorts) {
90 TestMessageHandler handler; 92 PortTestMessageHandler handler;
91 for (int i = 0; i < 32; i++) { 93 for (int i = 0; i < 32; i++) {
92 Dart_Port port = PortMap::CreatePort(&handler); 94 Dart_Port port = PortMap::CreatePort(&handler);
93 EXPECT(PortMapTestPeer::IsActivePort(port)); 95 EXPECT(PortMapTestPeer::IsActivePort(port));
94 PortMap::ClosePort(port); 96 PortMap::ClosePort(port);
95 EXPECT(!PortMapTestPeer::IsActivePort(port)); 97 EXPECT(!PortMapTestPeer::IsActivePort(port));
96 } 98 }
97 } 99 }
98 100
99 101
100 TEST_CASE(PortMap_SetLive) { 102 TEST_CASE(PortMap_SetLive) {
101 TestMessageHandler handler; 103 PortTestMessageHandler handler;
102 intptr_t port = PortMap::CreatePort(&handler); 104 intptr_t port = PortMap::CreatePort(&handler);
103 EXPECT_NE(0, port); 105 EXPECT_NE(0, port);
104 EXPECT(PortMapTestPeer::IsActivePort(port)); 106 EXPECT(PortMapTestPeer::IsActivePort(port));
105 EXPECT(!PortMapTestPeer::IsLivePort(port)); 107 EXPECT(!PortMapTestPeer::IsLivePort(port));
106 108
107 PortMap::SetLive(port); 109 PortMap::SetLive(port);
108 EXPECT(PortMapTestPeer::IsActivePort(port)); 110 EXPECT(PortMapTestPeer::IsActivePort(port));
109 EXPECT(PortMapTestPeer::IsLivePort(port)); 111 EXPECT(PortMapTestPeer::IsLivePort(port));
110 112
111 PortMap::ClosePort(port); 113 PortMap::ClosePort(port);
112 EXPECT(!PortMapTestPeer::IsActivePort(port)); 114 EXPECT(!PortMapTestPeer::IsActivePort(port));
113 EXPECT(!PortMapTestPeer::IsLivePort(port)); 115 EXPECT(!PortMapTestPeer::IsLivePort(port));
114 } 116 }
115 117
116 118
117 TEST_CASE(PortMap_PostMessage) { 119 TEST_CASE(PortMap_PostMessage) {
118 TestMessageHandler handler; 120 PortTestMessageHandler handler;
119 Dart_Port port = PortMap::CreatePort(&handler); 121 Dart_Port port = PortMap::CreatePort(&handler);
120 EXPECT_EQ(0, handler.notify_count); 122 EXPECT_EQ(0, handler.notify_count);
121 123
122 EXPECT(PortMap::PostMessage(new Message( 124 EXPECT(PortMap::PostMessage(new Message(
123 port, 0, reinterpret_cast<uint8_t*>(strdup("msg")), 125 port, 0, reinterpret_cast<uint8_t*>(strdup("msg")),
124 Message::kNormalPriority))); 126 Message::kNormalPriority)));
125 127
126 // Check that the message notify callback was called. 128 // Check that the message notify callback was called.
127 EXPECT_EQ(1, handler.notify_count); 129 EXPECT_EQ(1, handler.notify_count);
128 PortMap::ClosePorts(&handler); 130 PortMap::ClosePorts(&handler);
129 } 131 }
130 132
131 133
132 TEST_CASE(PortMap_PostMessageInvalidPort) { 134 TEST_CASE(PortMap_PostMessageInvalidPort) {
133 EXPECT(!PortMap::PostMessage(new Message( 135 EXPECT(!PortMap::PostMessage(new Message(
134 0, 0, reinterpret_cast<uint8_t*>(strdup("msg")), 136 0, 0, reinterpret_cast<uint8_t*>(strdup("msg")),
135 Message::kNormalPriority))); 137 Message::kNormalPriority)));
136 } 138 }
137 139
138
139 // End-of-test marker.
140 static const intptr_t kEOT = 0xFFFF;
141
142
143 uint8_t* AllocIntData(intptr_t payload) {
144 intptr_t* result = reinterpret_cast<intptr_t*>(malloc(sizeof(payload)));
145 *result = payload;
146 return reinterpret_cast<uint8_t*>(result);
147 }
148
149
150 intptr_t GetIntData(uint8_t* data) {
151 return *reinterpret_cast<intptr_t*>(data);
152 }
153
154
155 static Message* NextMessage() {
156 Isolate* isolate = Isolate::Current();
157 Message* result = isolate->message_handler()->queue()->Dequeue(0);
158 return result;
159 }
160
161
162 void ThreadedPort_start(uword parameter) {
163 // TODO(turnidge): We only use the isolate to get access to its
164 // message handler. I should rewrite this test to use a
165 // TestMessageHandler instead.
166 Isolate* isolate = Dart::CreateIsolate(NULL);
167
168 intptr_t remote = parameter;
169 intptr_t local = PortMap::CreatePort(isolate->message_handler());
170
171 PortMap::PostMessage(new Message(
172 remote, 0, AllocIntData(local), Message::kNormalPriority));
173 intptr_t count = 0;
174 while (true) {
175 Message* msg = NextMessage();
176 EXPECT_EQ(local, msg->dest_port());
177 EXPECT(msg != NULL);
178 if (GetIntData(msg->data()) == kEOT) {
179 break;
180 }
181 EXPECT(GetIntData(msg->data()) == count);
182 delete msg;
183 PortMap::PostMessage(new Message(
184 remote, 0, AllocIntData(count * 2), Message::kNormalPriority));
185 count++;
186 }
187 PortMap::PostMessage(new Message(
188 remote, 0, AllocIntData(kEOT), Message::kNormalPriority));
189 Dart::ShutdownIsolate();
190 }
191
192
193 TEST_CASE(ThreadedPort) {
194 intptr_t local = PortMap::CreatePort(Isolate::Current()->message_handler());
195
196 int result = Thread::Start(ThreadedPort_start, local);
197 EXPECT_EQ(0, result);
198
199 Message* msg = NextMessage();
200 EXPECT_EQ(local, msg->dest_port());
201 EXPECT(msg != NULL);
202 intptr_t remote = GetIntData(msg->data()); // Get the remote port.
203 delete msg;
204
205 for (intptr_t i = 0; i < 10; i++) {
206 PortMap::PostMessage(
207 new Message(remote, 0, AllocIntData(i), Message::kNormalPriority));
208 Message* msg = NextMessage();
209 EXPECT_EQ(local, msg->dest_port());
210 EXPECT(msg != NULL);
211 EXPECT_EQ(i * 2, GetIntData(msg->data()));
212 delete msg;
213 }
214
215 PortMap::PostMessage(
216 new Message(remote, 0, AllocIntData(kEOT), Message::kNormalPriority));
217 msg = NextMessage();
218 EXPECT_EQ(local, msg->dest_port());
219 EXPECT(msg != NULL);
220 EXPECT_EQ(kEOT, GetIntData(msg->data()));
221 delete msg;
222
223 // Give the spawned thread enough time to properly exit.
224 Monitor* waiter = new Monitor();
225 {
226 MonitorLocker ml(waiter);
227 ml.Wait(20);
228 }
229 delete waiter;
230 }
231
232 } // namespace dart 140 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/port.cc ('k') | runtime/vm/thread_pool.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698