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)); |
} |
} |