1 // Copyright 2013 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([ 6 "mojo/apps/js/bindings/codec", 7 "mojo/apps/js/bindings/core", 8 "mojo/apps/js/bindings/support", 9 ], function(codec, core, support) { 10 11 function Connector(handle) { 12 this.handle_ = handle; 13 this.error_ = false; 14 this.incomingReceiver_ = null; 15 this.readWaitCookie_ = null; 16 } 17 18 Connector.prototype.close = function() { 19 if (this.readWaitCookie_) { 20 support.cancelWait(this.readWaitCookie_); 21 this.readWaitCookie_ = null; 22 } 23 if (this.handle_ != core.kInvalidHandle) { 24 core.close(this.handle_); 25 this.handle_ = core.kInvalidHandle; 26 } 27 }; 28 29 Connector.prototype.accept = function(message) { 30 if (this.error_) 31 return false; 32 this.write_(message); 33 return !this.error_; 34 }; 35 36 Connector.prototype.setIncomingReceiver = function(receiver) { 37 this.incomingReceiver_ = receiver; 38 if (this.incomingReceiver_) 39 this.waitToReadMore_(); 40 }; 41 42 Connector.prototype.write_ = function(message) { 43 var result = core.writeMessage(this.handle_, 44 message.memory, 45 message.handles, 46 core.WRITE_MESSAGE_FLAG_NONE); 47 if (result != core.RESULT_OK) { 48 this.error_ = true 49 return; 50 } 51 // The handles were successfully transferred, so we don't own them anymore. 52 message.handles = []; 53 }; 54 55 Connector.prototype.waitToReadMore_ = function() { 56 this.readWaitCookie_ = support.asyncWait(this.handle_, 57 core.WAIT_FLAG_READABLE, 58 this.readMore_.bind(this)); 59 }; 60 61 Connector.prototype.readMore_ = function(result) { 62 for (;;) { 63 var read = core.readMessage(this.handle_, 64 core.READ_MESSAGE_FLAG_NONE); 65 if (read.result == core.RESULT_NOT_FOUND) { 66 this.waitToReadMore_(); 67 return; 68 } 69 if (read.result != core.RESULT_OK) { 70 this.error_ = true; 71 return; 72 } 73 // TODO(abarth): Should core.readMessage return a Uint8Array? 74 var memory = new Uint8Array(read.buffer); 75 var message = new codec.Message(memory, read.handles); 76 this.incomingReceiver_.accept(message); 77 } 78 }; 79 80 function Connection(handle, localFactory, remoteFactory) { 81 this.connector_ = new Connector(handle); 82 this.remote = new remoteFactory(this.connector_); 83 this.local = new localFactory(this.remote); 84 this.connector_.setIncomingReceiver(this.local); 85 } 86 87 Connection.prototype.close = function() { 88 this.connector_.close(); 89 this.connector_ = null; 90 this.local = null; 91 this.remote = null; 92 }; 93 94 var exports = {}; 95 exports.Connection = Connection; 96 return exports; 97 }); 98