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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 part of core;
6
7 class _MojoHandleWatcherNatives {
8 static int sendControlData(
9 int control_handle, int mojo_handle, SendPort port, int data)
10 native "MojoHandleWatcher_SendControlData";
11 static List recvControlData(int control_handle)
12 native "MojoHandleWatcher_RecvControlData";
13 static int setControlHandle(int control_handle)
14 native "MojoHandleWatcher_SetControlHandle";
15 static int getControlHandle()
16 native "MojoHandleWatcher_GetControlHandle";
17 }
18
19
20 class MojoHandleWatcher {
21 static const int ADD = 0;
22 static const int REMOVE = 1;
23 static const int TOGGLE_WRITE = 2;
24 static const int CLOSE = 3;
25 static const int SHUTDOWN = 4;
26
27 RawMojoHandle _dummy_handle;
28 int _control_handle;
29 bool _shutdown;
30 List<int> _handles;
31 List<SendPort> _ports;
32 List<int> _signals;
33 int _handle_count;
34 Map<int, int> _handle_indices;
35
36 MojoHandleWatcher(this._control_handle) :
37 _shutdown = false,
38 _ports = [null],
39 _signals = [MojoHandleSignals.READABLE],
40 _handle_count = 1 {
41 _handles = [_control_handle];
42 _handle_indices = new Map();
43 _handle_indices[_control_handle] = 0;
44 _dummy_handle = new RawMojoHandle(RawMojoHandle.INVALID);
45 }
46
47 static void _handleWatcherIsolate(MojoHandleWatcher eh) {
48 while (!eh._shutdown) {
49 int res = RawMojoHandle.waitMany(eh._handles,
50 eh._signals,
51 RawMojoHandle.DEADLINE_INDEFINITE);
52 if (res == 0) {
53 eh._handleControlMessage();
54 } else if (res > 0) {
55 int handle = eh._handles[res];
56 // Route event.
57 eh._routeEvent(res);
58 // Remove the handle from the list.
59 eh._removeHandle(handle);
60 } else if (res == MojoResult.FAILED_PRECONDITION) {
61 // None of the handles can ever be satisfied, including the control
62 // handle. This probably means we are going down. Clean up and
63 // shutdown.
64 eh._pruneClosedHandles();
65 eh._shutdown = true;
66 } else {
67 // Some handle is closed. We have to go through the list and find it.
68 eh._pruneClosedHandles();
69 }
70 }
71 }
72
73 void _routeEvent(int idx) {
74 int client_handle = _handles[idx];
75 int signals = _signals[idx];
76 SendPort port = _ports[idx];
77
78 _dummy_handle.h = client_handle;
79 bool readyWrite =
80 MojoHandleSignals.isWritable(signals) && _dummy_handle.readyWrite();
81 bool readyRead =
82 MojoHandleSignals.isReadable(signals) && _dummy_handle.readyRead();
83 if (readyRead && readyWrite) {
84 //print("routing READWRITE for handle $client_handle");
85 port.send(MojoHandleSignals.READWRITE);
86 } else if (readyWrite) {
87 //print("routing WRITABLE for handle $client_handle");
88 port.send(MojoHandleSignals.WRITABLE);
89 } else if (readyRead) {
90 //print("routing READABLE for handle $client_handle");
91 port.send(MojoHandleSignals.READABLE);
92 }
93 _dummy_handle.h = RawMojoHandle.INVALID;
94 }
95
96 void _handleControlMessage() {
97 List result = _MojoHandleWatcherNatives.recvControlData(_control_handle);
98 // result[0] = mojo handle if any
99 // result[1] = SendPort if any
100 // result[2] = command << 2 | WRITABLE | READABLE
101
102 int signals = result[2] & MojoHandleSignals.READWRITE;
103 switch (result[2] >> 2) {
104 case ADD:
105 _addHandle(result[0], result[1], signals);
106 break;
107 case REMOVE:
108 _removeHandle(result[0]);
109 break;
110 case TOGGLE_WRITE:
111 _toggleWrite(result[0]);
112 break;
113 case CLOSE:
114 _close(result[0]);
115 break;
116 case SHUTDOWN:
117 _shutdown = true;
118 break;
119 default:
120 break;
121 }
122 }
123
124 void _addHandle(int mojo_handle, SendPort port, int signals) {
125 _handles.add(mojo_handle);
126 _ports.add(port);
127 _signals.add(signals & MojoHandleSignals.READWRITE);
128 _handle_indices[mojo_handle] = _handle_count;
129 _handle_count++;
130 }
131
132 void _removeHandle(int mojo_handle) {
133 int idx = _handle_indices[mojo_handle];
134 if (idx == null) {
135 return;
136 }
137 if (idx == 0) {
138 // Cannot remove control handle.
139 return;
140 }
141 if (idx == _handle_count - 1) {
142 int handle = _handles[idx];
143 _handle_indices[handle] = null;
144 _handles.removeLast();
145 _signals.removeLast();
146 _ports.removeLast();
147 _handle_count--;
148 } else {
149 int last = _handle_count - 1;
150 _handles[idx] = _handles[last];
151 _signals[idx] = _signals[last];
152 _ports[idx] = _ports[last];
153 _handles.removeLast();
154 _signals.removeLast();
155 _ports.removeLast();
156 _handle_indices[_handles[idx]] = idx;
157 _handle_count--;
158 }
159 }
160
161 void _close(int mojo_handle) {
162 int idx = _handle_indices[mojo_handle];
163 if (idx == null) {
164 return;
165 }
166 if (idx == 0) {
167 // Cannot remove control handle.
168 return;
169 }
170 _dummy_handle.h = _handles[idx];
171 _dummy_handle.close();
172 _dummy_handle.h = RawMojoHandle.INVALID;
173 _removeHandle(mojo_handle);
174 }
175
176 void _toggleWrite(int mojo_handle) {
177 int idx = _handle_indices[mojo_handle];
178 if (idx == null) {
179 return;
180 }
181 if (idx == 0) {
182 // Cannot toggle the control handle.
183 return;
184 }
185 _signals[idx] = MojoHandleSignals.toggleWrite(_signals[idx]);
186 }
187
188 void _pruneClosedHandles() {
189 List<int> closed = new List();
190 for (var h in _handles) {
191 int res = 0;
192 _dummy_handle.h = h;
193 res = _dummy_handle.wait(MojoHandleSignals.READWRITE, 0);
194 if ((res != MojoResult.OK) && (res != MojoResult.DEADLINE_EXCEEDED)) {
195 closed.add(h);
196 }
197 _dummy_handle.h = RawMojoHandle.INVALID;
198 }
199
200 for (var h in closed) {
201 _close(h);
202 }
203 }
204
205 static Future<bool> Start() {
206 // 1. make control message pipe,
207 // 2. make MojoHandleWatcher with one end,
208 // 3. setControlHandle with the other end.
209 // 4. spawn isolate with MojoHandleWatcher,
210 // 5. return Future<bool> giving true on success.
211 MojoMessagePipe pipe = new MojoMessagePipe();
212 int consumer_handle = pipe.endpoints[0].handle.h;
213 int producer_handle = pipe.endpoints[1].handle.h;
214 MojoHandleWatcher eh = new MojoHandleWatcher(consumer_handle);
215 _MojoHandleWatcherNatives.setControlHandle(producer_handle);
216 return Isolate.spawn(_handleWatcherIsolate, eh).then((isolate) {
217 return true;
218 });
219 }
220
221 static void Stop() {
222 sendControlData(RawMojoHandle.INVALID, null, SHUTDOWN << 2);
223 }
224
225 static int sendControlData(int mojo_handle, SendPort port, int data) {
226 int control_handle = _MojoHandleWatcherNatives.getControlHandle();
227 if (control_handle == RawMojoHandle.INVALID) {
228 throw new Exception("Found invalid control handle");
229 }
230 return _MojoHandleWatcherNatives.sendControlData(
231 control_handle, mojo_handle, port, data);
232 }
233
234 static int close(int mojo_handle) {
235 return sendControlData(mojo_handle, null, CLOSE << 2);
236 }
237
238 static int toggleWrite(int mojo_handle) {
239 return sendControlData(mojo_handle, null, TOGGLE_WRITE << 2);
240 }
241
242 static int add(int mojo_handle, SendPort port, int signals) {
243 return sendControlData(
244 mojo_handle,
245 port,
246 (ADD << 2) | (signals & MojoHandleSignals.READWRITE));
247 }
248 }
OLDNEW
« 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