4c0f559d23
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@15 260f80e4-7a28-3924-810f-c04153c831b5
167 lines
4.3 KiB
Dart
167 lines
4.3 KiB
Dart
// Copyright (c) 2011, 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.
|
|
|
|
class ReceivePortFactory {
|
|
factory ReceivePort() {
|
|
return new ReceivePortImpl();
|
|
}
|
|
|
|
factory ReceivePort.singleShot() {
|
|
return new ReceivePortSingleShotImpl();
|
|
}
|
|
}
|
|
|
|
|
|
class ReceivePortImpl implements ReceivePort {
|
|
/*--- public interface ---*/
|
|
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 create_(int id) {
|
|
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 dispatch to the handler.
|
|
static void handleMessage_(int id, int replyId, var message) {
|
|
assert(_portMap != null);
|
|
ReceivePort port = _portMap[id];
|
|
SendPort replyTo = (replyId == 0) ? null : new SendPortImpl(replyId);
|
|
(port._onMessage)(message, replyTo);
|
|
PromiseQueue.process();
|
|
}
|
|
|
|
// 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 ReceivePortSingleShotImpl implements ReceivePort {
|
|
|
|
ReceivePortSingleShotImpl() : _port = new ReceivePortImpl() { }
|
|
|
|
void receive(void callback(var message, SendPort replyTo)) {
|
|
_port.receive((var message, SendPort replyTo) {
|
|
_port.close();
|
|
callback(message, replyTo);
|
|
});
|
|
}
|
|
|
|
void close() {
|
|
_port.close();
|
|
}
|
|
|
|
SendPort toSendPort() {
|
|
return _port.toSendPort();
|
|
}
|
|
|
|
final ReceivePortImpl _port;
|
|
|
|
}
|
|
|
|
|
|
class SendPortImpl implements SendPort {
|
|
/*--- public interface ---*/
|
|
void send(var message, SendPort replyTo) {
|
|
if (PromiseQueue.isEmpty()) {
|
|
this._sendNow(message, replyTo);
|
|
} else {
|
|
_enqueueSend(message, replyTo);
|
|
}
|
|
}
|
|
|
|
void _enqueueSend(var message, SendPort replyTo) {
|
|
PromiseQueue.enqueue(const []).then((ignored) {
|
|
this._sendNow(message, replyTo);
|
|
});
|
|
}
|
|
|
|
void _sendNow(var message, SendPort replyTo) {
|
|
int replyId = (replyTo === null) ? 0 : replyTo._id;
|
|
_sendInternal(_id, replyId, message);
|
|
}
|
|
|
|
ReceivePortSingleShotImpl call(var message) {
|
|
final result = new ReceivePortSingleShotImpl();
|
|
this.send(message, result.toSendPort());
|
|
return result;
|
|
}
|
|
|
|
ReceivePortSingleShotImpl _callNow(var message) {
|
|
final result = new ReceivePortSingleShotImpl();
|
|
this._sendNow(message, result.toSendPort());
|
|
return result;
|
|
}
|
|
|
|
bool operator==(var other) {
|
|
return (other is SendPortImpl) && _id == other._id;
|
|
}
|
|
|
|
int 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;
|
|
}
|
|
|
|
|
|
class IsolateNatives {
|
|
static Promise<SendPort> spawn(Isolate isolate, bool isLight) {
|
|
Promise<SendPort> result = new Promise<SendPort>();
|
|
SendPort port = _start(isolate, isLight);
|
|
result.complete(port);
|
|
return result;
|
|
}
|
|
|
|
// Starts a new isolate calling the run method on a new instance of the
|
|
// remote class's type.
|
|
// Returns the send port which is passed to the newly created isolate.
|
|
// This method is being dispatched to from the public core library code.
|
|
static SendPort _start(Isolate isolate, bool light)
|
|
native "IsolateNatives_start";
|
|
|
|
// The VM knows in which isolate the function must be run, therefore
|
|
// there is no need for wrapping it.
|
|
static Function bind(Function f) { return f; }
|
|
}
|