Home | History | Annotate | Download | only in js
      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.
      4 
      5 define("mojo/public/js/connector", [
      6   "mojo/public/js/buffer",
      7   "mojo/public/js/codec",
      8   "mojo/public/js/core",
      9   "mojo/public/js/support",
     10 ], function(buffer, codec, core, support) {
     11 
     12   function Connector(handle) {
     13     if (!core.isHandle(handle))
     14       throw new Error("Connector: not a handle " + handle);
     15     this.handle_ = handle;
     16     this.dropWrites_ = false;
     17     this.error_ = false;
     18     this.incomingReceiver_ = null;
     19     this.readWatcher_ = null;
     20     this.errorHandler_ = null;
     21 
     22     if (handle) {
     23       this.readWatcher_ = support.watch(handle,
     24                                         core.HANDLE_SIGNAL_READABLE,
     25                                         this.readMore_.bind(this));
     26     }
     27   }
     28 
     29   Connector.prototype.close = function() {
     30     if (this.readWatcher_) {
     31       support.cancelWatch(this.readWatcher_);
     32       this.readWatcher_ = null;
     33     }
     34     if (this.handle_ != null) {
     35       core.close(this.handle_);
     36       this.handle_ = null;
     37     }
     38   };
     39 
     40   Connector.prototype.accept = function(message) {
     41     if (this.error_)
     42       return false;
     43 
     44     if (this.dropWrites_)
     45       return true;
     46 
     47     var result = core.writeMessage(this.handle_,
     48                                    new Uint8Array(message.buffer.arrayBuffer),
     49                                    message.handles,
     50                                    core.WRITE_MESSAGE_FLAG_NONE);
     51     switch (result) {
     52       case core.RESULT_OK:
     53         // The handles were successfully transferred, so we don't own them
     54         // anymore.
     55         message.handles = [];
     56         break;
     57       case core.RESULT_FAILED_PRECONDITION:
     58         // There's no point in continuing to write to this pipe since the other
     59         // end is gone. Avoid writing any future messages. Hide write failures
     60         // from the caller since we'd like them to continue consuming any
     61         // backlog of incoming messages before regarding the message pipe as
     62         // closed.
     63         this.dropWrites_ = true;
     64         break;
     65       default:
     66         // This particular write was rejected, presumably because of bad input.
     67         // The pipe is not necessarily in a bad state.
     68         return false;
     69     }
     70     return true;
     71   };
     72 
     73   Connector.prototype.setIncomingReceiver = function(receiver) {
     74     this.incomingReceiver_ = receiver;
     75   };
     76 
     77   Connector.prototype.setErrorHandler = function(handler) {
     78     this.errorHandler_ = handler;
     79   };
     80 
     81   Connector.prototype.encounteredError = function() {
     82     return this.error_;
     83   };
     84 
     85   Connector.prototype.waitForNextMessageForTesting = function() {
     86     var wait = core.wait(this.handle_, core.HANDLE_SIGNAL_READABLE,
     87                          core.DEADLINE_INDEFINITE);
     88     this.readMore_(wait.result);
     89   };
     90 
     91   Connector.prototype.readMore_ = function(result) {
     92     for (;;) {
     93       var read = core.readMessage(this.handle_,
     94                                   core.READ_MESSAGE_FLAG_NONE);
     95       if (this.handle_ == null) // The connector has been closed.
     96         return;
     97       if (read.result == core.RESULT_SHOULD_WAIT)
     98         return;
     99       if (read.result != core.RESULT_OK) {
    100         this.error_ = true;
    101         if (this.errorHandler_)
    102           this.errorHandler_.onError(read.result);
    103         return;
    104       }
    105       var messageBuffer = new buffer.Buffer(read.buffer);
    106       var message = new codec.Message(messageBuffer, read.handles);
    107       if (this.incomingReceiver_)
    108         this.incomingReceiver_.accept(message);
    109     }
    110   };
    111 
    112   var exports = {};
    113   exports.Connector = Connector;
    114   return exports;
    115 });
    116