Chromium Code Reviews| Index: frog/lib/isolate_serialization.dart |
| diff --git a/frog/lib/isolate_serialization.dart b/frog/lib/isolate_serialization.dart |
| index 2ab10a3b45d0d2303f005c98e31c3a84c66db48d..b69a7a62a025917321b4a373fff164d8faff36f8 100644 |
| --- a/frog/lib/isolate_serialization.dart |
| +++ b/frog/lib/isolate_serialization.dart |
| @@ -50,7 +50,9 @@ class MessageTraverser { |
| if (isPrimitive(x)) return visitPrimitive(x); |
| if (x is List) return visitList(x); |
| if (x is Map) return visitMap(x); |
| - if (x is SendPortImpl) return visitSendPort(x); |
| + if (x is NativeJsSendPort) return visitNativeJsSendPort(x); |
| + if (x is WorkerSendPort) return visitWorkerSendPort(x); |
| + if (x is BufferingSendPort) return visitBufferingSendPort(x); |
| if (x is ReceivePortImpl) return visitReceivePort(x); |
| if (x is ReceivePortSingleShotImpl) return visitReceivePortSingleShot(x); |
| // TODO(floitsch): make this a real exception. (which one)? |
| @@ -60,7 +62,9 @@ class MessageTraverser { |
| abstract visitPrimitive(x); |
| abstract visitList(List x); |
| abstract visitMap(Map x); |
| - abstract visitSendPort(SendPortImpl x); |
| + abstract visitNativeJsSendPort(NativeJsSendPort x); |
| + abstract visitWorkerSendPort(WorkerSendPort x); |
| + abstract visitBufferingSendPort(BufferingSendPort x); |
| abstract visitReceivePort(ReceivePortImpl x); |
| abstract visitReceivePortSingleShot(ReceivePortSingleShotImpl x); |
| @@ -74,6 +78,12 @@ class MessageTraverser { |
| _getAttachedInfo(var o) native |
| "return o['__MessageTraverser__attached_info__'];"; |
| + |
| + _visitNativeOrWorkerPort(SendPort p) { |
| + if (p is NativeJsSendPort) return visitNativeJsSendPort(p); |
| + if (p is WorkerSendPort) return visitWorkerSendPort(p); |
| + throw "Illegal underlying port $p"; |
| + } |
| } |
| /** A visitor that recursively copies a message. */ |
| @@ -110,10 +120,23 @@ class Copier extends MessageTraverser { |
| return copy; |
| } |
| - SendPort visitSendPort(SendPortImpl port) { |
| - return new SendPortImpl(port._workerId, |
| - port._isolateId, |
| - port._receivePortId); |
| + SendPort visitNativeJsSendPort(NativeJsSendPort port) { |
| + return new NativeJsSendPort(port._receivePort, port._isolateId); |
| + } |
| + |
| + SendPort visitWorkerSendPort(WorkerSendPort port) { |
| + return new WorkerSendPort( |
| + port._workerId, port._isolateId, port._receivePortId); |
| + } |
| + |
| + SendPort visitBufferingSendPort(BufferingSendPort port) { |
| + if (port._port != null) { |
| + return _visitNativeOrWorkerPort(port._port); |
| + } else { |
| + // TODO(floitsch): Use real exception (which one?). |
| + throw "interal error: must call _waitForPendingPorts to ensure all" |
|
eub
2012/02/10 22:46:19
"internal"
|
| + + " ports are resolved at this point."; |
| + } |
| } |
| SendPort visitReceivePort(ReceivePortImpl port) { |
| @@ -154,16 +177,31 @@ class Serializer extends MessageTraverser { |
| return ['map', id, keys, values]; |
| } |
| - visitSendPort(SendPortImpl port) { |
| + visitNativeJsSendPort(NativeJsSendPort port) { |
| + return ['sendport', _globalState.currentWorkerId, |
| + port._isolateId, port._receivePort._id]; |
| + } |
| + |
| + visitWorkerSendPort(WorkerSendPort port) { |
| return ['sendport', port._workerId, port._isolateId, port._receivePortId]; |
| } |
| + SendPort visitBufferingSendPort(BufferingSendPort port) { |
| + if (port._port != null) { |
| + return _visitNativeOrWorkerPort(port._port); |
| + } else { |
| + // TODO(floitsch): Use real exception (which one?). |
| + throw "interal error: must call _waitForPendingPorts to ensure all" |
| + + " ports are resolved at this point."; |
| + } |
| + } |
| + |
| visitReceivePort(ReceivePortImpl port) { |
| - return visitSendPort(port.toSendPort());; |
| + return visitNativeJsSendPort(port.toSendPort());; |
| } |
| visitReceivePortSingleShot(ReceivePortSingleShotImpl port) { |
| - return visitSendPort(port.toSendPort()); |
| + return visitNativeJsSendPort(port.toSendPort()); |
| } |
| _serializeList(List list) { |
| @@ -178,6 +216,40 @@ class Serializer extends MessageTraverser { |
| int _nextFreeRefId = 0; |
| } |
| +/** Visitor that finds all unresolved [SendPort]s in a message. */ |
| +class PendingSendPortFinder extends MessageTraverser { |
| + List<Future<SendPort>> ports; |
| + PendingSendPortFinder() : super(), ports = []; |
| + |
| + visitPrimitive(x) {} |
| + visitNativeJsSendPort(NativeJsSendPort port) {} |
| + visitWorkerSendPort(WorkerSendPort port) {} |
| + visitReceivePort(ReceivePortImpl port) {} |
| + visitReceivePortSingleShot(ReceivePortSingleShotImpl port) {} |
| + |
| + visitList(List list) { |
| + final visited = _getInfo(list); |
| + if (visited !== null) return; |
| + _attachInfo(list, true); |
| + list.forEach(_dispatch); |
| + } |
| + |
| + visitMap(Map map) { |
| + final visited = _getInfo(map); |
| + if (visited !== null) return; |
| + |
| + _attachInfo(map, true); |
| + map.getValues().forEach(_dispatch); |
| + } |
| + |
| + visitBufferingSendPort(BufferingSendPort port) { |
| + if (port._port == null) { |
| + ports.add(port._futurePort); |
| + } |
| + } |
| +} |
| + |
| + |
| /** Deserializes arrays created with [Serializer]. */ |
| class Deserializer { |
| Deserializer(); |
| @@ -245,7 +317,14 @@ class Deserializer { |
| int workerId = x[1]; |
| int isolateId = x[2]; |
| int receivePortId = x[3]; |
| - return new SendPortImpl(workerId, isolateId, receivePortId); |
| + if (workerId == _globalState.currentWorkerId) { |
| + var isolate = _globalState.isolates[isolateId]; |
| + if (isolate == null) return null; // Isolate has been closed. |
| + var receivePort = isolate.lookup(receivePortId); |
| + return new NativeJsSendPort(receivePort, isolateId); |
| + } else { |
| + return new WorkerSendPort(workerId, isolateId, receivePortId); |
| + } |
| } |
| // TODO(floitsch): this should by Map<int, var> or Map<int, Dynamic>. |