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

Side by Side Diff: mojo/public/dart/src/handle.dart

Issue 800523004: Dart: Simplifies the handle watcher. Various cleanups and bugfixes. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: cleanup Created 5 years, 11 months 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
« no previous file with comments | « mojo/public/dart/src/data_pipe.dart ('k') | mojo/public/dart/src/handle_watcher.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 _MojoHandleNatives { 7 class _MojoHandleNatives {
8 static int register(MojoHandle handle) native "MojoHandle_Register"; 8 static int register(MojoEventStream eventStream) native "MojoHandle_Register";
9 static int close(int handle) native "MojoHandle_Close"; 9 static int close(int handle) native "MojoHandle_Close";
10 static List wait(int handle, int signals, int deadline) 10 static List wait(int handle, int signals, int deadline)
11 native "MojoHandle_Wait"; 11 native "MojoHandle_Wait";
12 static List waitMany( 12 static List waitMany(
13 List<int> handles, List<int> signals, int deadline) 13 List<int> handles, List<int> signals, int deadline)
14 native "MojoHandle_WaitMany"; 14 native "MojoHandle_WaitMany";
15 } 15 }
16 16
17 17
18 class RawMojoHandle { 18 class MojoHandle {
19 static const int INVALID = 0; 19 static const int INVALID = 0;
20 static const int DEADLINE_INDEFINITE = -1; 20 static const int DEADLINE_INDEFINITE = -1;
21 21
22 int h; 22 int h;
23 23
24 RawMojoHandle(this.h); 24 MojoHandle(this.h);
25 25
26 MojoResult close() { 26 MojoResult close() {
27 int result = _MojoHandleNatives.close(h); 27 int result = _MojoHandleNatives.close(h);
28 h = INVALID; 28 h = INVALID;
29 return new MojoResult(result); 29 return new MojoResult(result);
30 } 30 }
31 31
32 MojoWaitResult wait(int signals, int deadline) { 32 MojoWaitResult wait(int signals, int deadline) {
33 List result = _MojoHandleNatives.wait(h, signals, deadline); 33 List result = _MojoHandleNatives.wait(h, signals, deadline);
34 return new MojoWaitResult(new MojoResult(result[0]), result[1]); 34 return new MojoWaitResult(new MojoResult(result[0]), result[1]);
35 } 35 }
36 36
37 bool _ready(int signal) { 37 bool _ready(MojoHandleSignals signal) {
38 MojoWaitResult res = wait(signal, 0); 38 MojoWaitResult mwr = wait(signal.value, 0);
39 switch (res.result) { 39 switch (mwr.result) {
40 case MojoResult.OK: 40 case MojoResult.OK:
41 return true; 41 return true;
42 case MojoResult.DEADLINE_EXCEEDED: 42 case MojoResult.DEADLINE_EXCEEDED:
43 case MojoResult.CANCELLED: 43 case MojoResult.CANCELLED:
44 case MojoResult.INVALID_ARGUMENT: 44 case MojoResult.INVALID_ARGUMENT:
45 case MojoResult.FAILED_PRECONDITION: 45 case MojoResult.FAILED_PRECONDITION:
46 return false; 46 return false;
47 default: 47 default:
48 // Should be unreachable. 48 // Should be unreachable.
49 throw new Exception("Unreachable"); 49 throw "Unexpected result $res for wait on $h";
50 } 50 }
51 } 51 }
52 52
53 bool readyRead() => _ready(MojoHandleSignals.READABLE); 53 bool get readyRead => _ready(MojoHandleSignals.READABLE);
54 bool readyWrite() => _ready(MojoHandleSignals.WRITABLE); 54 bool get readyWrite => _ready(MojoHandleSignals.WRITABLE);
55 55
56 static MojoWaitManyResult waitMany(List<int> handles, 56 static MojoWaitManyResult waitMany(
57 List<int> signals, 57 List<int> handles, List<int> signals, int deadline) {
58 int deadline) { 58 List result = _MojoHandleNatives.waitMany(handles, signals, deadline);
59 List result = _MojoHandleNatives.waitMany(
60 handles, signals, deadline);
61
62 return new MojoWaitManyResult( 59 return new MojoWaitManyResult(
63 new MojoResult(result[0]), result[1], result[2]); 60 new MojoResult(result[0]), result[1], result[2]);
64 } 61 }
65 62
66 static MojoResult register(MojoHandle handle) { 63 static MojoResult register(MojoEventStream eventStream) {
67 return new MojoResult(_MojoHandleNatives.register(handle)); 64 return new MojoResult(_MojoHandleNatives.register(eventStream));
68 } 65 }
69 66
70 bool get isValid => (h != INVALID); 67 bool get isValid => (h != INVALID);
71 68
72 String toString() => "$h"; 69 String toString() => "$h";
73 70
74 bool operator ==(RawMojoHandle other) { 71 bool operator ==(MojoHandle other) {
75 return h == other.h; 72 return h == other.h;
76 } 73 }
77 } 74 }
78 75
79 76
80 class MojoHandle extends Stream<int> { 77 class MojoEventStream extends Stream<int> {
81 // The underlying Mojo handle. 78 // The underlying Mojo handle.
82 RawMojoHandle _handle; 79 MojoHandle _handle;
83 80
84 // Providing our own stream controller allows us to take custom actions when 81 // Providing our own stream controller allows us to take custom actions when
85 // listeners pause/resume/etc. their StreamSubscription. 82 // listeners pause/resume/etc. their StreamSubscription.
86 StreamController _controller; 83 StreamController _controller;
87 84
88 // The send port that we give to the handle watcher to notify us of handle 85 // The send port that we give to the handle watcher to notify us of handle
89 // events. 86 // events.
90 SendPort _sendPort; 87 SendPort _sendPort;
91 88
92 // The receive port on which we listen and receive events from the handle 89 // The receive port on which we listen and receive events from the handle
93 // watcher. 90 // watcher.
94 ReceivePort _receivePort; 91 ReceivePort _receivePort;
95 92
96 // The signals on this handle that we're interested in. 93 // The signals on this handle that we're interested in.
97 int _signals; 94 MojoHandleSignals _signals;
98 95
99 // Whether the handle has been added to the handle watcher. 96 // Whether listen has been called.
100 bool _eventHandlerAdded; 97 bool _isListening;
101 98
102 MojoHandle(this._handle) : 99 MojoEventStream(MojoHandle handle,
103 _signals = MojoHandleSignals.READABLE, 100 [MojoHandleSignals signals = MojoHandleSignals.READABLE]) :
104 _eventHandlerAdded = false { 101 _handle = handle,
105 MojoResult result = RawMojoHandle.register(this); 102 _signals = signals,
103 _isListening = false {
104 MojoResult result = MojoHandle.register(this);
106 if (!result.isOk) { 105 if (!result.isOk) {
107 throw new Exception("Failed to register the MojoHandle"); 106 throw "Failed to register the MojoHandle: $result.";
108 } 107 }
109 } 108 }
110 109
111 void close() { 110 void close() {
112 if (_eventHandlerAdded) { 111 if (_handle != null) {
113 MojoHandleWatcher.close(_handle); 112 MojoHandleWatcher.close(_handle);
114 _eventHandlerAdded = false; 113 _handle = null;
115 } else {
116 // If we're not in the handle watcher, then close the handle manually.
117 _handle.close();
118 } 114 }
119 if (_receivePort != null) { 115 if (_receivePort != null) {
120 _receivePort.close(); 116 _receivePort.close();
117 _receivePort = null;
121 } 118 }
122 } 119 }
123 120
124 // We wrap the callback provided by clients in listen() with some code to 121 StreamSubscription<List<int>> listen(
125 // handle adding and removing the handle to/from the handle watcher. Because 122 void onData(List event),
126 // the handle watcher removes this handle whenever it receives an event,
127 // we have to re-add it when the callback is finished.
128 Function _onDataClosure(origOnData) {
129 return ((int event) {
130 // The handle watcher removes this handle from its set on an event.
131 _eventHandlerAdded = false;
132 origOnData(event);
133
134 // The callback could have closed the handle. If so, don't add it back to
135 // the MojoHandleWatcher.
136 if (_handle.isValid) {
137 assert(!_eventHandlerAdded);
138 var res = MojoHandleWatcher.add(_handle, _sendPort, _signals);
139 if (!res.isOk) {
140 throw new Exception("Failed to re-add handle: $res");
141 }
142 _eventHandlerAdded = true;
143 }
144 });
145 }
146
147 StreamSubscription<int> listen(
148 void onData(int event),
149 {Function onError, void onDone(), bool cancelOnError}) { 123 {Function onError, void onDone(), bool cancelOnError}) {
124 if (_isListening) {
125 throw "Listen has already been called: $_handle.";
126 }
150 _receivePort = new ReceivePort(); 127 _receivePort = new ReceivePort();
151 _sendPort = _receivePort.sendPort; 128 _sendPort = _receivePort.sendPort;
152 _controller = new StreamController(sync: true, 129 _controller = new StreamController(sync: true,
153 onListen: _onSubscriptionStateChange, 130 onListen: _onSubscriptionStateChange,
154 onCancel: _onSubscriptionStateChange, 131 onCancel: _onSubscriptionStateChange,
155 onPause: _onPauseStateChange, 132 onPause: _onPauseStateChange,
156 onResume: _onPauseStateChange); 133 onResume: _onPauseStateChange);
157 _controller.addStream(_receivePort); 134 _controller.addStream(_receivePort);
158 135
159 assert(!_eventHandlerAdded); 136 if (_signals != MojoHandleSignals.NONE) {
160 var res = MojoHandleWatcher.add(_handle, _sendPort, _signals); 137 var res = MojoHandleWatcher.add(_handle, _sendPort, _signals.value);
161 if (!res.isOk) { 138 if (!res.isOk) {
162 throw new Exception("MojoHandleWatcher add failed: $res"); 139 throw "MojoHandleWatcher add failed: $res";
140 }
163 } 141 }
164 _eventHandlerAdded = true;
165 142
143 _isListening = true;
166 return _controller.stream.listen( 144 return _controller.stream.listen(
167 _onDataClosure(onData), 145 onData,
168 onError: onError, 146 onError: onError,
169 onDone: onDone, 147 onDone: onDone,
170 cancelOnError: cancelOnError); 148 cancelOnError: cancelOnError);
171 } 149 }
172 150
173 bool writeEnabled() => MojoHandleSignals.isWritable(_signals); 151 void enableSignals(MojoHandleSignals signals) {
174 152 _signals = signals;
175 void toggleWriteEvents() { 153 if (_isListening) {
176 _signals = MojoHandleSignals.toggleWrite(_signals); 154 var res = MojoHandleWatcher.add(_handle, _sendPort, signals.value);
177 if (_eventHandlerAdded) {
178 var res = MojoHandleWatcher.toggleWrite(_handle);
179 if (!res.isOk) { 155 if (!res.isOk) {
180 throw new Exception("MojoHandleWatcher failed to toggle write: $res"); 156 throw "MojoHandleWatcher add failed: $res";
181 } 157 }
182 } 158 }
183 } 159 }
184 160
185 void enableWriteEvents() { 161 void enableReadEvents() => enableSignals(MojoHandleSignals.READABLE);
186 assert(!writeEnabled()); 162 void enableWriteEvents() => enableSignals(MojoHandleSignals.WRITABLE);
187 toggleWriteEvents(); 163 void enableAllEvents() => enableSignals(MojoHandleSignals.READWRITE);
188 }
189
190 void disableWriteEvents() {
191 assert(writeEnabled());
192 toggleWriteEvents();
193 }
194 164
195 void _onSubscriptionStateChange() { 165 void _onSubscriptionStateChange() {
196 if (!_controller.hasListener) { 166 if (!_controller.hasListener) {
197 close(); 167 close();
198 } 168 }
199 } 169 }
200 170
201 void _onPauseStateChange() { 171 void _onPauseStateChange() {
202 if (_controller.isPaused) { 172 if (_controller.isPaused) {
203 if (_eventHandlerAdded) { 173 var res = MojoHandleWatcher.remove(_handle);
204 var res = MojoHandleWatcher.remove(_handle); 174 if (!res.isOk) {
205 if (!res.isOk) { 175 throw "MojoHandleWatcher add failed: $res";
206 throw new Exception("MojoHandleWatcher add failed: $res");
207 }
208 _eventHandlerAdded = false;
209 } 176 }
210 } else { 177 } else {
211 if (!_eventHandlerAdded) { 178 var res = MojoHandleWatcher.add(_handle, _sendPort, _signals.value);
212 var res = MojoHandleWatcher.add(_handle, _sendPort, _signals); 179 if (!res.isOk) {
213 if (!res.isOk) { 180 throw "MojoHandleWatcher add failed: $res";
214 throw new Exception("MojoHandleWatcher add failed: $res");
215 }
216 _eventHandlerAdded = true;
217 } 181 }
218 } 182 }
219 } 183 }
220 184
185 bool get readyRead => _handle.readyRead;
186 bool get readyWrite => _handle.readyWrite;
187
221 String toString() => "$_handle"; 188 String toString() => "$_handle";
222 } 189 }
OLDNEW
« no previous file with comments | « mojo/public/dart/src/data_pipe.dart ('k') | mojo/public/dart/src/handle_watcher.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698