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

Side by Side Diff: lib/isolate/frog/messages.dart

Issue 9422019: isolates refactor: this change introduces 'dart:isolate' as a library. This is a (Closed) Base URL: https://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
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 /** 5 // Defines message visitors, serialization, and deserialization.
6 * Abstract visitor for dart objects that can be passed as messages between any 6 #library("isolate.frog.messages");
7 * isolates. 7
8 */ 8 #import("dart:isolate");
9 #import("ports.dart");
10 #import("isolateimpl.dart");
11
12 /** Serialize [message] (or simulate serialization). */
13 serialize(message) {
14 if (globalState.needSerialization) {
15 return new Serializer().traverse(message);
16 } else {
17 return new Copier().traverse(message);
18 }
19 }
20
21 /** Deserialize [message] (or simulate deserialization). */
22 deserialize(message) {
23 if (globalState.needSerialization) {
24 return new Deserializer().deserialize(message);
25 } else {
26 // Nothing more to do.
27 return message;
28 }
29 }
30
31 /** Abstract visitor for dart objects that can be sent as isolate messages. */
9 class MessageTraverser { 32 class MessageTraverser {
10 static bool isPrimitive(x) { 33
11 return (x === null) || (x is String) || (x is num) || (x is bool); 34 List _taggedObjects;
12 }
13 35
14 MessageTraverser(); 36 MessageTraverser();
15 37
16 /** Visitor's entry point. */ 38 /** Visitor's entry point. */
17 traverse(var x) { 39 traverse(var x) {
18 if (isPrimitive(x)) return visitPrimitive(x); 40 if (isPrimitive(x)) return visitPrimitive(x);
19 _taggedObjects = new List(); 41 _taggedObjects = new List();
20 var result; 42 var result;
21 try { 43 try {
22 result = _dispatch(x); 44 result = _dispatch(x);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 83
62 abstract visitPrimitive(x); 84 abstract visitPrimitive(x);
63 abstract visitList(List x); 85 abstract visitList(List x);
64 abstract visitMap(Map x); 86 abstract visitMap(Map x);
65 abstract visitNativeJsSendPort(NativeJsSendPort x); 87 abstract visitNativeJsSendPort(NativeJsSendPort x);
66 abstract visitWorkerSendPort(WorkerSendPort x); 88 abstract visitWorkerSendPort(WorkerSendPort x);
67 abstract visitBufferingSendPort(BufferingSendPort x); 89 abstract visitBufferingSendPort(BufferingSendPort x);
68 abstract visitReceivePort(ReceivePortImpl x); 90 abstract visitReceivePort(ReceivePortImpl x);
69 abstract visitReceivePortSingleShot(ReceivePortSingleShotImpl x); 91 abstract visitReceivePortSingleShot(ReceivePortSingleShotImpl x);
70 92
71 List _taggedObjects;
72
73 _clearAttachedInfo(var o) native 93 _clearAttachedInfo(var o) native
74 "o['__MessageTraverser__attached_info__'] = (void 0);"; 94 "o['__MessageTraverser__attached_info__'] = (void 0);";
75 95
76 _setAttachedInfo(var o, var info) native 96 _setAttachedInfo(var o, var info) native
77 "o['__MessageTraverser__attached_info__'] = info;"; 97 "o['__MessageTraverser__attached_info__'] = info;";
78 98
79 _getAttachedInfo(var o) native 99 _getAttachedInfo(var o) native
80 "return o['__MessageTraverser__attached_info__'];"; 100 "return o['__MessageTraverser__attached_info__'];";
81 101
82 _visitNativeOrWorkerPort(SendPort p) { 102 _visitNativeOrWorkerPort(SendPort p) {
83 if (p is NativeJsSendPort) return visitNativeJsSendPort(p); 103 if (p is NativeJsSendPort) return visitNativeJsSendPort(p);
84 if (p is WorkerSendPort) return visitWorkerSendPort(p); 104 if (p is WorkerSendPort) return visitWorkerSendPort(p);
85 throw "Illegal underlying port $p"; 105 throw "Illegal underlying port $p";
86 } 106 }
107
108 static bool isPrimitive(x) {
109 return (x === null) || (x is String) || (x is num) || (x is bool);
110 }
87 } 111 }
88 112
113
89 /** A visitor that recursively copies a message. */ 114 /** A visitor that recursively copies a message. */
90 class Copier extends MessageTraverser { 115 class Copier extends MessageTraverser {
91 Copier() : super(); 116 Copier() : super();
92 117
93 visitPrimitive(x) => x; 118 visitPrimitive(x) => x;
94 119
95 List visitList(List list) { 120 List visitList(List list) {
96 List copy = _getInfo(list); 121 List copy = _getInfo(list);
97 if (copy !== null) return copy; 122 if (copy !== null) return copy;
98 123
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 return port.toSendPort(); 168 return port.toSendPort();
144 } 169 }
145 170
146 SendPort visitReceivePortSingleShot(ReceivePortSingleShotImpl port) { 171 SendPort visitReceivePortSingleShot(ReceivePortSingleShotImpl port) {
147 return port.toSendPort(); 172 return port.toSendPort();
148 } 173 }
149 } 174 }
150 175
151 /** Visitor that serializes a message as a JSON array. */ 176 /** Visitor that serializes a message as a JSON array. */
152 class Serializer extends MessageTraverser { 177 class Serializer extends MessageTraverser {
178 int _nextFreeRefId = 0;
179
153 Serializer() : super(); 180 Serializer() : super();
154 181
155 visitPrimitive(x) => x; 182 visitPrimitive(x) => x;
156 183
157 visitList(List list) { 184 visitList(List list) {
158 int copyId = _getInfo(list); 185 int copyId = _getInfo(list);
159 if (copyId !== null) return ['ref', copyId]; 186 if (copyId !== null) return ['ref', copyId];
160 187
161 int id = _nextFreeRefId++; 188 int id = _nextFreeRefId++;
162 _attachInfo(list, id); 189 _attachInfo(list, id);
163 var jsArray = _serializeList(list); 190 var jsArray = _serializeList(list);
164 // TODO(floitsch): we are losing the generic type. 191 // TODO(floitsch): we are losing the generic type.
165 return ['list', id, jsArray]; 192 return ['list', id, jsArray];
166 } 193 }
167 194
168 visitMap(Map map) { 195 visitMap(Map map) {
169 int copyId = _getInfo(map); 196 int copyId = _getInfo(map);
170 if (copyId !== null) return ['ref', copyId]; 197 if (copyId !== null) return ['ref', copyId];
171 198
172 int id = _nextFreeRefId++; 199 int id = _nextFreeRefId++;
173 _attachInfo(map, id); 200 _attachInfo(map, id);
174 var keys = _serializeList(map.getKeys()); 201 var keys = _serializeList(map.getKeys());
175 var values = _serializeList(map.getValues()); 202 var values = _serializeList(map.getValues());
176 // TODO(floitsch): we are losing the generic type. 203 // TODO(floitsch): we are losing the generic type.
177 return ['map', id, keys, values]; 204 return ['map', id, keys, values];
178 } 205 }
179 206
180 visitNativeJsSendPort(NativeJsSendPort port) { 207 visitNativeJsSendPort(NativeJsSendPort port) {
181 return ['sendport', _globalState.currentWorkerId, 208 return ['sendport', globalState.currentWorkerId,
182 port._isolateId, port._receivePort._id]; 209 port._isolateId, port._receivePort._id];
183 } 210 }
184 211
185 visitWorkerSendPort(WorkerSendPort port) { 212 visitWorkerSendPort(WorkerSendPort port) {
186 return ['sendport', port._workerId, port._isolateId, port._receivePortId]; 213 return ['sendport', port._workerId, port._isolateId, port._receivePortId];
187 } 214 }
188 215
189 visitBufferingSendPort(BufferingSendPort port) { 216 visitBufferingSendPort(BufferingSendPort port) {
190 if (port._port != null) { 217 if (port._port != null) {
191 return _visitNativeOrWorkerPort(port._port); 218 return _visitNativeOrWorkerPort(port._port);
(...skipping 13 matching lines...) Expand all
205 } 232 }
206 233
207 _serializeList(List list) { 234 _serializeList(List list) {
208 int len = list.length; 235 int len = list.length;
209 var result = new List(len); 236 var result = new List(len);
210 for (int i = 0; i < len; i++) { 237 for (int i = 0; i < len; i++) {
211 result[i] = _dispatch(list[i]); 238 result[i] = _dispatch(list[i]);
212 } 239 }
213 return result; 240 return result;
214 } 241 }
215
216 int _nextFreeRefId = 0;
217 } 242 }
218 243
219 /** Visitor that finds all unresolved [SendPort]s in a message. */
220 class PendingSendPortFinder extends MessageTraverser {
221 List<Future<SendPort>> ports;
222 PendingSendPortFinder() : super(), ports = [];
223
224 visitPrimitive(x) {}
225 visitNativeJsSendPort(NativeJsSendPort port) {}
226 visitWorkerSendPort(WorkerSendPort port) {}
227 visitReceivePort(ReceivePortImpl port) {}
228 visitReceivePortSingleShot(ReceivePortSingleShotImpl port) {}
229
230 visitList(List list) {
231 final visited = _getInfo(list);
232 if (visited !== null) return;
233 _attachInfo(list, true);
234 // TODO(sigmund): replace with the following: (bug #1660)
235 // list.forEach(_dispatch);
236 list.forEach((e) => _dispatch(e));
237 }
238
239 visitMap(Map map) {
240 final visited = _getInfo(map);
241 if (visited !== null) return;
242
243 _attachInfo(map, true);
244 // TODO(sigmund): replace with the following: (bug #1660)
245 // map.getValues().forEach(_dispatch);
246 map.getValues().forEach((e) => _dispatch(e));
247 }
248
249 visitBufferingSendPort(BufferingSendPort port) {
250 if (port._port == null) {
251 ports.add(port._futurePort);
252 }
253 }
254 }
255
256
257 /** Deserializes arrays created with [Serializer]. */ 244 /** Deserializes arrays created with [Serializer]. */
258 class Deserializer { 245 class Deserializer {
246 Map<int, Dynamic> _deserialized;
247
259 Deserializer(); 248 Deserializer();
260 249
261 static bool isPrimitive(x) { 250 static bool isPrimitive(x) {
262 return (x === null) || (x is String) || (x is num) || (x is bool); 251 return (x === null) || (x is String) || (x is num) || (x is bool);
263 } 252 }
264 253
265 deserialize(x) { 254 deserialize(x) {
266 if (isPrimitive(x)) return x; 255 if (isPrimitive(x)) return x;
267 // TODO(floitsch): this should be new HashMap<int, var|Dynamic>() 256 // TODO(floitsch): this should be new HashMap<int, var|Dynamic>()
268 _deserialized = new HashMap(); 257 _deserialized = new HashMap();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 } 305 }
317 return result; 306 return result;
318 } 307 }
319 308
320 SendPort _deserializeSendPort(List x) { 309 SendPort _deserializeSendPort(List x) {
321 int workerId = x[1]; 310 int workerId = x[1];
322 int isolateId = x[2]; 311 int isolateId = x[2];
323 int receivePortId = x[3]; 312 int receivePortId = x[3];
324 // If two isolates are in the same worker, we use NativeJsSendPorts to 313 // If two isolates are in the same worker, we use NativeJsSendPorts to
325 // deliver messages directly without using postMessage. 314 // deliver messages directly without using postMessage.
326 if (workerId == _globalState.currentWorkerId) { 315 if (workerId == globalState.currentWorkerId) {
327 var isolate = _globalState.isolates[isolateId]; 316 var isolate = globalState.isolates[isolateId];
328 if (isolate == null) return null; // Isolate has been closed. 317 if (isolate == null) return null; // Isolate has been closed.
329 var receivePort = isolate.lookup(receivePortId); 318 var receivePort = isolate.lookup(receivePortId);
330 return new NativeJsSendPort(receivePort, isolateId); 319 return new NativeJsSendPort(receivePort, isolateId);
331 } else { 320 } else {
332 return new WorkerSendPort(workerId, isolateId, receivePortId); 321 return new WorkerSendPort(workerId, isolateId, receivePortId);
333 } 322 }
334 } 323 }
335
336 Map<int, Dynamic> _deserialized;
337 } 324 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698