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

Side by Side Diff: tests/isolate/function_send_test.dart

Issue 584843003: Allow sending static/top-level functions through ports and as isolate (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 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 | « sdk/lib/_internal/compiler/js_lib/isolate_helper.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2014, 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 import "dart:isolate";
6 import "dart:async";
7 import "package:expect/expect.dart";
8 import "package:async_helper/async_helper.dart";
9
10 void toplevel(port, message) { port.send("toplevel:$message"); }
11 void mkToplevelFunc() => (p, m) { p.send(m); };
floitsch 2014/09/19 19:52:45 mkFuncToplevel or funcGeneratorToplevel
Lasse Reichstein Nielsen 2014/09/23 07:25:07 I'll go for createFuncToplevel.
12 class C {
13 Function initializer;
14 Function body;
15 C() : initializer = ((p, m) { throw "initializer"; }) {
16 body = (p, m) { throw "body"; };
17 }
18 static void staticFunc(port, message) { port.send("static:$message"); }
19 static Function mkStaticFunc() => (p, m) { throw "static expr"; };
20 void member(p, m) { throw "member"; }
21 void mkFunc() => (p, m) { throw "instance expr"; };
22 void call(n, p) { throw "C"; }
23 }
24
25 class Callable {
26 void call(p, m) { p.send(["callable", m]); }
27 }
28
29
30 void main() {
31 asyncStart();
32
33 // Sendables are top-level functions and static functions only.
34 testSendable("toplevel", toplevel);
35 testSendable("static", C.staticFunc);
36
37 // Unsendables are any closure - instance methods or function expression.
38 var c = new C();
39 testUnsendable("instance method", c.member);
40 testUnsendable("static context expression", mkToplevelFunc());
41 testUnsendable("static context expression", C.mkStaticFunc());
42 testUnsendable("initializer context expression", c.initializer);
43 testUnsendable("constructor context expression", c.body);
44 testUnsendable("instance method context expression", c.mkFunc());
45
46 // Actually allowed. Identical in VM, different, but still static, in dart2js.
floitsch 2014/09/19 19:52:45 If it's allowed, why is it commented?
Lasse Reichstein Nielsen 2014/09/23 07:25:07 I can't say whether it should be allowed or not, a
47 // testUnsendable("toplevel.call closure", toplevel.call);
48 // testUnsendable("static.call closure", C.staticFunc.call);
49
50 // Callable objects are sendable if general objects are (VM yes, dart2js no).
51 //testSendable("callable object", new Callable()); /// 01: ok
floitsch 2014/09/19 19:52:45 Why is it commented? Especially with "/// 01: ok".
Lasse Reichstein Nielsen 2014/09/23 07:25:07 Again I can't decide on whether it should be one o
52 testUnsendable("callable object", new Callable()); /// 02: ok
floitsch 2014/09/19 19:52:45 That looks like the same as above...
Lasse Reichstein Nielsen 2014/09/23 07:25:07 This one is test*Un*sendablem the one above is tes
53 testUnsendable("callable object", new Callable().call);
54 asyncEnd();
55 return;
56 }
57
58 // Create a receive port that expects exactly one message.
59 // Pass the message to `callback` and return the sendPort.
60 void singleMessagePort(callback) {
61 var p;
62 p = new RawReceivePort((v) { p.close(); callback(v); });
63 return p.sendPort;
64 }
65
66 // A singleMessagePort that expects the message to be a specific value.
67 void expectMessagePort(message) {
68 asyncStart();
69 return singleMessagePort((v) {
70 Expect.equals(message, v);
71 asyncEnd();
72 });
73 }
74
75 void testSendable(name, func) {
76 // Function as spawn message.
77 Isolate.spawn(callFunc, [func, expectMessagePort("$name:spawn"), "spawn"]);
78
79 // Send function to same isolate.
80 var reply = expectMessagePort("$name:direct");
81 singleMessagePort(callFunc).send([func, reply, "direct"]);
82
83 // Send function to other isolate, call it there.
84 reply = expectMessagePort("$name:other isolate");
85 callPort().then((p) {
86 p.send([func, reply, "other isolate"]);
87 });
88
89 // Round-trip function trough other isolate.
90 echoPort((roundtripFunc) {
91 Expect.identical(func, roundtripFunc, "$name:send through isolate");
92 }).then((port) { port.send(func); });
93 }
94
95 // Creates a new isolate and a pair of ports that expect a single message
96 // to be sent to the other isolate and back to the callback function.
97 Future<SendPort> echoPort(callback(value)) {
98 Completer completer = new Completer<SendPort>();
99 SendPort replyPort = singleMessagePort(callback);
100 RawReceivePort initPort;
101 initPort = new RawReceivePort((p) {
102 completer.complete(p);
103 initPort.close();
104 });
105 return Isolate.spawn(_echo, [replyPort, initPort.sendPort])
106 .then((isolate) => completer.future);
107 }
108
109 void _echo(msg) {
110 var replyPort = msg[0];
111 RawReceivePort requestPort;
112 requestPort = new RawReceivePort((msg) {
113 replyPort.send(msg);
114 requestPort.close(); // Single echo only.
115 });
116 msg[1].send(requestPort.sendPort);
117 }
118
119 // Creates other isolate that waits for a single message, `msg`, on the returned
120 // port, and executes it as `msg[0](msg[1],msg[2])` in the other isolate.
121 Future<SendPort> callPort() {
122 Completer completer = new Completer<SendPort>();
123 SendPort initPort = singleMessagePort(completer.complete);
124 return Isolate.spawn(_call, initPort)
125 .then((_) => completer.future);
126 }
127
128 void _call(initPort) {
129 initPort.send(singleMessagePort(callFunc));
130 }
131 // Expect.throws(() {
132 // noReply.sendPort.send([func]);
133 // }, null, "send wrapped");
134
135
136 void testUnsendable(name, func) {
137 asyncStart();
138 Isolate.spawn(nop, func).then((v) => throw "allowed spawn direct?",
139 onError: (e,s){ asyncEnd(); });
140 asyncStart();
141 Isolate.spawn(nop, [func]).then((v) => throw "allowed spawn wrapped?",
142 onError: (e,s){ asyncEnd(); });
143
144 asyncStart();
145 var noReply = new RawReceivePort((_) { throw "Unexpected message: $_"; });
146 // Currently succeedes incorrectly in dart2js.
147 // Expect.throws(() {
148 // noReply.sendPort.send(func);
149 // }, null, "send direct");
150 // Expect.throws(() {
151 // noReply.sendPort.send([func]);
152 // }, null, "send wrapped");
153 scheduleMicrotask(() {
154 noReply.close();
155 asyncEnd();
156 });
157
158 // Try sending through other isolate.
159 asyncStart();
160 echoPort((_) => throw "unreachable")
161 .then((p) => p.send(func))
162 .then((p) => throw "unreachable 2",
163 onError: (e, s) {asyncEnd();});
164 }
165
166 void nop(_) {}
167
168 void callFunc(message) {
169 message[0](message[1], message[2]);
170 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/js_lib/isolate_helper.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698