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 part of core; | 5 part of core; |
6 | 6 |
7 class _MojoHandleWatcherNatives { | 7 class _MojoHandleWatcherNatives { |
8 static int sendControlData( | 8 static int sendControlData( |
9 int controlHandle, int mojoHandle, SendPort port, int data) | 9 int controlHandle, int mojoHandle, SendPort port, int data) |
10 native "MojoHandleWatcher_SendControlData"; | 10 native "MojoHandleWatcher_SendControlData"; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
92 _handles.add(_controlHandle); | 92 _handles.add(_controlHandle); |
93 _ports.add(null); // There is no port for the control handle. | 93 _ports.add(null); // There is no port for the control handle. |
94 _signals.add(MojoHandleSignals.READABLE); | 94 _signals.add(MojoHandleSignals.READABLE); |
95 _handleIndices[_controlHandle] = 0; | 95 _handleIndices[_controlHandle] = 0; |
96 } | 96 } |
97 | 97 |
98 static void _handleWatcherIsolate(int consumerHandle) { | 98 static void _handleWatcherIsolate(int consumerHandle) { |
99 MojoHandleWatcher watcher = new MojoHandleWatcher(consumerHandle); | 99 MojoHandleWatcher watcher = new MojoHandleWatcher(consumerHandle); |
100 while (!watcher._shutdown) { | 100 while (!watcher._shutdown) { |
101 int deadline = watcher._processTimerDeadlines(); | 101 int deadline = watcher._processTimerDeadlines(); |
102 int res = RawMojoHandle.waitMany(watcher._handles, | 102 MojoWaitManyResult res = RawMojoHandle.waitMany(watcher._handles, |
103 watcher._signals, | 103 watcher._signals, |
104 deadline); | 104 deadline); |
105 if (res == 0) { | 105 if (res.result.isOk && res.index == 0) { |
106 watcher._handleControlMessage(); | 106 watcher._handleControlMessage(); |
107 } else if (res > 0) { | 107 } else if (res.result.isOk && res.index > 0) { |
108 int handle = watcher._handles[res]; | 108 int handle = watcher._handles[res.index]; |
109 // Route event. | 109 // Route event. |
110 watcher._routeEvent(res); | 110 watcher._routeEvent(res.index); |
111 // Remove the handle from the list. | 111 // Remove the handle from the list. |
112 watcher._removeHandle(handle); | 112 watcher._removeHandle(handle); |
113 } else if (res != MojoResult.kDeadlineExceeded) { | 113 } else if (res.areSignalStatesValid) { |
114 // Some handle was closed, but not by us. | 114 // Some handle was closed, but not by us. |
115 // We have to go through the list and find it. | 115 // Find it and close it on our side. |
116 watcher._pruneClosedHandles(); | 116 watcher._pruneClosedHandles(res.states); |
117 } | 117 } |
118 } | 118 } |
119 } | 119 } |
120 | 120 |
121 void _routeEvent(int idx) { | 121 void _routeEvent(int idx) { |
122 int client_handle = _handles[idx]; | 122 int client_handle = _handles[idx]; |
123 int signals = _signals[idx]; | 123 int signals = _signals[idx]; |
124 SendPort port = _ports[idx]; | 124 SendPort port = _ports[idx]; |
125 | 125 |
126 _tempHandle.h = client_handle; | 126 _tempHandle.h = client_handle; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
248 if (idx == null) { | 248 if (idx == null) { |
249 throw new Exception( | 249 throw new Exception( |
250 "Toggle write on a non-existent handle: $mojoHandle."); | 250 "Toggle write on a non-existent handle: $mojoHandle."); |
251 } | 251 } |
252 if (idx == 0) { | 252 if (idx == 0) { |
253 throw new Exception("The control handle (idx = 0) cannot be toggled."); | 253 throw new Exception("The control handle (idx = 0) cannot be toggled."); |
254 } | 254 } |
255 _signals[idx] = MojoHandleSignals.toggleWrite(_signals[idx]); | 255 _signals[idx] = MojoHandleSignals.toggleWrite(_signals[idx]); |
256 } | 256 } |
257 | 257 |
258 void _pruneClosedHandles() { | 258 void _pruneClosedHandles(List<MojoHandleSignalsState> states) { |
259 List<int> closed = new List(); | 259 List<int> closed = new List(); |
260 for (var h in _handles) { | 260 for (var i=0; i<_handles.length; i++) { |
261 _tempHandle.h = h; | 261 if (MojoHandleSignals.isPeerClosed(states[i].satisfied_signals)) { |
262 MojoResult res = _tempHandle.wait(MojoHandleSignals.READWRITE, 0); | 262 closed.add(_handles[i]); |
263 if ((!res.isOk) && (!res.isDeadlineExceeded)) { | |
264 closed.add(h); | |
265 } | 263 } |
266 _tempHandle.h = RawMojoHandle.INVALID; | |
267 } | 264 } |
268 for (var h in closed) { | 265 for (var h in closed) { |
269 _close(h, pruning: true); | 266 _close(h, pruning: true); |
270 } | 267 } |
268 // _close updated the _handles array, so at this point the _handles array | |
269 // and the signals array are mismatched. | |
zra
2015/01/08 17:23:11
This is not correct. _close() calls _removeHandle(
jimbe
2015/01/08 17:38:21
Poor choice of words. There are two separate signa
| |
271 } | 270 } |
272 | 271 |
273 void _shutdownHandleWatcher() { | 272 void _shutdownHandleWatcher() { |
274 _shutdown = true; | 273 _shutdown = true; |
275 _tempHandle.h = _controlHandle; | 274 _tempHandle.h = _controlHandle; |
276 _tempHandle.close(); | 275 _tempHandle.close(); |
277 _tempHandle.h = RawMojoHandle.INVALID; | 276 _tempHandle.h = RawMojoHandle.INVALID; |
278 } | 277 } |
279 | 278 |
280 static MojoResult _sendControlData(RawMojoHandle mojoHandle, | 279 static MojoResult _sendControlData(RawMojoHandle mojoHandle, |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
335 static MojoResult remove(RawMojoHandle mojoHandle) { | 334 static MojoResult remove(RawMojoHandle mojoHandle) { |
336 return _sendControlData(mojoHandle, null, _encodeCommand(REMOVE)); | 335 return _sendControlData(mojoHandle, null, _encodeCommand(REMOVE)); |
337 } | 336 } |
338 | 337 |
339 static MojoResult timer(SendPort port, int deadline) { | 338 static MojoResult timer(SendPort port, int deadline) { |
340 // The deadline will be unwrapped before sending to the handle watcher. | 339 // The deadline will be unwrapped before sending to the handle watcher. |
341 return _sendControlData( | 340 return _sendControlData( |
342 new RawMojoHandle(deadline), port, _encodeCommand(TIMER)); | 341 new RawMojoHandle(deadline), port, _encodeCommand(TIMER)); |
343 } | 342 } |
344 } | 343 } |
OLD | NEW |