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

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

Issue 8297004: Allow embedders to provide custom message delivery for an isolate. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years, 2 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
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 "vm/assert.h" 5 #include "vm/assert.h"
6 #include "vm/message_queue.h"
7 #include "vm/os.h"
6 #include "vm/port.h" 8 #include "vm/port.h"
7 #include "vm/unit_test.h" 9 #include "vm/unit_test.h"
8 10
9 namespace dart { 11 namespace dart {
10 12
11 TEST_CASE(Port) {
12 const char* msg_data = "Hallo Velo!";
13 13
14 intptr_t port1 = PortMap::CreatePort(); 14 // Intercept the post message callback and just store a copy of the message.
15 intptr_t port2 = PortMap::CreatePort(); 15 static const int kMaxSavedMsg = 80;
16 EXPECT(port1 != port2); 16 static char saved_msg[kMaxSavedMsg];
17 static bool MyPostMessageCallback(Dart_Isolate dest_isolate,
18 Dart_Port dest_port,
19 Dart_Port reply_port,
20 Dart_Message dart_message) {
21 const char* msg = reinterpret_cast<char*>(dart_message);
22 OS::SNPrint(saved_msg, kMaxSavedMsg, "%s", msg);
23 bool result = (strcmp(msg, "fail") != 0);
24 free(dart_message);
25 return result;
26 }
17 27
18 PortMessage* msg1 = new PortMessage(port1, 0, strdup(msg_data));
19 EXPECT_EQ(true, PortMap::PostMessage(msg1));
20 PortMessage* msg = PortMap::ReceiveMessage(10);
21 EXPECT_EQ(port1, msg->dest_id());
22 EXPECT_EQ(msg1, msg);
23 delete msg1;
24 28
25 msg1 = new PortMessage(port2, 0, strdup(msg_data)); 29 // Intercept the close port callback and remember which port was closed.
26 EXPECT_EQ(true, PortMap::PostMessage(msg1)); 30 static Dart_Port saved_port = 0;
27 msg = PortMap::ReceiveMessage(10); 31 static void MyClosePortCallback(Dart_Isolate dart_isolate,
28 EXPECT_EQ(port2, msg->dest_id()); 32 Dart_Port port) {
29 EXPECT_EQ(msg1, msg); 33 saved_port = port;
30 delete msg1; 34 }
35
36
37 static void InitPortMapTest() {
38 Dart_SetPostMessageCallback(&MyPostMessageCallback);
39 Dart_SetClosePortCallback(&MyClosePortCallback);
40 saved_port = 0;
41 saved_msg[0] = '\0';
42 }
43
44
45 TEST_CASE(PortMap_CreateAndCloseOnePort) {
46 InitPortMapTest();
47 intptr_t port = PortMap::CreatePort();
48 EXPECT_NE(0, port);
49 EXPECT(PortMap::IsActivePort(port));
50
51 PortMap::ClosePort(port);
52 EXPECT(!PortMap::IsActivePort(port));
53
54 // Embedder was notified of port closure.
55 EXPECT_EQ(port, saved_port);
56 }
57
58
59 TEST_CASE(PortMap_CreateAndCloseTwoPorts) {
60 InitPortMapTest();
61 Dart_Port port1 = PortMap::CreatePort();
62 Dart_Port port2 = PortMap::CreatePort();
63 EXPECT(PortMap::IsActivePort(port1));
64 EXPECT(PortMap::IsActivePort(port2));
65
66 // Uniqueness.
67 EXPECT_NE(port1, port2);
31 68
32 PortMap::ClosePort(port1); 69 PortMap::ClosePort(port1);
33 EXPECT_EQ(false, PortMap::IsActivePort(port1)); 70 EXPECT(!PortMap::IsActivePort(port1));
34 msg1 = new PortMessage(port1, 0, strdup(msg_data)); 71 EXPECT(PortMap::IsActivePort(port2));
35 EXPECT_EQ(false, PortMap::PostMessage(msg1)); 72 EXPECT_EQ(port1, saved_port);
36 delete msg1;
37 EXPECT(PortMap::ReceiveMessage(10) == NULL);
38 73
39 EXPECT_EQ(true, PortMap::IsActivePort(port2));
40 msg1 = new PortMessage(port2, 0, strdup(msg_data));
41 EXPECT_EQ(true, PortMap::PostMessage(msg1));
42 PortMap::ClosePort(port2); 74 PortMap::ClosePort(port2);
43 EXPECT(PortMap::ReceiveMessage(10) == NULL); 75 EXPECT(!PortMap::IsActivePort(port1));
76 EXPECT(!PortMap::IsActivePort(port2));
77 EXPECT_EQ(port2, saved_port);
78 }
44 79
80
81 TEST_CASE(PortMap_ClosePorts) {
82 InitPortMapTest();
83 Dart_Port port1 = PortMap::CreatePort();
84 Dart_Port port2 = PortMap::CreatePort();
85 EXPECT(PortMap::IsActivePort(port1));
86 EXPECT(PortMap::IsActivePort(port2));
87
88 // Close all ports at once.
89 PortMap::ClosePorts();
90 EXPECT(!PortMap::IsActivePort(port1));
91 EXPECT(!PortMap::IsActivePort(port2));
92
93 // Embedder is notified to close all ports as well.
94 EXPECT_EQ(kCloseAllPorts, saved_port);
95 }
96
97
98 TEST_CASE(PortMap_CreateManyPorts) {
99 InitPortMapTest();
45 for (int i = 0; i < 32; i++) { 100 for (int i = 0; i < 32; i++) {
46 intptr_t port = PortMap::CreatePort(); 101 Dart_Port port = PortMap::CreatePort();
102 EXPECT(PortMap::IsActivePort(port));
47 PortMap::ClosePort(port); 103 PortMap::ClosePort(port);
104 EXPECT(!PortMap::IsActivePort(port));
48 } 105 }
49 } 106 }
50 107
51 108
109 TEST_CASE(PortMap_PostMessage) {
110 InitPortMapTest();
111 Dart_Port port = PortMap::CreatePort();
112 EXPECT(PortMap::PostMessage(
113 port, 0, reinterpret_cast<Dart_Message>(strdup("msg"))));
114
115 // Check that the post message callback was called.
116 EXPECT_STREQ("msg", saved_msg);
117 PortMap::ClosePorts();
118 }
119
120
121 TEST_CASE(PortMap_PostMessageInvalidPort) {
122 InitPortMapTest();
123 EXPECT(!PortMap::PostMessage(
124 0, 0, reinterpret_cast<Dart_Message>(strdup("msg"))));
125
126 // Check that the post message callback was not called.
127 EXPECT_STREQ("", saved_msg);
128 }
129
130
131 TEST_CASE(PortMap_PostMessageFailureInCallback) {
132 InitPortMapTest();
133 Dart_Port port = PortMap::CreatePort();
134
135 // Our callback is rigged to return false when it sees the message
136 // "fail". This return value is propagated out of PostMessage.
137 EXPECT(!PortMap::PostMessage(
138 port, 0, reinterpret_cast<Dart_Message>(strdup("fail"))));
139
140 // Check that the post message callback was called.
141 EXPECT_STREQ("fail", saved_msg);
142 PortMap::ClosePorts();
143 }
144
145
52 // End-of-test marker. 146 // End-of-test marker.
53 static const intptr_t kEOT = 0xFFFF; 147 static const intptr_t kEOT = 0xFFFF;
54 148
55 void* AllocIntData(intptr_t payload) { 149 void* AllocIntData(intptr_t payload) {
56 intptr_t* result = reinterpret_cast<intptr_t*>(malloc(sizeof(payload))); 150 intptr_t* result = reinterpret_cast<intptr_t*>(malloc(sizeof(payload)));
57 *result = payload; 151 *result = payload;
58 return result; 152 return result;
59 } 153 }
60 154
61 155
62 intptr_t GetIntData(void* data) { 156 intptr_t GetIntData(void* data) {
63 return *reinterpret_cast<intptr_t*>(data); 157 return *reinterpret_cast<intptr_t*>(data);
64 } 158 }
65 159
66 160
161 static PortMessage* NextMessage() {
162 Isolate* isolate = Isolate::Current();
163 PortMessage* result = isolate->message_queue()->Dequeue(0);
164 return result;
165 }
166
167
67 void ThreadedPort_start(uword parameter) { 168 void ThreadedPort_start(uword parameter) {
68 Dart::CreateIsolate(NULL, NULL); 169 Dart::CreateIsolate(NULL, NULL);
69 170
70 intptr_t remote = parameter; 171 intptr_t remote = parameter;
71 intptr_t local = PortMap::CreatePort(); 172 intptr_t local = PortMap::CreatePort();
72 173
73 PortMap::PostMessage(new PortMessage(remote, 0, AllocIntData(local))); 174 PortMap::PostMessage(remote, 0, AllocIntData(local));
74 175
75 intptr_t count = 0; 176 intptr_t count = 0;
76 while (true) { 177 while (true) {
77 PortMessage* msg = PortMap::ReceiveMessage(0); 178 PortMessage* msg = NextMessage();
78 EXPECT_EQ(local, msg->dest_id()); 179 EXPECT_EQ(local, msg->dest_port());
79 EXPECT(msg != NULL); 180 EXPECT(msg != NULL);
80 if (GetIntData(msg->data()) == kEOT) { 181 if (GetIntData(msg->data()) == kEOT) {
81 break; 182 break;
82 } 183 }
83 EXPECT(GetIntData(msg->data()) == count); 184 EXPECT(GetIntData(msg->data()) == count);
84 delete msg; 185 delete msg;
85 PortMap::PostMessage(new PortMessage(remote, 0, AllocIntData(count * 2))); 186 PortMap::PostMessage(remote, 0, AllocIntData(count * 2));
86 count++; 187 count++;
87 } 188 }
88 PortMap::PostMessage(new PortMessage(remote, 0, AllocIntData(kEOT))); 189 PortMap::PostMessage(remote, 0, AllocIntData(kEOT));
89 190
90 Dart::ShutdownIsolate(); 191 Dart::ShutdownIsolate();
91 } 192 }
92 193
93 194
94 TEST_CASE(ThreadedPort) { 195 TEST_CASE(ThreadedPort) {
95 intptr_t local = PortMap::CreatePort(); 196 intptr_t local = PortMap::CreatePort();
96 197
97 Thread* thr = new Thread(ThreadedPort_start, local); 198 Thread* thr = new Thread(ThreadedPort_start, local);
98 EXPECT(thr != NULL); 199 EXPECT(thr != NULL);
99 200
100 PortMessage* msg = PortMap::ReceiveMessage(0); 201 PortMessage* msg = NextMessage();
101 EXPECT_EQ(local, msg->dest_id()); 202 EXPECT_EQ(local, msg->dest_port());
102 EXPECT(msg != NULL); 203 EXPECT(msg != NULL);
103 intptr_t remote = GetIntData(msg->data()); // Get the remote port. 204 intptr_t remote = GetIntData(msg->data()); // Get the remote port.
104 delete msg; 205 delete msg;
105 206
106 for (intptr_t i = 0; i < 10; i++) { 207 for (intptr_t i = 0; i < 10; i++) {
107 PortMap::PostMessage(new PortMessage(remote, 0, AllocIntData(i))); 208 PortMap::PostMessage(remote, 0, AllocIntData(i));
108 PortMessage* msg = PortMap::ReceiveMessage(0); 209 PortMessage* msg = NextMessage();
109 EXPECT_EQ(local, msg->dest_id()); 210 EXPECT_EQ(local, msg->dest_port());
110 EXPECT(msg != NULL); 211 EXPECT(msg != NULL);
111 EXPECT_EQ(i * 2, GetIntData(msg->data())); 212 EXPECT_EQ(i * 2, GetIntData(msg->data()));
112 delete msg; 213 delete msg;
113 } 214 }
114 215
115 PortMap::PostMessage(new PortMessage(remote, 0, AllocIntData(kEOT))); 216 PortMap::PostMessage(remote, 0, AllocIntData(kEOT));
116 msg = PortMap::ReceiveMessage(0); 217 msg = NextMessage();
117 EXPECT_EQ(local, msg->dest_id()); 218 EXPECT_EQ(local, msg->dest_port());
118 EXPECT(msg != NULL); 219 EXPECT(msg != NULL);
119 EXPECT_EQ(kEOT, GetIntData(msg->data())); 220 EXPECT_EQ(kEOT, GetIntData(msg->data()));
120 delete msg; 221 delete msg;
121 222
122 // Give the spawned thread enough time to properly exit. 223 // Give the spawned thread enough time to properly exit.
123 Monitor* waiter = new Monitor(); 224 Monitor* waiter = new Monitor();
124 { 225 {
125 MonitorLocker ml(waiter); 226 MonitorLocker ml(waiter);
126 ml.Wait(20); 227 ml.Wait(20);
127 } 228 }
128 delete waiter; 229 delete waiter;
129 } 230 }
130 231
131 } // namespace dart 232 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698