| 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 15 matching lines...) Expand all Loading... |
| 26 // | 26 // |
| 27 // add(handle, port, signals) - Instructs the MojoHandleWatcher isolate to add | 27 // add(handle, port, signals) - Instructs the MojoHandleWatcher isolate to add |
| 28 // 'handle' to the set of handles it watches, and to notify the calling | 28 // 'handle' to the set of handles it watches, and to notify the calling |
| 29 // isolate only for the events specified by 'signals' using the send port | 29 // isolate only for the events specified by 'signals' using the send port |
| 30 // 'port' | 30 // 'port' |
| 31 // | 31 // |
| 32 // remove(handle) - Instructs the MojoHandleWatcher isolate to remove 'handle' | 32 // remove(handle) - Instructs the MojoHandleWatcher isolate to remove 'handle' |
| 33 // from the set of handles it watches. This allows the application isolate | 33 // from the set of handles it watches. This allows the application isolate |
| 34 // to, e.g., pause the stream of events. | 34 // to, e.g., pause the stream of events. |
| 35 // | 35 // |
| 36 // toggleWrite(handle) - Modifies the set of signals that an application isolate | |
| 37 // wishes to be notified about. Whether the application isolate should be | |
| 38 // be notified about a handle ready for writing is made the opposite. | |
| 39 // | |
| 40 // close(handle) - Notifies the HandleWatcherIsolate that a handle it is | 36 // close(handle) - Notifies the HandleWatcherIsolate that a handle it is |
| 41 // watching should be removed from its set and closed. | 37 // watching should be removed from its set and closed. |
| 42 class MojoHandleWatcher { | 38 class MojoHandleWatcher { |
| 43 // Control commands. | 39 // Control commands. |
| 44 static const int ADD = 0; | 40 static const int ADD = 0; |
| 45 static const int REMOVE = 1; | 41 static const int REMOVE = 1; |
| 46 static const int TOGGLE_WRITE = 2; | 42 static const int CLOSE = 2; |
| 47 static const int CLOSE = 3; | 43 static const int TIMER = 3; |
| 48 static const int TIMER = 4; | 44 static const int SHUTDOWN = 4; |
| 49 static const int SHUTDOWN = 5; | |
| 50 | 45 |
| 51 static int _encodeCommand(int cmd, [int signals = 0]) => | 46 static int _encodeCommand(int cmd, [int signals = 0]) => |
| 52 (cmd << 2) | (signals & MojoHandleSignals.READWRITE); | 47 (cmd << 2) | (signals & MojoHandleSignals.kReadWrite); |
| 53 static int _decodeCommand(int cmd) => cmd >> 2; | 48 static int _decodeCommand(int cmd) => cmd >> 2; |
| 54 | 49 |
| 55 // The Mojo handle over which control messages are sent. | 50 // The Mojo handle over which control messages are sent. |
| 56 int _controlHandle; | 51 int _controlHandle; |
| 57 | 52 |
| 58 // Whether the handle watcher should shut down. | 53 // Whether the handle watcher should shut down. |
| 59 bool _shutdown; | 54 bool _shutdown; |
| 60 | 55 |
| 61 // The list of handles being watched. | 56 // The list of handles being watched. |
| 62 List<int> _handles; | 57 List<int> _handles; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 84 _handles = new List<int>(), | 79 _handles = new List<int>(), |
| 85 _ports = new List<SendPort>(), | 80 _ports = new List<SendPort>(), |
| 86 _signals = new List<int>(), | 81 _signals = new List<int>(), |
| 87 _handleIndices = new Map<int, int>(), | 82 _handleIndices = new Map<int, int>(), |
| 88 _handleCount = 1, | 83 _handleCount = 1, |
| 89 _tempHandle = new RawMojoHandle(RawMojoHandle.INVALID), | 84 _tempHandle = new RawMojoHandle(RawMojoHandle.INVALID), |
| 90 _timerQueue = new TimerQueue() { | 85 _timerQueue = new TimerQueue() { |
| 91 // Setup control handle. | 86 // Setup control handle. |
| 92 _handles.add(_controlHandle); | 87 _handles.add(_controlHandle); |
| 93 _ports.add(null); // There is no port for the control handle. | 88 _ports.add(null); // There is no port for the control handle. |
| 94 _signals.add(MojoHandleSignals.READABLE); | 89 _signals.add(MojoHandleSignals.kReadable); |
| 95 _handleIndices[_controlHandle] = 0; | 90 _handleIndices[_controlHandle] = 0; |
| 96 } | 91 } |
| 97 | 92 |
| 98 static void _handleWatcherIsolate(int consumerHandle) { | 93 static void _handleWatcherIsolate(int consumerHandle) { |
| 99 MojoHandleWatcher watcher = new MojoHandleWatcher(consumerHandle); | 94 MojoHandleWatcher watcher = new MojoHandleWatcher(consumerHandle); |
| 100 while (!watcher._shutdown) { | 95 while (!watcher._shutdown) { |
| 101 int deadline = watcher._processTimerDeadlines(); | 96 int deadline = watcher._processTimerDeadlines(); |
| 102 int res = RawMojoHandle.waitMany(watcher._handles, | 97 int res = RawMojoHandle.waitMany(watcher._handles, |
| 103 watcher._signals, | 98 watcher._signals, |
| 104 deadline); | 99 deadline); |
| 105 if (res == 0) { | 100 if (res == 0) { |
| 106 watcher._handleControlMessage(); | 101 watcher._handleControlMessage(); |
| 107 } else if (res > 0) { | 102 } else if (res > 0) { |
| 108 int handle = watcher._handles[res]; | 103 int handle = watcher._handles[res]; |
| 109 // Route event. | 104 // Route event. |
| 110 watcher._routeEvent(res); | 105 watcher._routeEvent(res); |
| 111 // Remove the handle from the list. | 106 // Remove the handle from the list. |
| 112 watcher._removeHandle(handle); | 107 watcher._removeHandle(handle); |
| 113 } else if (res != MojoResult.kDeadlineExceeded) { | 108 } else if (res != MojoResult.kDeadlineExceeded) { |
| 109 var result = new MojoResult(res); |
| 114 // Some handle was closed, but not by us. | 110 // Some handle was closed, but not by us. |
| 115 // We have to go through the list and find it. | 111 // We have to go through the list and find it. |
| 116 watcher._pruneClosedHandles(); | 112 watcher._pruneClosedHandles(); |
| 117 } | 113 } |
| 118 } | 114 } |
| 119 } | 115 } |
| 120 | 116 |
| 121 void _routeEvent(int idx) { | 117 void _routeEvent(int idx) { |
| 122 int client_handle = _handles[idx]; | 118 int client_handle = _handles[idx]; |
| 123 int signals = _signals[idx]; | 119 var signals = new MojoHandleSignals(_signals[idx]); |
| 124 SendPort port = _ports[idx]; | 120 SendPort port = _ports[idx]; |
| 125 | 121 |
| 126 _tempHandle.h = client_handle; | 122 _tempHandle.h = client_handle; |
| 127 bool readyWrite = | 123 bool readyWrite = signals.isWritable && _tempHandle.readyWrite; |
| 128 MojoHandleSignals.isWritable(signals) && _tempHandle.readyWrite(); | 124 bool readyRead = signals.isReadable && _tempHandle.readyRead; |
| 129 bool readyRead = | |
| 130 MojoHandleSignals.isReadable(signals) && _tempHandle.readyRead(); | |
| 131 if (readyRead && readyWrite) { | |
| 132 port.send(MojoHandleSignals.READWRITE); | |
| 133 } else if (readyWrite) { | |
| 134 port.send(MojoHandleSignals.WRITABLE); | |
| 135 } else if (readyRead) { | |
| 136 port.send(MojoHandleSignals.READABLE); | |
| 137 } | |
| 138 _tempHandle.h = RawMojoHandle.INVALID; | 125 _tempHandle.h = RawMojoHandle.INVALID; |
| 126 |
| 127 var event = MojoHandleSignals.NONE; |
| 128 event += readyRead ? MojoHandleSignals.READABLE : MojoHandleSignals.NONE; |
| 129 event += readyWrite ? MojoHandleSignals.WRITABLE : MojoHandleSignals.NONE; |
| 130 port.send([signals.value, event.value]); |
| 139 } | 131 } |
| 140 | 132 |
| 141 void _handleControlMessage() { | 133 void _handleControlMessage() { |
| 142 List result = _MojoHandleWatcherNatives.recvControlData(_controlHandle); | 134 List result = _MojoHandleWatcherNatives.recvControlData(_controlHandle); |
| 143 // result[0] = mojo handle if any, or a timer deadline in milliseconds. | 135 // result[0] = mojo handle if any, or a timer deadline in milliseconds. |
| 144 // result[1] = SendPort if any. | 136 // result[1] = SendPort if any. |
| 145 // result[2] = command << 2 | WRITABLE | READABLE | 137 // result[2] = command << 2 | WRITABLE | READABLE |
| 146 | 138 |
| 147 int signals = result[2] & MojoHandleSignals.READWRITE; | 139 var signals = new MojoHandleSignals( |
| 140 result[2] & MojoHandleSignals.kReadWrite); |
| 148 int command = _decodeCommand(result[2]); | 141 int command = _decodeCommand(result[2]); |
| 149 switch (command) { | 142 switch (command) { |
| 150 case ADD: | 143 case ADD: |
| 151 _addHandle(result[0], result[1], signals); | 144 _addHandle(result[0], result[1], signals); |
| 152 break; | 145 break; |
| 153 case REMOVE: | 146 case REMOVE: |
| 154 _removeHandle(result[0]); | 147 _removeHandle(result[0]); |
| 155 break; | 148 break; |
| 156 case TOGGLE_WRITE: | |
| 157 _toggleWrite(result[0]); | |
| 158 break; | |
| 159 case CLOSE: | 149 case CLOSE: |
| 160 _close(result[0]); | 150 _close(result[0]); |
| 161 break; | 151 break; |
| 162 case TIMER: | 152 case TIMER: |
| 163 _timer(result[1], result[0]); | 153 _timer(result[1], result[0]); |
| 164 break; | 154 break; |
| 165 case SHUTDOWN: | 155 case SHUTDOWN: |
| 166 _shutdownHandleWatcher(); | 156 _shutdownHandleWatcher(result[1]); |
| 167 break; | 157 break; |
| 168 default: | 158 default: |
| 169 throw new Exception("Invalid Command: $command"); | 159 throw "Invalid Command: $command"; |
| 170 break; | 160 break; |
| 171 } | 161 } |
| 172 } | 162 } |
| 173 | 163 |
| 174 void _addHandle(int mojoHandle, SendPort port, int signals) { | 164 void _addHandle(int mojoHandle, SendPort port, MojoHandleSignals signals) { |
| 175 _handles.add(mojoHandle); | 165 int idx = _handleIndices[mojoHandle]; |
| 176 _ports.add(port); | 166 if (idx == null) { |
| 177 _signals.add(signals & MojoHandleSignals.READWRITE); | 167 _handles.add(mojoHandle); |
| 178 _handleIndices[mojoHandle] = _handleCount; | 168 _ports.add(port); |
| 179 _handleCount++; | 169 _signals.add(signals.value); |
| 170 _handleIndices[mojoHandle] = _handleCount; |
| 171 _handleCount++; |
| 172 } else { |
| 173 assert(_ports[idx] == port); |
| 174 assert(_handles[idx] == mojoHandle); |
| 175 _signals[idx] |= signals.value; |
| 176 } |
| 180 } | 177 } |
| 181 | 178 |
| 182 void _removeHandle(int mojoHandle) { | 179 void _removeHandle(int mojoHandle) { |
| 183 int idx = _handleIndices[mojoHandle]; | 180 int idx = _handleIndices[mojoHandle]; |
| 184 if (idx == null) { | 181 if (idx == null) { |
| 185 throw new Exception("Remove on a non-existent handle: idx = $idx."); | 182 throw "Remove on a non-existent handle: idx = $idx."; |
| 186 } | 183 } |
| 187 if (idx == 0) { | 184 if (idx == 0) { |
| 188 throw new Exception("The control handle (idx = 0) cannot be removed."); | 185 throw "The control handle (idx = 0) cannot be removed."; |
| 189 } | 186 } |
| 190 // We don't use List.removeAt so that we know how to fix-up _handleIndices. | 187 // We don't use List.removeAt so that we know how to fix-up _handleIndices. |
| 191 if (idx == _handleCount - 1) { | 188 if (idx == _handleCount - 1) { |
| 192 int handle = _handles[idx]; | 189 int handle = _handles[idx]; |
| 193 _handleIndices[handle] = null; | 190 _handleIndices[handle] = null; |
| 194 _handles.removeLast(); | 191 _handles.removeLast(); |
| 195 _signals.removeLast(); | 192 _signals.removeLast(); |
| 196 _ports.removeLast(); | 193 _ports.removeLast(); |
| 197 _handleCount--; | 194 _handleCount--; |
| 198 } else { | 195 } else { |
| 199 int last = _handleCount - 1; | 196 int last = _handleCount - 1; |
| 197 _handleIndices[_handles[idx]] = null; |
| 200 _handles[idx] = _handles[last]; | 198 _handles[idx] = _handles[last]; |
| 201 _signals[idx] = _signals[last]; | 199 _signals[idx] = _signals[last]; |
| 202 _ports[idx] = _ports[last]; | 200 _ports[idx] = _ports[last]; |
| 203 _handles.removeLast(); | 201 _handles.removeLast(); |
| 204 _signals.removeLast(); | 202 _signals.removeLast(); |
| 205 _ports.removeLast(); | 203 _ports.removeLast(); |
| 206 _handleIndices[_handles[idx]] = idx; | 204 _handleIndices[_handles[idx]] = idx; |
| 207 _handleCount--; | 205 _handleCount--; |
| 208 } | 206 } |
| 209 } | 207 } |
| 210 | 208 |
| 211 void _close(int mojoHandle, {bool pruning : false}) { | 209 void _close(int mojoHandle, {bool pruning : false}) { |
| 212 int idx = _handleIndices[mojoHandle]; | 210 int idx = _handleIndices[mojoHandle]; |
| 213 if (idx == null) { | 211 if (idx == null) { |
| 214 throw new Exception("Close on a non-existent handle: idx = $idx."); | 212 // A client may request to close a handle that has already been closed on |
| 213 // the other side and pruned, but before receiving notification from the |
| 214 // handle watcher. |
| 215 return; |
| 215 } | 216 } |
| 216 if (idx == 0) { | 217 if (idx == 0) { |
| 217 throw new Exception("The control handle (idx = 0) cannot be closed."); | 218 throw "The control handle (idx = 0) cannot be closed."; |
| 218 } | 219 } |
| 219 _tempHandle.h = _handles[idx]; | 220 _tempHandle.h = _handles[idx]; |
| 220 _tempHandle.close(); | 221 _tempHandle.close(); |
| 221 _tempHandle.h = RawMojoHandle.INVALID; | 222 _tempHandle.h = RawMojoHandle.INVALID; |
| 222 if (pruning) { | 223 if (pruning) { |
| 223 // If this handle is being pruned, notify the application isolate | 224 // If this handle is being pruned, notify the application isolate |
| 224 // by sending MojoHandleSignals.NONE. | 225 // by sending MojoHandleSignals.PEER_CLOSED. |
| 225 _ports[idx].send(MojoHandleSignals.NONE); | 226 _ports[idx].send([_signals[idx], MojoHandleSignals.kPeerClosed]); |
| 226 } | 227 } |
| 227 _removeHandle(mojoHandle); | 228 _removeHandle(mojoHandle); |
| 228 } | 229 } |
| 229 | 230 |
| 230 // Returns the next timer deadline in units of microseconds from 'now'. | 231 // Returns the next timer deadline in units of microseconds from 'now'. |
| 231 int _processTimerDeadlines() { | 232 int _processTimerDeadlines() { |
| 232 int now = (new DateTime.now()).millisecondsSinceEpoch; | 233 int now = (new DateTime.now()).millisecondsSinceEpoch; |
| 233 while (_timerQueue.hasTimer && (now >= _timerQueue.currentTimeout)) { | 234 while (_timerQueue.hasTimer && (now >= _timerQueue.currentTimeout)) { |
| 234 _timerQueue.currentPort.send(null); | 235 _timerQueue.currentPort.send(null); |
| 235 _timerQueue.removeCurrent(); | 236 _timerQueue.removeCurrent(); |
| 236 now = (new DateTime.now()).millisecondsSinceEpoch; | 237 now = (new DateTime.now()).millisecondsSinceEpoch; |
| 237 } | 238 } |
| 238 return _timerQueue.hasTimer ? (_timerQueue.currentTimeout - now) * 1000 | 239 return _timerQueue.hasTimer ? (_timerQueue.currentTimeout - now) * 1000 |
| 239 : RawMojoHandle.DEADLINE_INDEFINITE; | 240 : RawMojoHandle.DEADLINE_INDEFINITE; |
| 240 } | 241 } |
| 241 | 242 |
| 242 void _timer(SendPort port, int deadline) { | 243 void _timer(SendPort port, int deadline) { |
| 243 _timerQueue.updateTimer(port, deadline); | 244 _timerQueue.updateTimer(port, deadline); |
| 244 } | 245 } |
| 245 | 246 |
| 246 void _toggleWrite(int mojoHandle) { | |
| 247 int idx = _handleIndices[mojoHandle]; | |
| 248 if (idx == null) { | |
| 249 throw new Exception( | |
| 250 "Toggle write on a non-existent handle: $mojoHandle."); | |
| 251 } | |
| 252 if (idx == 0) { | |
| 253 throw new Exception("The control handle (idx = 0) cannot be toggled."); | |
| 254 } | |
| 255 _signals[idx] = MojoHandleSignals.toggleWrite(_signals[idx]); | |
| 256 } | |
| 257 | |
| 258 void _pruneClosedHandles() { | 247 void _pruneClosedHandles() { |
| 259 List<int> closed = new List(); | 248 List<int> closed = new List(); |
| 260 for (var h in _handles) { | 249 for (var h in _handles) { |
| 261 _tempHandle.h = h; | 250 _tempHandle.h = h; |
| 262 MojoResult res = _tempHandle.wait(MojoHandleSignals.READWRITE, 0); | 251 MojoResult res = _tempHandle.wait(MojoHandleSignals.kReadWrite, 0); |
| 263 if ((!res.isOk) && (!res.isDeadlineExceeded)) { | 252 if ((!res.isOk) && (!res.isDeadlineExceeded)) { |
| 264 closed.add(h); | 253 closed.add(h); |
| 265 } | 254 } |
| 266 _tempHandle.h = RawMojoHandle.INVALID; | 255 _tempHandle.h = RawMojoHandle.INVALID; |
| 267 } | 256 } |
| 268 for (var h in closed) { | 257 for (var h in closed) { |
| 269 _close(h, pruning: true); | 258 _close(h, pruning: true); |
| 270 } | 259 } |
| 271 } | 260 } |
| 272 | 261 |
| 273 void _shutdownHandleWatcher() { | 262 void _shutdownHandleWatcher(SendPort shutdownSendPort) { |
| 274 _shutdown = true; | 263 _shutdown = true; |
| 275 _tempHandle.h = _controlHandle; | 264 _tempHandle.h = _controlHandle; |
| 276 _tempHandle.close(); | 265 _tempHandle.close(); |
| 277 _tempHandle.h = RawMojoHandle.INVALID; | 266 _tempHandle.h = RawMojoHandle.INVALID; |
| 267 shutdownSendPort.send(null); |
| 278 } | 268 } |
| 279 | 269 |
| 280 static MojoResult _sendControlData(RawMojoHandle mojoHandle, | 270 static MojoResult _sendControlData(RawMojoHandle mojoHandle, |
| 281 SendPort port, | 271 SendPort port, |
| 282 int data) { | 272 int data) { |
| 283 int controlHandle = _MojoHandleWatcherNatives.getControlHandle(); | 273 int controlHandle = _MojoHandleWatcherNatives.getControlHandle(); |
| 284 if (controlHandle == RawMojoHandle.INVALID) { | 274 if (controlHandle == RawMojoHandle.INVALID) { |
| 285 throw new Exception("Found invalid control handle"); | 275 return MojoResult.FAILED_PRECONDITION; |
| 286 } | 276 } |
| 287 | 277 |
| 288 int rawHandle = RawMojoHandle.INVALID; | 278 int rawHandle = RawMojoHandle.INVALID; |
| 289 if (mojoHandle != null) { | 279 if (mojoHandle != null) { |
| 290 rawHandle = mojoHandle.h; | 280 rawHandle = mojoHandle.h; |
| 291 } | 281 } |
| 292 var result = _MojoHandleWatcherNatives.sendControlData( | 282 var result = _MojoHandleWatcherNatives.sendControlData( |
| 293 controlHandle, rawHandle, port, data); | 283 controlHandle, rawHandle, port, data); |
| 294 return new MojoResult(result); | 284 return new MojoResult(result); |
| 295 } | 285 } |
| 296 | 286 |
| 297 static Future<Isolate> Start() { | 287 static Future<Isolate> Start() { |
| 298 // Make a control message pipe, | 288 // Make a control message pipe, |
| 299 MojoMessagePipe pipe = new MojoMessagePipe(); | 289 MojoMessagePipe pipe = new MojoMessagePipe(); |
| 300 int consumerHandle = pipe.endpoints[0].handle.h; | 290 int consumerHandle = pipe.endpoints[0].handle.h; |
| 301 int producerHandle = pipe.endpoints[1].handle.h; | 291 int producerHandle = pipe.endpoints[1].handle.h; |
| 302 | 292 |
| 303 // Call setControlHandle with the other end. | 293 // Call setControlHandle with the other end. |
| 294 assert(producerHandle != RawMojoHandle.INVALID); |
| 304 _MojoHandleWatcherNatives.setControlHandle(producerHandle); | 295 _MojoHandleWatcherNatives.setControlHandle(producerHandle); |
| 305 | 296 |
| 306 // Spawn the handle watcher isolate with the MojoHandleWatcher, | 297 // Spawn the handle watcher isolate with the MojoHandleWatcher, |
| 307 return Isolate.spawn(_handleWatcherIsolate, consumerHandle); | 298 return Isolate.spawn(_handleWatcherIsolate, consumerHandle); |
| 308 } | 299 } |
| 309 | 300 |
| 310 static void Stop() { | 301 static void Stop() { |
| 302 // Create a port for notification that the handle watcher has shutdown. |
| 303 var shutdownReceivePort = new ReceivePort(); |
| 304 var shutdownSendPort = shutdownReceivePort.sendPort; |
| 305 |
| 311 // Send the shutdown command. | 306 // Send the shutdown command. |
| 312 _sendControlData(null, null, _encodeCommand(SHUTDOWN)); | 307 _sendControlData(null, shutdownSendPort, _encodeCommand(SHUTDOWN)); |
| 313 | 308 |
| 314 // Close the control handle. | 309 // Close the control handle. |
| 315 int controlHandle = _MojoHandleWatcherNatives.getControlHandle(); | 310 int controlHandle = _MojoHandleWatcherNatives.getControlHandle(); |
| 316 var handle = new RawMojoHandle(controlHandle); | 311 var handle = new RawMojoHandle(controlHandle); |
| 317 handle.close(); | 312 handle.close(); |
| 318 | 313 |
| 319 // Invalidate the control handle. | 314 // Invalidate the control handle. |
| 320 _MojoHandleWatcherNatives.setControlHandle(RawMojoHandle.INVALID); | 315 _MojoHandleWatcherNatives.setControlHandle(RawMojoHandle.INVALID); |
| 316 |
| 317 // Wait for the handle watcher isolate to exit. |
| 318 shutdownReceivePort.first.then((_) { |
| 319 shutdownReceivePort.close(); |
| 320 }); |
| 321 } | 321 } |
| 322 | 322 |
| 323 static MojoResult close(RawMojoHandle mojoHandle) { | 323 static MojoResult close(RawMojoHandle mojoHandle) { |
| 324 return _sendControlData(mojoHandle, null, _encodeCommand(CLOSE)); | 324 return _sendControlData(mojoHandle, null, _encodeCommand(CLOSE)); |
| 325 } | 325 } |
| 326 | 326 |
| 327 static MojoResult toggleWrite(RawMojoHandle mojoHandle) { | |
| 328 return _sendControlData(mojoHandle, null, _encodeCommand(TOGGLE_WRITE)); | |
| 329 } | |
| 330 | |
| 331 static MojoResult add(RawMojoHandle mojoHandle, SendPort port, int signals) { | 327 static MojoResult add(RawMojoHandle mojoHandle, SendPort port, int signals) { |
| 332 return _sendControlData(mojoHandle, port, _encodeCommand(ADD, signals)); | 328 return _sendControlData(mojoHandle, port, _encodeCommand(ADD, signals)); |
| 333 } | 329 } |
| 334 | 330 |
| 335 static MojoResult remove(RawMojoHandle mojoHandle) { | 331 static MojoResult remove(RawMojoHandle mojoHandle) { |
| 336 return _sendControlData(mojoHandle, null, _encodeCommand(REMOVE)); | 332 return _sendControlData(mojoHandle, null, _encodeCommand(REMOVE)); |
| 337 } | 333 } |
| 338 | 334 |
| 339 static MojoResult timer(SendPort port, int deadline) { | 335 static MojoResult timer(SendPort port, int deadline) { |
| 340 // The deadline will be unwrapped before sending to the handle watcher. | 336 // The deadline will be unwrapped before sending to the handle watcher. |
| 341 return _sendControlData( | 337 return _sendControlData( |
| 342 new RawMojoHandle(deadline), port, _encodeCommand(TIMER)); | 338 new RawMojoHandle(deadline), port, _encodeCommand(TIMER)); |
| 343 } | 339 } |
| 344 } | 340 } |
| OLD | NEW |