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

Unified Diff: mojo/public/dart/system/lib/src/handle_watcher.dart

Issue 674383002: Initial work on Dart bindings for Mojo. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Merge. Work on templates. Created 6 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojo/public/dart/system/lib/src/handle.dart ('k') | mojo/public/dart/system/lib/src/message_pipe.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/public/dart/system/lib/src/handle_watcher.dart
diff --git a/mojo/public/dart/system/lib/src/handle_watcher.dart b/mojo/public/dart/system/lib/src/handle_watcher.dart
new file mode 100644
index 0000000000000000000000000000000000000000..4cc3dc8f12b047fa5df0a77c9556508cca01e80b
--- /dev/null
+++ b/mojo/public/dart/system/lib/src/handle_watcher.dart
@@ -0,0 +1,248 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// 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 control_handle, int mojo_handle, SendPort port, int data)
+ native "MojoHandleWatcher_SendControlData";
+ static List recvControlData(int control_handle)
+ native "MojoHandleWatcher_RecvControlData";
+ static int setControlHandle(int control_handle)
+ native "MojoHandleWatcher_SetControlHandle";
+ static int getControlHandle()
+ native "MojoHandleWatcher_GetControlHandle";
+}
+
+
+class MojoHandleWatcher {
+ static const int ADD = 0;
+ static const int REMOVE = 1;
+ static const int TOGGLE_WRITE = 2;
+ static const int CLOSE = 3;
+ static const int SHUTDOWN = 4;
+
+ RawMojoHandle _dummy_handle;
+ int _control_handle;
+ bool _shutdown;
+ List<int> _handles;
+ List<SendPort> _ports;
+ List<int> _signals;
+ int _handle_count;
+ Map<int, int> _handle_indices;
+
+ MojoHandleWatcher(this._control_handle) :
+ _shutdown = false,
+ _ports = [null],
+ _signals = [MojoHandleSignals.READABLE],
+ _handle_count = 1 {
+ _handles = [_control_handle];
+ _handle_indices = new Map();
+ _handle_indices[_control_handle] = 0;
+ _dummy_handle = new RawMojoHandle(RawMojoHandle.INVALID);
+ }
+
+ static void _handleWatcherIsolate(MojoHandleWatcher eh) {
+ while (!eh._shutdown) {
+ int res = RawMojoHandle.waitMany(eh._handles,
+ eh._signals,
+ RawMojoHandle.DEADLINE_INDEFINITE);
+ if (res == 0) {
+ eh._handleControlMessage();
+ } else if (res > 0) {
+ int handle = eh._handles[res];
+ // Route event.
+ eh._routeEvent(res);
+ // Remove the handle from the list.
+ eh._removeHandle(handle);
+ } else if (res == MojoResult.FAILED_PRECONDITION) {
+ // None of the handles can ever be satisfied, including the control
+ // handle. This probably means we are going down. Clean up and
+ // shutdown.
+ eh._pruneClosedHandles();
+ eh._shutdown = true;
+ } else {
+ // Some handle is closed. We have to go through the list and find it.
+ eh._pruneClosedHandles();
+ }
+ }
+ }
+
+ void _routeEvent(int idx) {
+ int client_handle = _handles[idx];
+ int signals = _signals[idx];
+ SendPort port = _ports[idx];
+
+ _dummy_handle.h = client_handle;
+ bool readyWrite =
+ MojoHandleSignals.isWritable(signals) && _dummy_handle.readyWrite();
+ bool readyRead =
+ MojoHandleSignals.isReadable(signals) && _dummy_handle.readyRead();
+ if (readyRead && readyWrite) {
+ //print("routing READWRITE for handle $client_handle");
+ port.send(MojoHandleSignals.READWRITE);
+ } else if (readyWrite) {
+ //print("routing WRITABLE for handle $client_handle");
+ port.send(MojoHandleSignals.WRITABLE);
+ } else if (readyRead) {
+ //print("routing READABLE for handle $client_handle");
+ port.send(MojoHandleSignals.READABLE);
+ }
+ _dummy_handle.h = RawMojoHandle.INVALID;
+ }
+
+ void _handleControlMessage() {
+ List result = _MojoHandleWatcherNatives.recvControlData(_control_handle);
+ // result[0] = mojo handle if any
+ // result[1] = SendPort if any
+ // result[2] = command << 2 | WRITABLE | READABLE
+
+ int signals = result[2] & MojoHandleSignals.READWRITE;
+ switch (result[2] >> 2) {
+ case ADD:
+ _addHandle(result[0], result[1], signals);
+ break;
+ case REMOVE:
+ _removeHandle(result[0]);
+ break;
+ case TOGGLE_WRITE:
+ _toggleWrite(result[0]);
+ break;
+ case CLOSE:
+ _close(result[0]);
+ break;
+ case SHUTDOWN:
+ _shutdown = true;
+ break;
+ default:
+ break;
+ }
+ }
+
+ void _addHandle(int mojo_handle, SendPort port, int signals) {
+ _handles.add(mojo_handle);
+ _ports.add(port);
+ _signals.add(signals & MojoHandleSignals.READWRITE);
+ _handle_indices[mojo_handle] = _handle_count;
+ _handle_count++;
+ }
+
+ void _removeHandle(int mojo_handle) {
+ int idx = _handle_indices[mojo_handle];
+ if (idx == null) {
+ return;
+ }
+ if (idx == 0) {
+ // Cannot remove control handle.
+ return;
+ }
+ if (idx == _handle_count - 1) {
+ int handle = _handles[idx];
+ _handle_indices[handle] = null;
+ _handles.removeLast();
+ _signals.removeLast();
+ _ports.removeLast();
+ _handle_count--;
+ } else {
+ int last = _handle_count - 1;
+ _handles[idx] = _handles[last];
+ _signals[idx] = _signals[last];
+ _ports[idx] = _ports[last];
+ _handles.removeLast();
+ _signals.removeLast();
+ _ports.removeLast();
+ _handle_indices[_handles[idx]] = idx;
+ _handle_count--;
+ }
+ }
+
+ void _close(int mojo_handle) {
+ int idx = _handle_indices[mojo_handle];
+ if (idx == null) {
+ return;
+ }
+ if (idx == 0) {
+ // Cannot remove control handle.
+ return;
+ }
+ _dummy_handle.h = _handles[idx];
+ _dummy_handle.close();
+ _dummy_handle.h = RawMojoHandle.INVALID;
+ _removeHandle(mojo_handle);
+ }
+
+ void _toggleWrite(int mojo_handle) {
+ int idx = _handle_indices[mojo_handle];
+ if (idx == null) {
+ return;
+ }
+ if (idx == 0) {
+ // Cannot toggle the control handle.
+ return;
+ }
+ _signals[idx] = MojoHandleSignals.toggleWrite(_signals[idx]);
+ }
+
+ void _pruneClosedHandles() {
+ List<int> closed = new List();
+ for (var h in _handles) {
+ int res = 0;
+ _dummy_handle.h = h;
+ res = _dummy_handle.wait(MojoHandleSignals.READWRITE, 0);
+ if ((res != MojoResult.OK) && (res != MojoResult.DEADLINE_EXCEEDED)) {
+ closed.add(h);
+ }
+ _dummy_handle.h = RawMojoHandle.INVALID;
+ }
+
+ for (var h in closed) {
+ _close(h);
+ }
+ }
+
+ static Future<bool> Start() {
+ // 1. make control message pipe,
+ // 2. make MojoHandleWatcher with one end,
+ // 3. setControlHandle with the other end.
+ // 4. spawn isolate with MojoHandleWatcher,
+ // 5. return Future<bool> giving true on success.
+ MojoMessagePipe pipe = new MojoMessagePipe();
+ int consumer_handle = pipe.endpoints[0].handle.h;
+ int producer_handle = pipe.endpoints[1].handle.h;
+ MojoHandleWatcher eh = new MojoHandleWatcher(consumer_handle);
+ _MojoHandleWatcherNatives.setControlHandle(producer_handle);
+ return Isolate.spawn(_handleWatcherIsolate, eh).then((isolate) {
+ return true;
+ });
+ }
+
+ static void Stop() {
+ sendControlData(RawMojoHandle.INVALID, null, SHUTDOWN << 2);
+ }
+
+ static int sendControlData(int mojo_handle, SendPort port, int data) {
+ int control_handle = _MojoHandleWatcherNatives.getControlHandle();
+ if (control_handle == RawMojoHandle.INVALID) {
+ throw new Exception("Found invalid control handle");
+ }
+ return _MojoHandleWatcherNatives.sendControlData(
+ control_handle, mojo_handle, port, data);
+ }
+
+ static int close(int mojo_handle) {
+ return sendControlData(mojo_handle, null, CLOSE << 2);
+ }
+
+ static int toggleWrite(int mojo_handle) {
+ return sendControlData(mojo_handle, null, TOGGLE_WRITE << 2);
+ }
+
+ static int add(int mojo_handle, SendPort port, int signals) {
+ return sendControlData(
+ mojo_handle,
+ port,
+ (ADD << 2) | (signals & MojoHandleSignals.READWRITE));
+ }
+}
« no previous file with comments | « mojo/public/dart/system/lib/src/handle.dart ('k') | mojo/public/dart/system/lib/src/message_pipe.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698