OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 import "dart:isolate"; | 5 import "dart:isolate"; |
6 import "dart:async"; | 6 import "dart:async"; |
7 import "package:expect/expect.dart"; | 7 import "package:expect/expect.dart"; |
8 import "package:async_helper/async_helper.dart"; | 8 import "package:async_helper/async_helper.dart"; |
9 | 9 |
10 void toplevel(port, message) { port.send("toplevel:$message"); } | 10 void toplevel(port, message) { |
11 Function createFuncToplevel() => (p, m) { p.send(m); }; | 11 port.send("toplevel:$message"); |
| 12 } |
| 13 |
| 14 Function createFuncToplevel() => (p, m) { |
| 15 p.send(m); |
| 16 }; |
| 17 |
12 class C { | 18 class C { |
13 Function initializer; | 19 Function initializer; |
14 Function body; | 20 Function body; |
15 C() : initializer = ((p, m) { throw "initializer"; }) { | 21 C() |
16 body = (p, m) { throw "body"; }; | 22 : initializer = ((p, m) { |
| 23 throw "initializer"; |
| 24 }) { |
| 25 body = (p, m) { |
| 26 throw "body"; |
| 27 }; |
17 } | 28 } |
18 static void staticFunc(port, message) { port.send("static:$message"); } | 29 static void staticFunc(port, message) { |
19 static Function createFuncStatic() => (p, m) { throw "static expr"; }; | 30 port.send("static:$message"); |
20 void instanceMethod(p, m) { throw "instanceMethod"; } | 31 } |
21 Function createFuncMember() => (p, m) { throw "instance expr"; }; | 32 |
22 void call(n, p) { throw "C"; } | 33 static Function createFuncStatic() => (p, m) { |
| 34 throw "static expr"; |
| 35 }; |
| 36 void instanceMethod(p, m) { |
| 37 throw "instanceMethod"; |
| 38 } |
| 39 |
| 40 Function createFuncMember() => (p, m) { |
| 41 throw "instance expr"; |
| 42 }; |
| 43 void call(n, p) { |
| 44 throw "C"; |
| 45 } |
23 } | 46 } |
24 | 47 |
25 class Callable { | 48 class Callable { |
26 void call(p, m) { p.send(["callable", m]); } | 49 void call(p, m) { |
| 50 p.send(["callable", m]); |
| 51 } |
27 } | 52 } |
28 | 53 |
29 | |
30 void main() { | 54 void main() { |
31 asyncStart(); | 55 asyncStart(); |
32 | 56 |
33 // top-level functions, static functions, closures, instance methods | 57 // top-level functions, static functions, closures, instance methods |
34 // or function expressions are not sendable to an isolate spawned using | 58 // or function expressions are not sendable to an isolate spawned using |
35 // spawnUri. | 59 // spawnUri. |
36 testUnsendable("toplevel", toplevel); | 60 testUnsendable("toplevel", toplevel); |
37 testUnsendable("static", C.staticFunc); | 61 testUnsendable("static", C.staticFunc); |
38 var c = new C(); | 62 var c = new C(); |
39 testUnsendable("instance method", c.instanceMethod); | 63 testUnsendable("instance method", c.instanceMethod); |
40 testUnsendable("static context expression", createFuncToplevel()); | 64 testUnsendable("static context expression", createFuncToplevel()); |
41 testUnsendable("static context expression", C.createFuncStatic()); | 65 testUnsendable("static context expression", C.createFuncStatic()); |
42 testUnsendable("initializer context expression", c.initializer); | 66 testUnsendable("initializer context expression", c.initializer); |
43 testUnsendable("constructor context expression", c.body); | 67 testUnsendable("constructor context expression", c.body); |
44 testUnsendable("instance method context expression", c.createFuncMember()); | 68 testUnsendable("instance method context expression", c.createFuncMember()); |
45 testUnsendable("toplevel", toplevel.call); | 69 testUnsendable("toplevel", toplevel.call); |
46 testUnsendable("static", C.staticFunc.call); | 70 testUnsendable("static", C.staticFunc.call); |
47 testUnsendable("callable object", new Callable().call); | 71 testUnsendable("callable object", new Callable().call); |
48 | 72 |
49 asyncEnd(); | 73 asyncEnd(); |
50 return; | 74 return; |
51 } | 75 } |
52 | 76 |
53 // Create a receive port that expects exactly one message. | 77 // Create a receive port that expects exactly one message. |
54 // Pass the message to `callback` and return the sendPort. | 78 // Pass the message to `callback` and return the sendPort. |
55 SendPort singleMessagePort(callback) { | 79 SendPort singleMessagePort(callback) { |
56 var p; | 80 var p; |
57 p = new RawReceivePort((v) { p.close(); callback(v); }); | 81 p = new RawReceivePort((v) { |
| 82 p.close(); |
| 83 callback(v); |
| 84 }); |
58 return p.sendPort; | 85 return p.sendPort; |
59 } | 86 } |
60 | 87 |
61 // A singleMessagePort that expects the message to be a specific value. | 88 // A singleMessagePort that expects the message to be a specific value. |
62 SendPort expectMessagePort(message) { | 89 SendPort expectMessagePort(message) { |
63 asyncStart(); | 90 asyncStart(); |
64 return singleMessagePort((v) { | 91 return singleMessagePort((v) { |
65 Expect.equals(message, v); | 92 Expect.equals(message, v); |
66 asyncEnd(); | 93 asyncEnd(); |
67 }); | 94 }); |
68 } | 95 } |
69 | 96 |
70 // Creates a new isolate and a pair of ports that expect a single message | 97 // Creates a new isolate and a pair of ports that expect a single message |
71 // to be sent to the other isolate and back to the callback function. | 98 // to be sent to the other isolate and back to the callback function. |
72 Future<SendPort> echoPort(callback(value)) { | 99 Future<SendPort> echoPort(callback(value)) { |
73 Completer completer = new Completer<SendPort>(); | 100 Completer completer = new Completer<SendPort>(); |
74 SendPort replyPort = singleMessagePort(callback); | 101 SendPort replyPort = singleMessagePort(callback); |
75 RawReceivePort initPort; | 102 RawReceivePort initPort; |
76 initPort = new RawReceivePort((p) { | 103 initPort = new RawReceivePort((p) { |
77 completer.complete(p); | 104 completer.complete(p); |
78 initPort.close(); | 105 initPort.close(); |
79 }); | 106 }); |
80 return Isolate.spawn(_echo, [replyPort, initPort.sendPort]) | 107 return Isolate.spawn(_echo, [replyPort, initPort.sendPort]).then( |
81 .then((isolate) => completer.future); | 108 (isolate) => completer.future); |
82 } | 109 } |
83 | 110 |
84 void _echo(msg) { | 111 void _echo(msg) { |
85 var replyPort = msg[0]; | 112 var replyPort = msg[0]; |
86 RawReceivePort requestPort; | 113 RawReceivePort requestPort; |
87 requestPort = new RawReceivePort((msg) { | 114 requestPort = new RawReceivePort((msg) { |
88 replyPort.send(msg); | 115 replyPort.send(msg); |
89 requestPort.close(); // Single echo only. | 116 requestPort.close(); // Single echo only. |
90 }); | 117 }); |
91 msg[1].send(requestPort.sendPort); | 118 msg[1].send(requestPort.sendPort); |
92 } | 119 } |
93 | 120 |
94 // Creates other isolate that waits for a single message, `msg`, on the returned | 121 // Creates other isolate that waits for a single message, `msg`, on the returned |
95 // port, and executes it as `msg[0](msg[1],msg[2])` in the other isolate. | 122 // port, and executes it as `msg[0](msg[1],msg[2])` in the other isolate. |
96 Future<SendPort> callPort() { | 123 Future<SendPort> callPort() { |
97 Completer completer = new Completer<SendPort>(); | 124 Completer completer = new Completer<SendPort>(); |
98 SendPort initPort = singleMessagePort(completer.complete); | 125 SendPort initPort = singleMessagePort(completer.complete); |
99 return Isolate.spawn(_call, initPort) | 126 return Isolate.spawn(_call, initPort).then((_) => completer.future); |
100 .then((_) => completer.future); | |
101 } | 127 } |
102 | 128 |
103 void _call(initPort) { | 129 void _call(initPort) { |
104 initPort.send(singleMessagePort(callFunc)); | 130 initPort.send(singleMessagePort(callFunc)); |
105 } | 131 } |
106 | 132 |
107 void testUnsendable(name, func) { | 133 void testUnsendable(name, func) { |
108 asyncStart(); | 134 asyncStart(); |
109 Isolate.spawnUri(Uri.parse("function_send_test.dart"), [], func) | 135 Isolate |
110 .then((v) => throw "allowed spawn direct?", onError: (e,s){ asyncEnd(); }); | 136 .spawnUri(Uri.parse("function_send_test.dart"), [], func) |
| 137 .then((v) => throw "allowed spawn direct?", onError: (e, s) { |
| 138 asyncEnd(); |
| 139 }); |
111 asyncStart(); | 140 asyncStart(); |
112 Isolate.spawnUri(Uri.parse("function_send_test.dart"), [], [func]) | 141 Isolate.spawnUri(Uri.parse("function_send_test.dart"), [], [func]).then( |
113 .then((v) => throw "allowed spawn wrapped?", onError: (e,s){ asyncEnd(); }); | 142 (v) => throw "allowed spawn wrapped?", onError: (e, s) { |
| 143 asyncEnd(); |
| 144 }); |
114 } | 145 } |
115 | 146 |
116 void callFunc(message) { | 147 void callFunc(message) { |
117 message[0](message[1], message[2]); | 148 message[0](message[1], message[2]); |
118 } | 149 } |
OLD | NEW |