Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Side by Side Diff: mojo/public/dart/src/handle_watcher.dart

Issue 782693004: Update mojo sdk to rev f6c8ec07c01deebc13178d516225fd12695c3dc2 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: hack mojo_system_impl gypi for android :| Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 27 matching lines...) Expand all
38 // be notified about a handle ready for writing is made the opposite. 38 // be notified about a handle ready for writing is made the opposite.
39 // 39 //
40 // close(handle) - Notifies the HandleWatcherIsolate that a handle it is 40 // close(handle) - Notifies the HandleWatcherIsolate that a handle it is
41 // watching should be removed from its set and closed. 41 // watching should be removed from its set and closed.
42 class MojoHandleWatcher { 42 class MojoHandleWatcher {
43 // Control commands. 43 // Control commands.
44 static const int ADD = 0; 44 static const int ADD = 0;
45 static const int REMOVE = 1; 45 static const int REMOVE = 1;
46 static const int TOGGLE_WRITE = 2; 46 static const int TOGGLE_WRITE = 2;
47 static const int CLOSE = 3; 47 static const int CLOSE = 3;
48 static const int SHUTDOWN = 4; 48 static const int TIMER = 4;
49 static const int SHUTDOWN = 5;
49 50
50 static int _encodeCommand(int cmd, [int signals = 0]) => 51 static int _encodeCommand(int cmd, [int signals = 0]) =>
51 (cmd << 2) | (signals & MojoHandleSignals.READWRITE); 52 (cmd << 2) | (signals & MojoHandleSignals.READWRITE);
52 static int _decodeCommand(int cmd) => cmd >> 2; 53 static int _decodeCommand(int cmd) => cmd >> 2;
53 54
54 // The Mojo handle over which control messages are sent. 55 // The Mojo handle over which control messages are sent.
55 int _controlHandle; 56 int _controlHandle;
56 57
57 // Whether the handle watcher should shut down. 58 // Whether the handle watcher should shut down.
58 bool _shutdown; 59 bool _shutdown;
59 60
60 // The list of handles being watched. 61 // The list of handles being watched.
61 List<int> _handles; 62 List<int> _handles;
62 int _handleCount; 63 int _handleCount;
63 64
64 // A port for each handle on which to send events back to the isolate that 65 // A port for each handle on which to send events back to the isolate that
65 // owns the handle. 66 // owns the handle.
66 List<SendPort> _ports; 67 List<SendPort> _ports;
67 68
68 // The signals that we care about for each handle. 69 // The signals that we care about for each handle.
69 List<int> _signals; 70 List<int> _signals;
70 71
71 // A mapping from Mojo handles to their indices in _handles. 72 // A mapping from Mojo handles to their indices in _handles.
72 Map<int, int> _handleIndices; 73 Map<int, int> _handleIndices;
73 74
74 // Since we are not storing wrapped handles, a dummy handle for when we need 75 // Since we are not storing wrapped handles, a dummy handle for when we need
75 // a RawMojoHandle. 76 // a RawMojoHandle.
76 RawMojoHandle _tempHandle; 77 RawMojoHandle _tempHandle;
77 78
79 // Priority queue of timers registered with the watcher.
80 TimerQueue _timerQueue;
81
78 MojoHandleWatcher(this._controlHandle) : 82 MojoHandleWatcher(this._controlHandle) :
79 _shutdown = false, 83 _shutdown = false,
80 _handles = new List<int>(), 84 _handles = new List<int>(),
81 _ports = new List<SendPort>(), 85 _ports = new List<SendPort>(),
82 _signals = new List<int>(), 86 _signals = new List<int>(),
83 _handleIndices = new Map<int, int>(), 87 _handleIndices = new Map<int, int>(),
84 _handleCount = 1, 88 _handleCount = 1,
85 _tempHandle = new RawMojoHandle(RawMojoHandle.INVALID) { 89 _tempHandle = new RawMojoHandle(RawMojoHandle.INVALID),
90 _timerQueue = new TimerQueue() {
86 // Setup control handle. 91 // Setup control handle.
87 _handles.add(_controlHandle); 92 _handles.add(_controlHandle);
88 _ports.add(null); // There is no port for the control handle. 93 _ports.add(null); // There is no port for the control handle.
89 _signals.add(MojoHandleSignals.READABLE); 94 _signals.add(MojoHandleSignals.READABLE);
90 _handleIndices[_controlHandle] = 0; 95 _handleIndices[_controlHandle] = 0;
91 } 96 }
92 97
93 static void _handleWatcherIsolate(MojoHandleWatcher watcher) { 98 static void _handleWatcherIsolate(int consumerHandle) {
99 MojoHandleWatcher watcher = new MojoHandleWatcher(consumerHandle);
94 while (!watcher._shutdown) { 100 while (!watcher._shutdown) {
101 int deadline = watcher._processTimerDeadlines();
95 int res = RawMojoHandle.waitMany(watcher._handles, 102 int res = RawMojoHandle.waitMany(watcher._handles,
96 watcher._signals, 103 watcher._signals,
97 RawMojoHandle.DEADLINE_INDEFINITE); 104 deadline);
98 if (res == 0) { 105 if (res == 0) {
99 watcher._handleControlMessage(); 106 watcher._handleControlMessage();
100 } else if (res > 0) { 107 } else if (res > 0) {
101 int handle = watcher._handles[res]; 108 int handle = watcher._handles[res];
102 // Route event. 109 // Route event.
103 watcher._routeEvent(res); 110 watcher._routeEvent(res);
104 // Remove the handle from the list. 111 // Remove the handle from the list.
105 watcher._removeHandle(handle); 112 watcher._removeHandle(handle);
106 } else { 113 } else if (res != MojoResult.kDeadlineExceeded) {
107 // Some handle was closed, but not by us. 114 // Some handle was closed, but not by us.
108 // We have to go through the list and find it. 115 // We have to go through the list and find it.
109 watcher._pruneClosedHandles(); 116 watcher._pruneClosedHandles();
110 } 117 }
111 } 118 }
112 } 119 }
113 120
114 void _routeEvent(int idx) { 121 void _routeEvent(int idx) {
115 int client_handle = _handles[idx]; 122 int client_handle = _handles[idx];
116 int signals = _signals[idx]; 123 int signals = _signals[idx];
117 SendPort port = _ports[idx]; 124 SendPort port = _ports[idx];
118 125
119 _tempHandle.h = client_handle; 126 _tempHandle.h = client_handle;
120 bool readyWrite = 127 bool readyWrite =
121 MojoHandleSignals.isWritable(signals) && _tempHandle.readyWrite(); 128 MojoHandleSignals.isWritable(signals) && _tempHandle.readyWrite();
122 bool readyRead = 129 bool readyRead =
123 MojoHandleSignals.isReadable(signals) && _tempHandle.readyRead(); 130 MojoHandleSignals.isReadable(signals) && _tempHandle.readyRead();
124 if (readyRead && readyWrite) { 131 if (readyRead && readyWrite) {
125 port.send(MojoHandleSignals.READWRITE); 132 port.send(MojoHandleSignals.READWRITE);
126 } else if (readyWrite) { 133 } else if (readyWrite) {
127 port.send(MojoHandleSignals.WRITABLE); 134 port.send(MojoHandleSignals.WRITABLE);
128 } else if (readyRead) { 135 } else if (readyRead) {
129 port.send(MojoHandleSignals.READABLE); 136 port.send(MojoHandleSignals.READABLE);
130 } 137 }
131 _tempHandle.h = RawMojoHandle.INVALID; 138 _tempHandle.h = RawMojoHandle.INVALID;
132 } 139 }
133 140
134 void _handleControlMessage() { 141 void _handleControlMessage() {
135 List result = _MojoHandleWatcherNatives.recvControlData(_controlHandle); 142 List result = _MojoHandleWatcherNatives.recvControlData(_controlHandle);
136 // result[0] = mojo handle if any 143 // result[0] = mojo handle if any, or a timer deadline in milliseconds.
137 // result[1] = SendPort if any 144 // result[1] = SendPort if any.
138 // result[2] = command << 2 | WRITABLE | READABLE 145 // result[2] = command << 2 | WRITABLE | READABLE
139 146
140 int signals = result[2] & MojoHandleSignals.READWRITE; 147 int signals = result[2] & MojoHandleSignals.READWRITE;
141 int command = _decodeCommand(result[2]); 148 int command = _decodeCommand(result[2]);
142 switch (command) { 149 switch (command) {
143 case ADD: 150 case ADD:
144 _addHandle(result[0], result[1], signals); 151 _addHandle(result[0], result[1], signals);
145 break; 152 break;
146 case REMOVE: 153 case REMOVE:
147 _removeHandle(result[0]); 154 _removeHandle(result[0]);
148 break; 155 break;
149 case TOGGLE_WRITE: 156 case TOGGLE_WRITE:
150 _toggleWrite(result[0]); 157 _toggleWrite(result[0]);
151 break; 158 break;
152 case CLOSE: 159 case CLOSE:
153 _close(result[0]); 160 _close(result[0]);
154 break; 161 break;
162 case TIMER:
163 _timer(result[1], result[0]);
164 break;
155 case SHUTDOWN: 165 case SHUTDOWN:
156 _shutdownHandleWatcher(); 166 _shutdownHandleWatcher();
157 break; 167 break;
158 default: 168 default:
159 throw new Exception("Invalid Command: $command"); 169 throw new Exception("Invalid Command: $command");
160 break; 170 break;
161 } 171 }
162 } 172 }
163 173
164 void _addHandle(int mojoHandle, SendPort port, int signals) { 174 void _addHandle(int mojoHandle, SendPort port, int signals) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 _tempHandle.close(); 220 _tempHandle.close();
211 _tempHandle.h = RawMojoHandle.INVALID; 221 _tempHandle.h = RawMojoHandle.INVALID;
212 if (pruning) { 222 if (pruning) {
213 // If this handle is being pruned, notify the application isolate 223 // If this handle is being pruned, notify the application isolate
214 // by sending MojoHandleSignals.NONE. 224 // by sending MojoHandleSignals.NONE.
215 _ports[idx].send(MojoHandleSignals.NONE); 225 _ports[idx].send(MojoHandleSignals.NONE);
216 } 226 }
217 _removeHandle(mojoHandle); 227 _removeHandle(mojoHandle);
218 } 228 }
219 229
230 // Returns the next timer deadline in units of microseconds from 'now'.
231 int _processTimerDeadlines() {
232 int now = (new DateTime.now()).millisecondsSinceEpoch;
233 while (_timerQueue.hasTimer && (now >= _timerQueue.currentTimeout)) {
234 _timerQueue.currentPort.send(null);
235 _timerQueue.removeCurrent();
236 now = (new DateTime.now()).millisecondsSinceEpoch;
237 }
238 return _timerQueue.hasTimer ? (_timerQueue.currentTimeout - now) * 1000
239 : RawMojoHandle.DEADLINE_INDEFINITE;
240 }
241
242 void _timer(SendPort port, int deadline) {
243 _timerQueue.updateTimer(port, deadline);
244 }
245
220 void _toggleWrite(int mojoHandle) { 246 void _toggleWrite(int mojoHandle) {
221 int idx = _handleIndices[mojoHandle]; 247 int idx = _handleIndices[mojoHandle];
222 if (idx == null) { 248 if (idx == null) {
223 throw new Exception( 249 throw new Exception(
224 "Toggle write on a non-existent handle: $mojoHandle."); 250 "Toggle write on a non-existent handle: $mojoHandle.");
225 } 251 }
226 if (idx == 0) { 252 if (idx == 0) {
227 throw new Exception("The control handle (idx = 0) cannot be toggled."); 253 throw new Exception("The control handle (idx = 0) cannot be toggled.");
228 } 254 }
229 _signals[idx] = MojoHandleSignals.toggleWrite(_signals[idx]); 255 _signals[idx] = MojoHandleSignals.toggleWrite(_signals[idx]);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 controlHandle, rawHandle, port, data); 293 controlHandle, rawHandle, port, data);
268 return new MojoResult(result); 294 return new MojoResult(result);
269 } 295 }
270 296
271 static Future<Isolate> Start() { 297 static Future<Isolate> Start() {
272 // Make a control message pipe, 298 // Make a control message pipe,
273 MojoMessagePipe pipe = new MojoMessagePipe(); 299 MojoMessagePipe pipe = new MojoMessagePipe();
274 int consumerHandle = pipe.endpoints[0].handle.h; 300 int consumerHandle = pipe.endpoints[0].handle.h;
275 int producerHandle = pipe.endpoints[1].handle.h; 301 int producerHandle = pipe.endpoints[1].handle.h;
276 302
277 // Make a MojoHandleWatcher with one end.
278 MojoHandleWatcher watcher = new MojoHandleWatcher(consumerHandle);
279
280 // Call setControlHandle with the other end. 303 // Call setControlHandle with the other end.
281 _MojoHandleWatcherNatives.setControlHandle(producerHandle); 304 _MojoHandleWatcherNatives.setControlHandle(producerHandle);
282 305
283 // Spawn the handle watcher isolate with the MojoHandleWatcher, 306 // Spawn the handle watcher isolate with the MojoHandleWatcher,
284 return Isolate.spawn(_handleWatcherIsolate, watcher); 307 return Isolate.spawn(_handleWatcherIsolate, consumerHandle);
285 } 308 }
286 309
287 static void Stop() { 310 static void Stop() {
288 // Send the shutdown command. 311 // Send the shutdown command.
289 _sendControlData(null, null, _encodeCommand(SHUTDOWN)); 312 _sendControlData(null, null, _encodeCommand(SHUTDOWN));
290 313
291 // Close the control handle. 314 // Close the control handle.
292 int controlHandle = _MojoHandleWatcherNatives.getControlHandle(); 315 int controlHandle = _MojoHandleWatcherNatives.getControlHandle();
293 var handle = new RawMojoHandle(controlHandle); 316 var handle = new RawMojoHandle(controlHandle);
294 handle.close(); 317 handle.close();
318
319 // Invalidate the control handle.
320 _MojoHandleWatcherNatives.setControlHandle(RawMojoHandle.INVALID);
295 } 321 }
296 322
297 static MojoResult close(RawMojoHandle mojoHandle) { 323 static MojoResult close(RawMojoHandle mojoHandle) {
298 return _sendControlData(mojoHandle, null, _encodeCommand(CLOSE)); 324 return _sendControlData(mojoHandle, null, _encodeCommand(CLOSE));
299 } 325 }
300 326
301 static MojoResult toggleWrite(RawMojoHandle mojoHandle) { 327 static MojoResult toggleWrite(RawMojoHandle mojoHandle) {
302 return _sendControlData(mojoHandle, null, _encodeCommand(TOGGLE_WRITE)); 328 return _sendControlData(mojoHandle, null, _encodeCommand(TOGGLE_WRITE));
303 } 329 }
304 330
305 static MojoResult add(RawMojoHandle mojoHandle, SendPort port, int signals) { 331 static MojoResult add(RawMojoHandle mojoHandle, SendPort port, int signals) {
306 return _sendControlData(mojoHandle, port, _encodeCommand(ADD, signals)); 332 return _sendControlData(mojoHandle, port, _encodeCommand(ADD, signals));
307 } 333 }
308 334
309 static MojoResult remove(RawMojoHandle mojoHandle) { 335 static MojoResult remove(RawMojoHandle mojoHandle) {
310 return _sendControlData(mojoHandle, null, _encodeCommand(REMOVE)); 336 return _sendControlData(mojoHandle, null, _encodeCommand(REMOVE));
311 } 337 }
338
339 static MojoResult timer(SendPort port, int deadline) {
340 // The deadline will be unwrapped before sending to the handle watcher.
341 return _sendControlData(
342 new RawMojoHandle(deadline), port, _encodeCommand(TIMER));
343 }
312 } 344 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698