// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. patch class ReceivePort { /* patch */ factory ReceivePort() { return new _ReceivePortImpl(); } } class _ReceivePortImpl implements ReceivePort { factory _ReceivePortImpl() native "ReceivePortImpl_factory"; receive(void onMessage(var message, SendPort replyTo)) { _onMessage = onMessage; } close() { _portMap.remove(_id); _closeInternal(_id); } SendPort toSendPort() { return new _SendPortImpl(_id); } /**** Internal implementation details ****/ // Called from the VM to create a new ReceivePort instance. static _ReceivePortImpl _get_or_create(int id) { if (_portMap != null) { _ReceivePortImpl port = _portMap[id]; if (port != null) { return port; } } return new _ReceivePortImpl._internal(id); } _ReceivePortImpl._internal(int id) : _id = id { if (_portMap == null) { _portMap = new Map(); } _portMap[id] = this; } // Called from the VM to retrieve the ReceivePort for a message. static _ReceivePortImpl _lookupReceivePort(int id) { assert(_portMap != null); return _portMap[id]; } // Called from the VM to dispatch to the handler. static void _handleMessage(_ReceivePortImpl port, int replyId, var message) { assert(port != null); SendPort replyTo = (replyId == 0) ? null : new _SendPortImpl(replyId); (port._onMessage)(message, replyTo); } // Call into the VM to close the VM maintained mappings. static _closeInternal(int id) native "ReceivePortImpl_closeInternal"; final int _id; var _onMessage; // id to ReceivePort mapping. static Map _portMap; } class _SendPortImpl implements SendPort { /*--- public interface ---*/ void send(var message, [SendPort replyTo = null]) { this._sendNow(message, replyTo); } void _sendNow(var message, SendPort replyTo) { int replyId = (replyTo == null) ? 0 : replyTo._id; _sendInternal(_id, replyId, message); } Future call(var message) { final completer = new Completer(); final port = new _ReceivePortImpl(); send(message, port.toSendPort()); port.receive((value, ignoreReplyTo) { port.close(); if (value is Exception) { completer.completeError(value); } else { completer.complete(value); } }); return completer.future; } bool operator==(var other) { return (other is _SendPortImpl) && _id == other._id; } int get hashCode { return _id; } /*--- private implementation ---*/ const _SendPortImpl(int id) : _id = id; // _SendPortImpl._create is called from the VM when a new SendPort instance is // needed by the VM code. static SendPort _create(int id) { return new _SendPortImpl(id); } // Forward the implementation of sending messages to the VM. Only port ids // are being handed to the VM. static _sendInternal(int sendId, int replyId, var message) native "SendPortImpl_sendInternal_"; final int _id; } _getPortInternal() native "isolate_getPortInternal"; ReceivePort _portInternal; patch class _Isolate { /* patch */ static ReceivePort get port { if (_portInternal == null) { _portInternal = _getPortInternal(); } return _portInternal; } /* patch */ static spawnFunction(void topLevelFunction(), [bool UnhandledExceptionCallback(IsolateUnhandledException e)]) native "isolate_spawnFunction"; /* patch */ static spawnUri(String uri) native "isolate_spawnUri"; }