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

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

Issue 9169063: Add support for native ports in the vm. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 8 years, 10 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/vm_sources.gypi » ('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_queue.h" 6 #include "vm/message.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 // Intercept the post message callback and just store a copy of the message. 32 class TestMessageHandler : public MessageHandler {
33 static int notify_count = 0; 33 public:
34 static void MyMessageNotifyCallback(Dart_Isolate dest_isolate) { 34 TestMessageHandler() : notify_count(0) {}
35 notify_count++;
36 }
37 35
36 void MessageNotify(Message::Priority priority) {
37 notify_count++;
38 }
38 39
39 static void InitPortMapTest() { 40 int notify_count;
40 Dart_SetMessageNotifyCallback(&MyMessageNotifyCallback); 41 };
41 notify_count = 0;
42 }
43 42
44 43
45 TEST_CASE(PortMap_CreateAndCloseOnePort) { 44 TEST_CASE(PortMap_CreateAndCloseOnePort) {
46 InitPortMapTest(); 45 TestMessageHandler handler;
47 intptr_t port = PortMap::CreatePort(); 46 intptr_t port = PortMap::CreatePort(&handler);
48 EXPECT_NE(0, port); 47 EXPECT_NE(0, port);
49 EXPECT(PortMapTestPeer::IsActivePort(port)); 48 EXPECT(PortMapTestPeer::IsActivePort(port));
50 49
51 PortMap::ClosePort(port); 50 PortMap::ClosePort(port);
52 EXPECT(!PortMapTestPeer::IsActivePort(port)); 51 EXPECT(!PortMapTestPeer::IsActivePort(port));
53 } 52 }
54 53
55 54
56 TEST_CASE(PortMap_CreateAndCloseTwoPorts) { 55 TEST_CASE(PortMap_CreateAndCloseTwoPorts) {
57 InitPortMapTest(); 56 TestMessageHandler handler;
58 Dart_Port port1 = PortMap::CreatePort(); 57 Dart_Port port1 = PortMap::CreatePort(&handler);
59 Dart_Port port2 = PortMap::CreatePort(); 58 Dart_Port port2 = PortMap::CreatePort(&handler);
60 EXPECT(PortMapTestPeer::IsActivePort(port1)); 59 EXPECT(PortMapTestPeer::IsActivePort(port1));
61 EXPECT(PortMapTestPeer::IsActivePort(port2)); 60 EXPECT(PortMapTestPeer::IsActivePort(port2));
62 61
63 // Uniqueness. 62 // Uniqueness.
64 EXPECT_NE(port1, port2); 63 EXPECT_NE(port1, port2);
65 64
66 PortMap::ClosePort(port1); 65 PortMap::ClosePort(port1);
67 EXPECT(!PortMapTestPeer::IsActivePort(port1)); 66 EXPECT(!PortMapTestPeer::IsActivePort(port1));
68 EXPECT(PortMapTestPeer::IsActivePort(port2)); 67 EXPECT(PortMapTestPeer::IsActivePort(port2));
69 68
70 PortMap::ClosePort(port2); 69 PortMap::ClosePort(port2);
71 EXPECT(!PortMapTestPeer::IsActivePort(port1)); 70 EXPECT(!PortMapTestPeer::IsActivePort(port1));
72 EXPECT(!PortMapTestPeer::IsActivePort(port2)); 71 EXPECT(!PortMapTestPeer::IsActivePort(port2));
73 } 72 }
74 73
75 74
76 TEST_CASE(PortMap_ClosePorts) { 75 TEST_CASE(PortMap_ClosePorts) {
77 InitPortMapTest(); 76 TestMessageHandler handler;
78 Dart_Port port1 = PortMap::CreatePort(); 77 Dart_Port port1 = PortMap::CreatePort(&handler);
79 Dart_Port port2 = PortMap::CreatePort(); 78 Dart_Port port2 = PortMap::CreatePort(&handler);
80 EXPECT(PortMapTestPeer::IsActivePort(port1)); 79 EXPECT(PortMapTestPeer::IsActivePort(port1));
81 EXPECT(PortMapTestPeer::IsActivePort(port2)); 80 EXPECT(PortMapTestPeer::IsActivePort(port2));
82 81
83 // Close all ports at once. 82 // Close all ports at once.
84 PortMap::ClosePorts(); 83 PortMap::ClosePorts(&handler);
85 EXPECT(!PortMapTestPeer::IsActivePort(port1)); 84 EXPECT(!PortMapTestPeer::IsActivePort(port1));
86 EXPECT(!PortMapTestPeer::IsActivePort(port2)); 85 EXPECT(!PortMapTestPeer::IsActivePort(port2));
87 } 86 }
88 87
89 88
90 TEST_CASE(PortMap_CreateManyPorts) { 89 TEST_CASE(PortMap_CreateManyPorts) {
91 InitPortMapTest(); 90 TestMessageHandler handler;
92 for (int i = 0; i < 32; i++) { 91 for (int i = 0; i < 32; i++) {
93 Dart_Port port = PortMap::CreatePort(); 92 Dart_Port port = PortMap::CreatePort(&handler);
94 EXPECT(PortMapTestPeer::IsActivePort(port)); 93 EXPECT(PortMapTestPeer::IsActivePort(port));
95 PortMap::ClosePort(port); 94 PortMap::ClosePort(port);
96 EXPECT(!PortMapTestPeer::IsActivePort(port)); 95 EXPECT(!PortMapTestPeer::IsActivePort(port));
97 } 96 }
98 } 97 }
99 98
100 99
101 TEST_CASE(PortMap_SetLive) { 100 TEST_CASE(PortMap_SetLive) {
102 InitPortMapTest(); 101 TestMessageHandler handler;
103 intptr_t port = PortMap::CreatePort(); 102 intptr_t port = PortMap::CreatePort(&handler);
104 EXPECT_NE(0, port); 103 EXPECT_NE(0, port);
105 EXPECT(PortMapTestPeer::IsActivePort(port)); 104 EXPECT(PortMapTestPeer::IsActivePort(port));
106 EXPECT(!PortMapTestPeer::IsLivePort(port)); 105 EXPECT(!PortMapTestPeer::IsLivePort(port));
107 106
108 PortMap::SetLive(port); 107 PortMap::SetLive(port);
109 EXPECT(PortMapTestPeer::IsActivePort(port)); 108 EXPECT(PortMapTestPeer::IsActivePort(port));
110 EXPECT(PortMapTestPeer::IsLivePort(port)); 109 EXPECT(PortMapTestPeer::IsLivePort(port));
111 110
112 PortMap::ClosePort(port); 111 PortMap::ClosePort(port);
113 EXPECT(!PortMapTestPeer::IsActivePort(port)); 112 EXPECT(!PortMapTestPeer::IsActivePort(port));
114 EXPECT(!PortMapTestPeer::IsLivePort(port)); 113 EXPECT(!PortMapTestPeer::IsLivePort(port));
115 } 114 }
116 115
117 116
118 TEST_CASE(PortMap_PostMessage) { 117 TEST_CASE(PortMap_PostMessage) {
119 InitPortMapTest(); 118 TestMessageHandler handler;
120 Dart_Port port = PortMap::CreatePort(); 119 Dart_Port port = PortMap::CreatePort(&handler);
120 EXPECT_EQ(0, handler.notify_count);
121
121 EXPECT(PortMap::PostMessage(new Message( 122 EXPECT(PortMap::PostMessage(new Message(
122 port, 0, reinterpret_cast<uint8_t*>(strdup("msg")), 123 port, 0, reinterpret_cast<uint8_t*>(strdup("msg")),
123 Message::kNormalPriority))); 124 Message::kNormalPriority)));
124 125
125 // Check that the message notify callback was called. 126 // Check that the message notify callback was called.
126 EXPECT_EQ(1, notify_count); 127 EXPECT_EQ(1, handler.notify_count);
127 PortMap::ClosePorts(); 128 PortMap::ClosePorts(&handler);
128 } 129 }
129 130
130 131
131 TEST_CASE(PortMap_PostMessageInvalidPort) { 132 TEST_CASE(PortMap_PostMessageInvalidPort) {
132 InitPortMapTest();
133 EXPECT(!PortMap::PostMessage(new Message( 133 EXPECT(!PortMap::PostMessage(new Message(
134 0, 0, reinterpret_cast<uint8_t*>(strdup("msg")), 134 0, 0, reinterpret_cast<uint8_t*>(strdup("msg")),
135 Message::kNormalPriority))); 135 Message::kNormalPriority)));
136
137 // Check that the message notifycallback was not called.
138 EXPECT_STREQ(0, notify_count);
139 } 136 }
140 137
141 138
142 // End-of-test marker. 139 // End-of-test marker.
143 static const intptr_t kEOT = 0xFFFF; 140 static const intptr_t kEOT = 0xFFFF;
144 141
145 142
146 uint8_t* AllocIntData(intptr_t payload) { 143 uint8_t* AllocIntData(intptr_t payload) {
147 intptr_t* result = reinterpret_cast<intptr_t*>(malloc(sizeof(payload))); 144 intptr_t* result = reinterpret_cast<intptr_t*>(malloc(sizeof(payload)));
148 *result = payload; 145 *result = payload;
149 return reinterpret_cast<uint8_t*>(result); 146 return reinterpret_cast<uint8_t*>(result);
150 } 147 }
151 148
152 149
153 intptr_t GetIntData(uint8_t* data) { 150 intptr_t GetIntData(uint8_t* data) {
154 return *reinterpret_cast<intptr_t*>(data); 151 return *reinterpret_cast<intptr_t*>(data);
155 } 152 }
156 153
157 154
158 static Message* NextMessage() { 155 static Message* NextMessage() {
159 Isolate* isolate = Isolate::Current(); 156 Isolate* isolate = Isolate::Current();
160 Message* result = isolate->message_queue()->Dequeue(0); 157 Message* result = isolate->message_handler()->queue()->Dequeue(0);
161 return result; 158 return result;
162 } 159 }
163 160
164 161
165 void ThreadedPort_start(uword parameter) { 162 void ThreadedPort_start(uword parameter) {
166 // We only need an isolate here because the MutexLocker in 163 // TODO(turnidge): We only use the isolate to get access to its
167 // PortMap::CreatePort expects it, we don't need to initialize 164 // message handler. I should rewrite this test to use a
168 // the isolate as it does not run any dart code. 165 // TestMessageHandler instead.
169 Dart::CreateIsolate(NULL); 166 Isolate* isolate = Dart::CreateIsolate(NULL);
170 167
171 intptr_t remote = parameter; 168 intptr_t remote = parameter;
172 intptr_t local = PortMap::CreatePort(); 169 intptr_t local = PortMap::CreatePort(isolate->message_handler());
173 170
174 PortMap::PostMessage(new Message( 171 PortMap::PostMessage(new Message(
175 remote, 0, AllocIntData(local), Message::kNormalPriority)); 172 remote, 0, AllocIntData(local), Message::kNormalPriority));
176 intptr_t count = 0; 173 intptr_t count = 0;
177 while (true) { 174 while (true) {
178 Message* msg = NextMessage(); 175 Message* msg = NextMessage();
179 EXPECT_EQ(local, msg->dest_port()); 176 EXPECT_EQ(local, msg->dest_port());
180 EXPECT(msg != NULL); 177 EXPECT(msg != NULL);
181 if (GetIntData(msg->data()) == kEOT) { 178 if (GetIntData(msg->data()) == kEOT) {
182 break; 179 break;
183 } 180 }
184 EXPECT(GetIntData(msg->data()) == count); 181 EXPECT(GetIntData(msg->data()) == count);
185 delete msg; 182 delete msg;
186 PortMap::PostMessage(new Message( 183 PortMap::PostMessage(new Message(
187 remote, 0, AllocIntData(count * 2), Message::kNormalPriority)); 184 remote, 0, AllocIntData(count * 2), Message::kNormalPriority));
188 count++; 185 count++;
189 } 186 }
190 PortMap::PostMessage(new Message( 187 PortMap::PostMessage(new Message(
191 remote, 0, AllocIntData(kEOT), Message::kNormalPriority)); 188 remote, 0, AllocIntData(kEOT), Message::kNormalPriority));
192 Dart::ShutdownIsolate(); 189 Dart::ShutdownIsolate();
193 } 190 }
194 191
195 192
196 TEST_CASE(ThreadedPort) { 193 TEST_CASE(ThreadedPort) {
197 intptr_t local = PortMap::CreatePort(); 194 intptr_t local = PortMap::CreatePort(Isolate::Current()->message_handler());
198 195
199 Thread* thr = new Thread(ThreadedPort_start, local); 196 Thread* thr = new Thread(ThreadedPort_start, local);
200 EXPECT(thr != NULL); 197 EXPECT(thr != NULL);
201 198
202 Message* msg = NextMessage(); 199 Message* msg = NextMessage();
203 EXPECT_EQ(local, msg->dest_port()); 200 EXPECT_EQ(local, msg->dest_port());
204 EXPECT(msg != NULL); 201 EXPECT(msg != NULL);
205 intptr_t remote = GetIntData(msg->data()); // Get the remote port. 202 intptr_t remote = GetIntData(msg->data()); // Get the remote port.
206 delete msg; 203 delete msg;
207 204
(...skipping 18 matching lines...) Expand all
226 // Give the spawned thread enough time to properly exit. 223 // Give the spawned thread enough time to properly exit.
227 Monitor* waiter = new Monitor(); 224 Monitor* waiter = new Monitor();
228 { 225 {
229 MonitorLocker ml(waiter); 226 MonitorLocker ml(waiter);
230 ml.Wait(20); 227 ml.Wait(20);
231 } 228 }
232 delete waiter; 229 delete waiter;
233 } 230 }
234 231
235 } // namespace dart 232 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/port.cc ('k') | runtime/vm/vm_sources.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698