| Index: third_party/mojo/src/mojo/public/dart/src/handle_watcher.dart
|
| diff --git a/third_party/mojo/src/mojo/public/dart/src/handle_watcher.dart b/third_party/mojo/src/mojo/public/dart/src/handle_watcher.dart
|
| index 198a9f66fc3c80025856674d4ac0304994e33847..70cc2978dc54cee2ba01ec940ab69206ecdb7fc9 100644
|
| --- a/third_party/mojo/src/mojo/public/dart/src/handle_watcher.dart
|
| +++ b/third_party/mojo/src/mojo/public/dart/src/handle_watcher.dart
|
| @@ -2,17 +2,7 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -part of core;
|
| -
|
| -class _MojoHandleWatcherNatives {
|
| - static int sendControlData(int controlHandle, int mojoHandle, SendPort port,
|
| - int data) native "MojoHandleWatcher_SendControlData";
|
| - static List recvControlData(
|
| - int controlHandle) native "MojoHandleWatcher_RecvControlData";
|
| - static int setControlHandle(
|
| - int controlHandle) native "MojoHandleWatcher_SetControlHandle";
|
| - static int getControlHandle() native "MojoHandleWatcher_GetControlHandle";
|
| -}
|
| +part of internal;
|
|
|
| // The MojoHandleWatcher sends a stream of events to application isolates that
|
| // register Mojo handles with it. Application isolates make the following calls:
|
| @@ -36,14 +26,27 @@ class MojoHandleWatcher {
|
| static const int TIMER = 3;
|
| static const int SHUTDOWN = 4;
|
|
|
| + static const int kMojoHandleInvalid = 0;
|
| + static const int kDeadlineIndefinite = -1;
|
| +
|
| + static const int kMojoResultOk = 0;
|
| + static const int kMojoResultDeadlineExceeded = -4;
|
| + static const int kMojoResultFailedPrecondition = -9;
|
| +
|
| + static const int kMojoSignalsReadable = (1 << 0);
|
| + static const int kMojoSignalsWritable = (1 << 1);
|
| + static const int kMojoSignalsPeerClosed = (1 << 2);
|
| + static const int kMojoSignalsAll =
|
| + kMojoSignalsReadable | kMojoSignalsWritable | kMojoSignalsPeerClosed;
|
| +
|
| static int _encodeCommand(int cmd, [int signals = 0]) =>
|
| - (cmd << 3) | (signals & MojoHandleSignals.kAll);
|
| + (cmd << 3) | (signals & kMojoSignalsAll);
|
| static int _decodeCommand(int cmd) {
|
| - assert(MojoHandleSignals.kAll < 1 << 3);
|
| + assert(kMojoSignalsAll < 1 << 3);
|
| return cmd >> 3;
|
| }
|
| - static MojoHandleSignals _decodeSignals(int cmd) {
|
| - return new MojoHandleSignals(cmd & MojoHandleSignals.kAll);
|
| + static int _decodeSignals(int cmd) {
|
| + return cmd & kMojoSignalsAll;
|
| }
|
|
|
| // The Mojo handle over which control messages are sent.
|
| @@ -66,10 +69,6 @@ class MojoHandleWatcher {
|
| // A mapping from Mojo handles to their indices in _handles.
|
| Map<int, int> _handleIndices;
|
|
|
| - // Since we are not storing wrapped handles, a dummy handle for when we need
|
| - // a MojoHandle.
|
| - MojoHandle _tempHandle;
|
| -
|
| // Priority queue of timers registered with the watcher.
|
| TimerQueue _timerQueue;
|
|
|
| @@ -80,12 +79,11 @@ class MojoHandleWatcher {
|
| _signals = new List<int>(),
|
| _handleIndices = new Map<int, int>(),
|
| _handleCount = 1,
|
| - _tempHandle = new MojoHandle(MojoHandle.INVALID),
|
| _timerQueue = new TimerQueue() {
|
| // Setup control handle.
|
| _handles.add(_controlHandle);
|
| _ports.add(null); // There is no port for the control handle.
|
| - _signals.add(MojoHandleSignals.kReadable);
|
| + _signals.add(kMojoSignalsReadable);
|
| _handleIndices[_controlHandle] = 0;
|
| }
|
|
|
| @@ -93,22 +91,22 @@ class MojoHandleWatcher {
|
| MojoHandleWatcher watcher = new MojoHandleWatcher(consumerHandle);
|
| while (!watcher._shutdown) {
|
| int deadline = watcher._processTimerDeadlines();
|
| - MojoWaitManyResult mwmr =
|
| - MojoHandle.waitMany(watcher._handles, watcher._signals, deadline);
|
| - if (mwmr.result.isOk && mwmr.index == 0) {
|
| + // mwmr[0]: result, mwmr[1]: index, mwmr[2]: list of signal states.
|
| + List mwmr = MojoHandleNatives.waitMany(
|
| + watcher._handles, watcher._signals, deadline);
|
| + if ((mwmr[0] == kMojoResultOk) && (mwmr[1] == 0)) {
|
| watcher._handleControlMessage();
|
| - } else if (mwmr.result.isOk && (mwmr.index > 0)) {
|
| - int handle = watcher._handles[mwmr.index];
|
| + } else if ((mwmr[0] == kMojoResultOk) && (mwmr[1] > 0)) {
|
| + int handle = watcher._handles[mwmr[1]];
|
|
|
| // Route event.
|
| - watcher._routeEvent(
|
| - mwmr.states[mwmr.index].satisfied_signals, mwmr.index);
|
| + watcher._routeEvent(mwmr[2][mwmr[1]][0], mwmr[1]);
|
| // Remove the handle from the list.
|
| watcher._removeHandle(handle);
|
| - } else if (!mwmr.result.isDeadlineExceeded) {
|
| + } else if (mwmr[0] != kMojoResultDeadlineExceeded) {
|
| // Some handle was closed, but not by us.
|
| // Find it and close it on our side.
|
| - watcher._pruneClosedHandles(mwmr.states);
|
| + watcher._pruneClosedHandles(mwmr[2]);
|
| }
|
| }
|
| }
|
| @@ -118,7 +116,7 @@ class MojoHandleWatcher {
|
| }
|
|
|
| void _handleControlMessage() {
|
| - List result = _MojoHandleWatcherNatives.recvControlData(_controlHandle);
|
| + List result = MojoHandleWatcherNatives.recvControlData(_controlHandle);
|
| // result[0] = mojo handle if any, or a timer deadline in milliseconds.
|
| // result[1] = SendPort if any.
|
| // result[2] = command << 2 | WRITABLE | READABLE
|
| @@ -147,18 +145,18 @@ class MojoHandleWatcher {
|
| }
|
| }
|
|
|
| - void _addHandle(int mojoHandle, SendPort port, MojoHandleSignals signals) {
|
| + void _addHandle(int mojoHandle, SendPort port, int signals) {
|
| int idx = _handleIndices[mojoHandle];
|
| if (idx == null) {
|
| _handles.add(mojoHandle);
|
| _ports.add(port);
|
| - _signals.add(signals.value);
|
| + _signals.add(signals);
|
| _handleIndices[mojoHandle] = _handleCount;
|
| _handleCount++;
|
| } else {
|
| assert(_ports[idx] == port);
|
| assert(_handles[idx] == mojoHandle);
|
| - _signals[idx] |= signals.value;
|
| + _signals[idx] |= signals;
|
| }
|
| }
|
|
|
| @@ -200,21 +198,19 @@ class MojoHandleWatcher {
|
| // has already been pruned. This happens when the app isolate has not yet
|
| // received the PEER_CLOSED event. The app isolate will not close the
|
| // handle, so we must do so here.
|
| - _tempHandle._set(mojoHandle);
|
| - _tempHandle.close();
|
| + MojoHandleNatives.close(mojoHandle);
|
| if (port != null) port.send(null); // Notify that close is done.
|
| return;
|
| }
|
| if (idx == 0) {
|
| throw "The control handle (idx = 0) cannot be closed.";
|
| }
|
| - _tempHandle._set(_handles[idx]);
|
| - _tempHandle.close();
|
| + MojoHandleNatives.close(_handles[idx]);
|
| if (port != null) port.send(null); // Notify that close is done.
|
| if (pruning) {
|
| // If this handle is being pruned, notify the application isolate
|
| // by sending MojoHandleSignals.PEER_CLOSED.
|
| - _ports[idx].send([_signals[idx], MojoHandleSignals.kPeerClosed]);
|
| + _ports[idx].send([_signals[idx], kMojoSignalsPeerClosed]);
|
| }
|
| _removeHandle(mojoHandle);
|
| }
|
| @@ -229,28 +225,27 @@ class MojoHandleWatcher {
|
| }
|
| return _timerQueue.hasTimer
|
| ? (_timerQueue.currentTimeout - now) * 1000
|
| - : MojoHandle.DEADLINE_INDEFINITE;
|
| + : kDeadlineIndefinite;
|
| }
|
|
|
| void _timer(SendPort port, int deadline) {
|
| _timerQueue.updateTimer(port, deadline);
|
| }
|
|
|
| - void _pruneClosedHandles(List<MojoHandleSignalsState> states) {
|
| + void _pruneClosedHandles(List<List<int>> states) {
|
| List<int> closed = new List();
|
| for (var i = 0; i < _handles.length; i++) {
|
| if (states != null) {
|
| - var signals = new MojoHandleSignals(states[i].satisfied_signals);
|
| - if (signals.isPeerClosed) {
|
| + int signals = states[i][0];
|
| + if ((signals & kMojoSignalsPeerClosed) != 0) {
|
| closed.add(_handles[i]);
|
| }
|
| } else {
|
| - _tempHandle._set(_handles[i]);
|
| - MojoWaitResult mwr = _tempHandle.wait(MojoHandleSignals.kAll, 0);
|
| - if ((!mwr.result.isOk) && (!mwr.result.isDeadlineExceeded)) {
|
| + List mwr = MojoHandleNatives.wait(_handles[i], kMojoSignalsAll, 0);
|
| + if ((mwr[0] != kMojoResultOk) &&
|
| + (mwr[0] != kMojoResultDeadlineExceeded)) {
|
| closed.add(_handles[i]);
|
| }
|
| - _tempHandle._set(MojoHandle.INVALID);
|
| }
|
| }
|
| for (var h in closed) {
|
| @@ -262,38 +257,36 @@ class MojoHandleWatcher {
|
|
|
| void _shutdownHandleWatcher(SendPort shutdownSendPort) {
|
| _shutdown = true;
|
| - _tempHandle._set(_controlHandle);
|
| - _tempHandle.close();
|
| + MojoHandleNatives.close(_controlHandle);
|
| shutdownSendPort.send(null);
|
| }
|
|
|
| - static MojoResult _sendControlData(
|
| - MojoHandle mojoHandle, SendPort port, int data) {
|
| - int controlHandle = _MojoHandleWatcherNatives.getControlHandle();
|
| - if (controlHandle == MojoHandle.INVALID) {
|
| - return MojoResult.FAILED_PRECONDITION;
|
| + static int _sendControlData(int rawHandle, SendPort port, int data) {
|
| + int controlHandle = MojoHandleWatcherNatives.getControlHandle();
|
| + if (controlHandle == kMojoHandleInvalid) {
|
| + return kMojoResultFailedPrecondition;
|
| }
|
|
|
| - int rawHandle = MojoHandle.INVALID;
|
| - if (mojoHandle != null) {
|
| - rawHandle = mojoHandle.h;
|
| - }
|
| - var result = _MojoHandleWatcherNatives.sendControlData(
|
| + var result = MojoHandleWatcherNatives.sendControlData(
|
| controlHandle, rawHandle, port, data);
|
| - return new MojoResult(result);
|
| + return result;
|
| }
|
|
|
| // Starts up the MojoHandleWatcher isolate. Should be called only once
|
| // per VM process.
|
| static Future<Isolate> _start() {
|
| // Make a control message pipe,
|
| - MojoMessagePipe pipe = new MojoMessagePipe();
|
| - int consumerHandle = pipe.endpoints[0].handle.h;
|
| - int producerHandle = pipe.endpoints[1].handle.h;
|
| + List pipeEndpoints = MojoMessagePipeNatives.MojoCreateMessagePipe(0);
|
| + assert(pipeEndpoints != null);
|
| + assert((pipeEndpoints is List) && (pipeEndpoints.length == 3));
|
| + assert(pipeEndpoints[0] == kMojoResultOk);
|
| +
|
| + int consumerHandle = pipeEndpoints[1];
|
| + int producerHandle = pipeEndpoints[2];
|
|
|
| // Call setControlHandle with the other end.
|
| - assert(producerHandle != MojoHandle.INVALID);
|
| - _MojoHandleWatcherNatives.setControlHandle(producerHandle);
|
| + assert(producerHandle != kMojoHandleInvalid);
|
| + MojoHandleWatcherNatives.setControlHandle(producerHandle);
|
|
|
| // Spawn the handle watcher isolate with the MojoHandleWatcher,
|
| return Isolate.spawn(_handleWatcherIsolate, consumerHandle);
|
| @@ -307,15 +300,15 @@ class MojoHandleWatcher {
|
| var shutdownSendPort = shutdownReceivePort.sendPort;
|
|
|
| // Send the shutdown command.
|
| - _sendControlData(null, shutdownSendPort, _encodeCommand(SHUTDOWN));
|
| + _sendControlData(
|
| + kMojoHandleInvalid, shutdownSendPort, _encodeCommand(SHUTDOWN));
|
|
|
| // Close the control handle.
|
| - int controlHandle = _MojoHandleWatcherNatives.getControlHandle();
|
| - var handle = new MojoHandle(controlHandle);
|
| - handle.close();
|
| + int controlHandle = MojoHandleWatcherNatives.getControlHandle();
|
| + MojoHandleNatives.close(controlHandle);
|
|
|
| // Invalidate the control handle.
|
| - _MojoHandleWatcherNatives.setControlHandle(MojoHandle.INVALID);
|
| + MojoHandleWatcherNatives.setControlHandle(kMojoHandleInvalid);
|
|
|
| // Wait for the handle watcher isolate to exit.
|
| shutdownReceivePort.first.then((_) {
|
| @@ -326,13 +319,13 @@ class MojoHandleWatcher {
|
| // If wait is true, returns a future that resolves only after the handle
|
| // has actually been closed by the handle watcher. Otherwise, returns a
|
| // future that resolves immediately.
|
| - static Future<MojoResult> close(MojoHandle mojoHandle, {bool wait: false}) {
|
| - assert(MojoHandle._removeUnclosedHandle(mojoHandle));
|
| + static Future<int> close(int mojoHandle, {bool wait: false}) {
|
| + //assert(MojoHandle._removeUnclosedHandle(mojoHandle));
|
| if (!wait) {
|
| return new Future.value(
|
| _sendControlData(mojoHandle, null, _encodeCommand(CLOSE)));
|
| }
|
| - MojoResult result;
|
| + int result;
|
| var completer = new Completer();
|
| var rawPort = new RawReceivePort((_) {
|
| completer.complete(result);
|
| @@ -345,17 +338,16 @@ class MojoHandleWatcher {
|
| });
|
| }
|
|
|
| - static MojoResult add(MojoHandle mojoHandle, SendPort port, int signals) {
|
| + static int add(int mojoHandle, SendPort port, int signals) {
|
| return _sendControlData(mojoHandle, port, _encodeCommand(ADD, signals));
|
| }
|
|
|
| - static MojoResult remove(MojoHandle mojoHandle) {
|
| + static int remove(int mojoHandle) {
|
| return _sendControlData(mojoHandle, null, _encodeCommand(REMOVE));
|
| }
|
|
|
| - static MojoResult timer(Object ignored, SendPort port, int deadline) {
|
| + static int timer(Object ignored, SendPort port, int deadline) {
|
| // The deadline will be unwrapped before sending to the handle watcher.
|
| - return _sendControlData(
|
| - new MojoHandle._internal(deadline), port, _encodeCommand(TIMER));
|
| + return _sendControlData(deadline, port, _encodeCommand(TIMER));
|
| }
|
| }
|
|
|