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

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: 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
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(MojoHandle handle) native "MojoHandle_Register";
9 static int close(int handle) native "MojoHandle_Close"; 9 static int close(int handle) native "MojoHandle_Close";
10 static int wait(int handle, int signals, int deadline) 10 static int wait(int handle, int signals, int deadline)
(...skipping 16 matching lines...) Expand all
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 MojoResult wait(int signals, int deadline) { 32 MojoResult wait(int signals, int deadline) {
33 int result = _MojoHandleNatives.wait(h, signals, deadline); 33 int result = _MojoHandleNatives.wait(h, signals, deadline);
34 return new MojoResult(result); 34 return new MojoResult(result);
35 } 35 }
36 36
37 bool _ready(int signal) { 37 bool _ready(MojoHandleSignals signal) {
38 MojoResult res = wait(signal, 0); 38 MojoResult res = wait(signal.value, 0);
39 switch (res) { 39 switch (res) {
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 int waitMany(List<int> handles, 56 static int waitMany(List<int> handles,
57 List<int> signals, 57 List<int> signals,
58 int deadline) { 58 int deadline) {
59 if (handles.length != signals.length) { 59 if (handles.length != signals.length) {
60 return MojoResult.kInvalidArgument; 60 return MojoResult.kInvalidArgument;
61 } 61 }
62 return _MojoHandleNatives.waitMany( 62 return _MojoHandleNatives.waitMany(
63 handles, signals, handles.length, deadline); 63 handles, signals, handles.length, deadline);
64 } 64 }
(...skipping 22 matching lines...) Expand all
87 87
88 // The send port that we give to the handle watcher to notify us of handle 88 // The send port that we give to the handle watcher to notify us of handle
89 // events. 89 // events.
90 SendPort _sendPort; 90 SendPort _sendPort;
91 91
92 // The receive port on which we listen and receive events from the handle 92 // The receive port on which we listen and receive events from the handle
93 // watcher. 93 // watcher.
94 ReceivePort _receivePort; 94 ReceivePort _receivePort;
95 95
96 // The signals on this handle that we're interested in. 96 // The signals on this handle that we're interested in.
97 int _signals; 97 MojoHandleSignals _signals;
98 98
99 // Whether the handle has been added to the handle watcher. 99 // Whether listen has been called.
100 bool _eventHandlerAdded; 100 bool _isListening;
101 101
102 MojoHandle(this._handle) : 102 MojoHandle(RawMojoHandle handle,
103 _signals = MojoHandleSignals.READABLE, 103 [MojoHandleSignals signals = MojoHandleSignals.READABLE]) :
abarth-chromium 2015/01/04 08:46:07 Why should a handle be associated with a set of si
zra 2015/01/05 15:45:41 Maybe the following renaming could clear things up
zra 2015/01/05 21:22:31 Done.
104 _eventHandlerAdded = false { 104 _handle = handle,
105 _signals = signals,
106 _isListening = false {
105 MojoResult result = RawMojoHandle.register(this); 107 MojoResult result = RawMojoHandle.register(this);
106 if (!result.isOk) { 108 if (!result.isOk) {
107 throw new Exception("Failed to register the MojoHandle"); 109 throw "Failed to register the MojoHandle: $result.";
108 } 110 }
109 } 111 }
110 112
111 void close() { 113 void close() {
112 if (_eventHandlerAdded) { 114 if (_handle != null) {
113 MojoHandleWatcher.close(_handle); 115 MojoHandleWatcher.close(_handle);
114 _eventHandlerAdded = false;
115 } else {
116 // If we're not in the handle watcher, then close the handle manually.
117 _handle.close(); 116 _handle.close();
117 _handle = null;
118 } 118 }
119 if (_receivePort != null) { 119 if (_receivePort != null) {
120 _receivePort.close(); 120 _receivePort.close();
121 _receivePort = null;
121 } 122 }
122 } 123 }
123 124
124 // We wrap the callback provided by clients in listen() with some code to 125 StreamSubscription<List<int>> listen(
125 // handle adding and removing the handle to/from the handle watcher. Because 126 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}) { 127 {Function onError, void onDone(), bool cancelOnError}) {
128 if (_isListening) {
129 throw "Listen has already been called: $_handle.";
130 }
150 _receivePort = new ReceivePort(); 131 _receivePort = new ReceivePort();
151 _sendPort = _receivePort.sendPort; 132 _sendPort = _receivePort.sendPort;
152 _controller = new StreamController(sync: true, 133 _controller = new StreamController(sync: true,
153 onListen: _onSubscriptionStateChange, 134 onListen: _onSubscriptionStateChange,
154 onCancel: _onSubscriptionStateChange, 135 onCancel: _onSubscriptionStateChange,
155 onPause: _onPauseStateChange, 136 onPause: _onPauseStateChange,
156 onResume: _onPauseStateChange); 137 onResume: _onPauseStateChange);
157 _controller.addStream(_receivePort); 138 _controller.addStream(_receivePort);
158 139
159 assert(!_eventHandlerAdded); 140 if (_signals != MojoHandleSignals.NONE) {
160 var res = MojoHandleWatcher.add(_handle, _sendPort, _signals); 141 var res = MojoHandleWatcher.add(_handle, _sendPort, _signals.value);
161 if (!res.isOk) { 142 if (!res.isOk) {
162 throw new Exception("MojoHandleWatcher add failed: $res"); 143 throw "MojoHandleWatcher add failed: $res";
144 }
163 } 145 }
164 _eventHandlerAdded = true;
165 146
147 _isListening = true;
166 return _controller.stream.listen( 148 return _controller.stream.listen(
167 _onDataClosure(onData), 149 onData,
168 onError: onError, 150 onError: onError,
169 onDone: onDone, 151 onDone: onDone,
170 cancelOnError: cancelOnError); 152 cancelOnError: cancelOnError);
171 } 153 }
172 154
173 bool writeEnabled() => MojoHandleSignals.isWritable(_signals); 155 void enableSignals(MojoHandleSignals signals) {
174 156 _signals = signals;
175 void toggleWriteEvents() { 157 if (_isListening) {
176 _signals = MojoHandleSignals.toggleWrite(_signals); 158 var res = MojoHandleWatcher.add(_handle, _sendPort, signals.value);
177 if (_eventHandlerAdded) {
178 var res = MojoHandleWatcher.toggleWrite(_handle);
179 if (!res.isOk) { 159 if (!res.isOk) {
180 throw new Exception("MojoHandleWatcher failed to toggle write: $res"); 160 throw "MojoHandleWatcher add failed: $res";
181 } 161 }
182 } 162 }
183 } 163 }
184 164
185 void enableWriteEvents() { 165 void enableReadEvents() => enableSignals(MojoHandleSignals.READABLE);
186 assert(!writeEnabled()); 166 void enableWriteEvents() => enableSignals(MojoHandleSignals.WRITABLE);
187 toggleWriteEvents(); 167 void enableAllEvents() => enableSignals(MojoHandleSignals.READWRITE);
188 }
189
190 void disableWriteEvents() {
191 assert(writeEnabled());
192 toggleWriteEvents();
193 }
194 168
195 void _onSubscriptionStateChange() { 169 void _onSubscriptionStateChange() {
196 if (!_controller.hasListener) { 170 if (!_controller.hasListener) {
197 close(); 171 close();
198 } 172 }
199 } 173 }
200 174
201 void _onPauseStateChange() { 175 void _onPauseStateChange() {
202 if (_controller.isPaused) { 176 if (_controller.isPaused) {
203 if (_eventHandlerAdded) { 177 var res = MojoHandleWatcher.remove(_handle);
204 var res = MojoHandleWatcher.remove(_handle); 178 if (!res.isOk) {
205 if (!res.isOk) { 179 throw "MojoHandleWatcher add failed: $res";
206 throw new Exception("MojoHandleWatcher add failed: $res");
207 }
208 _eventHandlerAdded = false;
209 } 180 }
210 } else { 181 } else {
211 if (!_eventHandlerAdded) { 182 var res = MojoHandleWatcher.add(_handle, _sendPort, _signals.value);
212 var res = MojoHandleWatcher.add(_handle, _sendPort, _signals); 183 if (!res.isOk) {
213 if (!res.isOk) { 184 throw "MojoHandleWatcher add failed: $res";
214 throw new Exception("MojoHandleWatcher add failed: $res");
215 }
216 _eventHandlerAdded = true;
217 } 185 }
218 } 186 }
219 } 187 }
220 188
189 bool get readyRead => _handle.readyRead;
190 bool get readyWrite => _handle.readyWrite;
191
221 String toString() => "$_handle"; 192 String toString() => "$_handle";
222 } 193 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698