blob: 42f2f9d599ed63fa260d63f788a7a8ca8572d192 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
define([
"mojo/apps/js/bindings/codec",
"mojo/apps/js/bindings/core",
"mojo/apps/js/bindings/support",
], function(codec, core, support) {
function Connector(handle) {
this.handle_ = handle;
this.error_ = false;
this.incomingReceiver_ = null;
this.readWaitCookie_ = null;
}
Connector.prototype.close = function() {
if (this.readWaitCookie_) {
support.cancelWait(this.readWaitCookie_);
this.readWaitCookie_ = null;
}
if (this.handle_ != core.kInvalidHandle) {
core.close(this.handle_);
this.handle_ = core.kInvalidHandle;
}
};
Connector.prototype.accept = function(message) {
if (this.error_)
return false;
this.write_(message);
return !this.error_;
};
Connector.prototype.setIncomingReceiver = function(receiver) {
this.incomingReceiver_ = receiver;
if (this.incomingReceiver_)
this.waitToReadMore_();
};
Connector.prototype.write_ = function(message) {
var result = core.writeMessage(this.handle_,
message.memory,
message.handles,
core.WRITE_MESSAGE_FLAG_NONE);
if (result != core.RESULT_OK) {
this.error_ = true
return;
}
// The handles were successfully transferred, so we don't own them anymore.
message.handles = [];
};
Connector.prototype.waitToReadMore_ = function() {
this.readWaitCookie_ = support.asyncWait(this.handle_,
core.WAIT_FLAG_READABLE,
this.readMore_.bind(this));
};
Connector.prototype.readMore_ = function(result) {
for (;;) {
var read = core.readMessage(this.handle_,
core.READ_MESSAGE_FLAG_NONE);
if (read.result == core.RESULT_NOT_FOUND) {
this.waitToReadMore_();
return;
}
if (read.result != core.RESULT_OK) {
this.error_ = true;
return;
}
// TODO(abarth): Should core.readMessage return a Uint8Array?
var memory = new Uint8Array(read.buffer);
var message = new codec.Message(memory, read.handles);
this.incomingReceiver_.accept(message);
}
};
function Connection(handle, localFactory, remoteFactory) {
this.connector_ = new Connector(handle);
this.remote = new remoteFactory(this.connector_);
this.local = new localFactory(this.remote);
this.connector_.setIncomingReceiver(this.local);
}
Connection.prototype.close = function() {
this.connector_.close();
this.connector_ = null;
this.local = null;
this.remote = null;
};
var exports = {};
exports.Connection = Connection;
return exports;
});