OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 define("mojo/public/js/connector", [ | 5 define("mojo/public/js/connector", [ |
6 "mojo/public/js/buffer", | 6 "mojo/public/js/buffer", |
7 "mojo/public/js/codec", | 7 "mojo/public/js/codec", |
8 "mojo/public/js/core", | 8 "mojo/public/js/core", |
9 "mojo/public/js/support", | 9 "mojo/public/js/support", |
10 ], function(buffer, codec, core, support) { | 10 "mojo/public/js/validator", |
| 11 ], function(buffer, codec, core, support, validator) { |
11 | 12 |
12 function Connector(handle) { | 13 function Connector(handle) { |
13 if (!core.isHandle(handle)) | 14 if (!core.isHandle(handle)) |
14 throw new Error("Connector: not a handle " + handle); | 15 throw new Error("Connector: not a handle " + handle); |
15 this.handle_ = handle; | 16 this.handle_ = handle; |
16 this.dropWrites_ = false; | 17 this.dropWrites_ = false; |
17 this.error_ = false; | 18 this.error_ = false; |
18 this.incomingReceiver_ = null; | 19 this.incomingReceiver_ = null; |
19 this.readWatcher_ = null; | 20 this.readWatcher_ = null; |
20 this.errorHandler_ = null; | 21 this.errorHandler_ = null; |
21 this.paused_ = false; | 22 this.paused_ = false; |
22 | 23 |
23 if (handle) { | 24 this.waitToReadMore(); |
24 this.readWatcher_ = support.watch(handle, | |
25 core.HANDLE_SIGNAL_READABLE, | |
26 this.readMore_.bind(this)); | |
27 } | |
28 } | 25 } |
29 | 26 |
30 Connector.prototype.close = function() { | 27 Connector.prototype.close = function() { |
31 if (this.readWatcher_) { | 28 this.cancelWait(); |
32 support.cancelWatch(this.readWatcher_); | |
33 this.readWatcher_ = null; | |
34 } | |
35 if (this.handle_ != null) { | 29 if (this.handle_ != null) { |
36 core.close(this.handle_); | 30 core.close(this.handle_); |
37 this.handle_ = null; | 31 this.handle_ = null; |
38 } | 32 } |
39 }; | 33 }; |
40 | 34 |
41 Connector.prototype.pauseIncomingMethodCallProcessing = function() { | 35 Connector.prototype.pauseIncomingMethodCallProcessing = function() { |
42 if (this.paused_) { | 36 if (this.paused_) { |
43 return; | 37 return; |
44 } | 38 } |
45 this.paused_= true; | 39 this.paused_= true; |
46 | 40 this.cancelWait(); |
47 if (this.readWatcher_) { | |
48 support.cancelWatch(this.readWatcher_); | |
49 this.readWatcher_ = null; | |
50 } | |
51 }; | 41 }; |
52 | 42 |
53 Connector.prototype.resumeIncomingMethodCallProcessing = function() { | 43 Connector.prototype.resumeIncomingMethodCallProcessing = function() { |
54 if (!this.paused_) { | 44 if (!this.paused_) { |
55 return; | 45 return; |
56 } | 46 } |
57 this.paused_= false; | 47 this.paused_= false; |
58 | 48 this.waitToReadMore(); |
59 if (this.handle_) { | |
60 this.readWatcher_ = support.watch(this.handle_, | |
61 core.HANDLE_SIGNAL_READABLE, | |
62 this.readMore_.bind(this)); | |
63 } | |
64 }; | 49 }; |
65 | 50 |
66 Connector.prototype.accept = function(message) { | 51 Connector.prototype.accept = function(message) { |
67 if (this.error_) | 52 if (this.error_) |
68 return false; | 53 return false; |
69 | 54 |
70 if (this.dropWrites_) | 55 if (this.dropWrites_) |
71 return true; | 56 return true; |
72 | 57 |
73 var result = core.writeMessage(this.handle_, | 58 var result = core.writeMessage(this.handle_, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 return; | 100 return; |
116 } | 101 } |
117 | 102 |
118 var read = core.readMessage(this.handle_, | 103 var read = core.readMessage(this.handle_, |
119 core.READ_MESSAGE_FLAG_NONE); | 104 core.READ_MESSAGE_FLAG_NONE); |
120 if (this.handle_ == null) // The connector has been closed. | 105 if (this.handle_ == null) // The connector has been closed. |
121 return; | 106 return; |
122 if (read.result == core.RESULT_SHOULD_WAIT) | 107 if (read.result == core.RESULT_SHOULD_WAIT) |
123 return; | 108 return; |
124 if (read.result != core.RESULT_OK) { | 109 if (read.result != core.RESULT_OK) { |
125 // TODO(wangjimmy): Add a handleError method to swap the handle to be | 110 this.handleError(read.result !== core.RESULT_FAILED_PRECONDITION, |
126 // closed with a dummy handle in the case when | 111 false); |
127 // read.result != MOJO_RESULT_FAILED_PRECONDITION | |
128 this.error_ = true; | |
129 if (this.errorHandler_) | |
130 this.errorHandler_.onError(); | |
131 return; | 112 return; |
132 } | 113 } |
133 var messageBuffer = new buffer.Buffer(read.buffer); | 114 var messageBuffer = new buffer.Buffer(read.buffer); |
134 var message = new codec.Message(messageBuffer, read.handles); | 115 var message = new codec.Message(messageBuffer, read.handles); |
135 if (this.incomingReceiver_) | 116 var receiverResult = this.incomingReceiver_ && |
136 this.incomingReceiver_.accept(message); | 117 this.incomingReceiver_.accept(message); |
| 118 |
| 119 // Handle invalid incoming message. |
| 120 if (!validator.isTestingMode() && !receiverResult) { |
| 121 // TODO(yzshen): Consider notifying the embedder. |
| 122 this.handleError(true, false); |
| 123 } |
137 } | 124 } |
138 }; | 125 }; |
139 | 126 |
| 127 Connector.prototype.cancelWait = function() { |
| 128 if (this.readWatcher_) { |
| 129 support.cancelWatch(this.readWatcher_); |
| 130 this.readWatcher_ = null; |
| 131 } |
| 132 }; |
| 133 |
| 134 Connector.prototype.waitToReadMore = function() { |
| 135 if (this.handle_) { |
| 136 this.readWatcher_ = support.watch(this.handle_, |
| 137 core.HANDLE_SIGNAL_READABLE, |
| 138 this.readMore_.bind(this)); |
| 139 } |
| 140 }; |
| 141 |
| 142 Connector.prototype.handleError = function(forcePipeReset, |
| 143 forceAsyncHandler) { |
| 144 if (this.error_ || this.handle_ === null) { |
| 145 return; |
| 146 } |
| 147 |
| 148 if (this.paused_) { |
| 149 // Enforce calling the error handler asynchronously if the user has |
| 150 // paused receiving messages. We need to wait until the user starts |
| 151 // receiving messages again. |
| 152 forceAsyncHandler = true; |
| 153 } |
| 154 |
| 155 if (!forcePipeReset && forceAsyncHandler) { |
| 156 forcePipeReset = true; |
| 157 } |
| 158 |
| 159 this.cancelWait(); |
| 160 if (forcePipeReset) { |
| 161 core.close(this.handle_); |
| 162 var dummyPipe = core.createMessagePipe(); |
| 163 this.handle_ = dummyPipe.handle0; |
| 164 } |
| 165 |
| 166 if (forceAsyncHandler) { |
| 167 if (!this.paused_) { |
| 168 this.waitToReadMore(); |
| 169 } |
| 170 } else { |
| 171 this.error_ = true; |
| 172 if (this.errorHandler_) { |
| 173 this.errorHandler_.onError(); |
| 174 } |
| 175 } |
| 176 }; |
| 177 |
140 var exports = {}; | 178 var exports = {}; |
141 exports.Connector = Connector; | 179 exports.Connector = Connector; |
142 return exports; | 180 return exports; |
143 }); | 181 }); |
OLD | NEW |