1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 define("mojo/public/js/bindings/connector", [
6 "mojo/public/js/bindings/buffer",
7 "mojo/public/js/bindings/codec",
8 "mojo/public/js/bindings/core",
9 "mojo/public/js/bindings/support",
10 ], function(buffer, codec, core, support) {
12 function Connector(handle) {
13 this.handle_ = handle;
14 this.dropWrites_ = false;
16 this.incomingReceiver_ = null;
17 this.readWaitCookie_ = null;
18 this.errorHandler_ = null;
20 this.waitToReadMore_();
23 Connector.prototype.close = function() {
24 if (this.readWaitCookie_) {
25 support.cancelWait(this.readWaitCookie_);
26 this.readWaitCookie_ = null;
28 if (this.handle_ != null) {
29 core.close(this.handle_);
34 Connector.prototype.accept = function(message) {
41 var result = core.writeMessage(this.handle_,
42 new Uint8Array(message.buffer.arrayBuffer),
44 core.WRITE_MESSAGE_FLAG_NONE);
47 // The handles were successfully transferred, so we don't own them
51 case core.RESULT_FAILED_PRECONDITION:
52 // There's no point in continuing to write to this pipe since the other
53 // end is gone. Avoid writing any future messages. Hide write failures
54 // from the caller since we'd like them to continue consuming any
55 // backlog of incoming messages before regarding the message pipe as
57 this.dropWrites_ = true;
60 // This particular write was rejected, presumably because of bad input.
61 // The pipe is not necessarily in a bad state.
67 Connector.prototype.setIncomingReceiver = function(receiver) {
68 this.incomingReceiver_ = receiver;
71 Connector.prototype.setErrorHandler = function(handler) {
72 this.errorHandler_ = handler;
75 Connector.prototype.encounteredError = function() {
79 Connector.prototype.waitToReadMore_ = function() {
80 this.readWaitCookie_ = support.asyncWait(this.handle_,
81 core.HANDLE_SIGNAL_READABLE,
82 this.readMore_.bind(this));
85 Connector.prototype.readMore_ = function(result) {
87 var read = core.readMessage(this.handle_,
88 core.READ_MESSAGE_FLAG_NONE);
89 if (read.result == core.RESULT_SHOULD_WAIT) {
90 this.waitToReadMore_();
93 if (read.result != core.RESULT_OK) {
95 if (this.errorHandler_)
96 this.errorHandler_.onError(read.result);
99 var messageBuffer = new buffer.Buffer(read.buffer);
100 var message = new codec.Message(messageBuffer, read.handles);
101 if (this.incomingReceiver_) {
102 this.incomingReceiver_.accept(message);
107 // The TestConnector subclass is only intended to be used in unit tests. It
108 // enables delivering a message to the pipe's handle without an async wait.
110 function TestConnector(handle) {
111 Connector.call(this, handle);
114 TestConnector.prototype = Object.create(Connector.prototype);
116 TestConnector.prototype.waitToReadMore_ = function() {
119 TestConnector.prototype.deliverMessage = function() {
120 this.readMore_(core.RESULT_OK);
124 exports.Connector = Connector;
125 exports.TestConnector = TestConnector;