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

Side by Side Diff: runtime/bin/socket_impl.dart

Issue 9812007: Add error handling to socket streams (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 5
6 class _SocketBase { 6 class _SocketBase {
7 // Bit flags used when communicating between the eventhandler and 7 // Bit flags used when communicating between the eventhandler and
8 // dart code. The EVENT flags are used to indicate events of 8 // dart code. The EVENT flags are used to indicate events of
9 // interest when sending a message from dart code to the 9 // interest when sending a message from dart code to the
10 // eventhandler. When receiving a message from the eventhandler the 10 // eventhandler. When receiving a message from the eventhandler the
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 void _multiplex(int event_mask) { 47 void _multiplex(int event_mask) {
48 _canActivateHandlers = false; 48 _canActivateHandlers = false;
49 for (int i = _FIRST_EVENT; i <= _LAST_EVENT; i++) { 49 for (int i = _FIRST_EVENT; i <= _LAST_EVENT; i++) {
50 if (((event_mask & (1 << i)) != 0)) { 50 if (((event_mask & (1 << i)) != 0)) {
51 if ((i == _CLOSE_EVENT) && this is _Socket && _id >= 0) { 51 if ((i == _CLOSE_EVENT) && this is _Socket && _id >= 0) {
52 _closedRead = true; 52 _closedRead = true;
53 if (_closedWrite) _close(); 53 if (_closedWrite) _close();
54 } 54 }
55 55
56 var eventHandler = _handlerMap[i]; 56 var eventHandler = _handlerMap[i];
57 if (eventHandler != null) { 57 if (eventHandler != null || i == _ERROR_EVENT) {
58 // Unregister the out handler before executing it. 58 // Unregister the out handler before executing it.
59 if (i == _OUT_EVENT) _setHandler(i, null); 59 if (i == _OUT_EVENT) _setHandler(i, null);
60 60
61 // Don't call the in handler if there is no data available 61 // Don't call the in handler if there is no data available
62 // after all. 62 // after all.
63 if ((i == _IN_EVENT) && (this is _Socket) && (available() == 0)) { 63 if ((i == _IN_EVENT) && (this is _Socket) && (available() == 0)) {
64 continue; 64 continue;
65 } 65 }
66 if (i == _ERROR_EVENT) { 66 if (i == _ERROR_EVENT) {
67 eventHandler(new SocketIOException("", _getError())); 67 _reportError(_getError(), "");
68 close(); 68 close();
69 } else { 69 } else {
70 eventHandler(); 70 eventHandler();
71 } 71 }
72 } 72 }
73 } 73 }
74 } 74 }
75 _canActivateHandlers = true; 75 _canActivateHandlers = true;
76 _activateHandlers(); 76 _activateHandlers();
77 } 77 }
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 void _sendToEventHandler(int data) { 180 void _sendToEventHandler(int data) {
181 if (_handler === null) { 181 if (_handler === null) {
182 _handler = new ReceivePort(); 182 _handler = new ReceivePort();
183 _handler.receive((var message, ignored) { _multiplex(message); }); 183 _handler.receive((var message, ignored) { _multiplex(message); });
184 } 184 }
185 assert(_id >= 0); 185 assert(_id >= 0);
186 _EventHandler._sendData(_id, _handler, data); 186 _EventHandler._sendData(_id, _handler, data);
187 } 187 }
188 188
189 bool _reportError(error, String message) { 189 bool _reportError(error, String message) {
190 void doReportError(Exception e) {
191 // Invoke the error callback if any.
192 if (_handlerMap[_ERROR_EVENT] != null) {
193 _handlerMap[_ERROR_EVENT](e);
194 }
195 // Propagate the error to any additional listeners.
196 _propagateError(e);
197 }
198
190 // For all errors we close the socket, call the error handler and 199 // For all errors we close the socket, call the error handler and
191 // disable further calls of the error handler. 200 // disable further calls of the error handler.
192 close(); 201 close();
193 var onError = _handlerMap[_ERROR_EVENT]; 202 if (error is OSError) {
194 if (onError != null) { 203 doReportError(new SocketIOException(message, error));
195 if (error is OSError) { 204 } else if (error is List) {
196 onError(new SocketIOException(message, error)); 205 assert(_isErrorResponse(error));
197 } else if (error is List) { 206 switch (error[0]) {
198 assert(_isErrorResponse(error)); 207 case _FileUtils.kIllegalArgumentResponse:
199 switch (error[0]) { 208 doReportError(new IllegalArgumentException());
200 case _FileUtils.kIllegalArgumentResponse: 209 break;
201 onError(new IllegalArgumentException()); 210 case _FileUtils.kOSErrorResponse:
202 break; 211 doReportError(new SocketIOException(
203 case _FileUtils.kOSErrorResponse: 212 message, new OSError(error[2], error[1])));
204 onError(new SocketIOException( 213 break;
205 message, new OSError(error[2], error[1]))); 214 default:
206 break; 215 doReportError(new Exception("Unknown error"));
207 default: 216 break;
208 onError(new Exception("Unknown error"));
209 break;
210 }
211 } else {
212 onError(new SocketIOException(message));
213 } 217 }
218 } else {
219 doReportError(new SocketIOException(message));
214 } 220 }
215 } 221 }
216 222
217 int hashCode() => _hashCode; 223 int hashCode() => _hashCode;
218 224
225 void _propagateError(Exception e) => null;
226
219 abstract bool _isListenSocket(); 227 abstract bool _isListenSocket();
220 abstract bool _isPipe(); 228 abstract bool _isPipe();
221 229
222 // Socket id is set from native. -1 indicates that the socket was closed. 230 // Socket id is set from native. -1 indicates that the socket was closed.
223 int _id; 231 int _id;
224 232
225 // Dedicated ReceivePort for socket events. 233 // Dedicated ReceivePort for socket events.
226 ReceivePort _handler; 234 ReceivePort _handler;
227 235
228 // Poll event to handler map. 236 // Poll event to handler map.
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 if (_inputStream != null) throw new StreamException( 465 if (_inputStream != null) throw new StreamException(
458 "Cannot set close handler when input stream is used"); 466 "Cannot set close handler when input stream is used");
459 _onClosed = callback; 467 _onClosed = callback;
460 } 468 }
461 469
462 bool _isListenSocket() => false; 470 bool _isListenSocket() => false;
463 471
464 bool _isPipe() => _pipe; 472 bool _isPipe() => _pipe;
465 473
466 InputStream get inputStream() { 474 InputStream get inputStream() {
467 if (_inputStream === null) { 475 if (_inputStream == null) {
468 if (_handlerMap[_IN_EVENT] !== null || 476 if (_handlerMap[_IN_EVENT] !== null ||
469 _handlerMap[_CLOSE_EVENT] !== null) { 477 _handlerMap[_CLOSE_EVENT] !== null) {
470 throw new StreamException( 478 throw new StreamException(
471 "Cannot get input stream when socket handlers are used"); 479 "Cannot get input stream when socket handlers are used");
472 } 480 }
473 _inputStream = new SocketInputStream(this); 481 _inputStream = new SocketInputStream(this);
474 } 482 }
475 return _inputStream; 483 return _inputStream;
476 } 484 }
477 485
478 OutputStream get outputStream() { 486 OutputStream get outputStream() {
479 if (_outputStream === null) { 487 if (_outputStream == null) {
480 if (_handlerMap[_OUT_EVENT] !== null) { 488 if (_handlerMap[_OUT_EVENT] !== null) {
481 throw new StreamException( 489 throw new StreamException(
482 "Cannot get input stream when socket handlers are used"); 490 "Cannot get input stream when socket handlers are used");
483 } 491 }
484 _outputStream = new SocketOutputStream(this); 492 _outputStream = new SocketOutputStream(this);
485 } 493 }
486 return _outputStream; 494 return _outputStream;
487 } 495 }
488 496
489 void set _onWrite(void callback()) { 497 void set _onWrite(void callback()) {
490 _setHandler(_OUT_EVENT, callback); 498 _setHandler(_OUT_EVENT, callback);
491 } 499 }
492 500
493 void set _onData(void callback()) { 501 void set _onData(void callback()) {
494 _setHandler(_IN_EVENT, callback); 502 _setHandler(_IN_EVENT, callback);
495 } 503 }
496 504
497 void set _onClosed(void callback()) { 505 void set _onClosed(void callback()) {
498 _setHandler(_CLOSE_EVENT, callback); 506 _setHandler(_CLOSE_EVENT, callback);
499 } 507 }
500 508
509 void _propagateError(Exception e) {
510 if (_inputStream != null) {
511 _inputStream._onError(e);
512 }
513 if (_outputStream != null) {
514 _outputStream._onError(e);
515 }
516 }
517
501 void _updateOutHandler() { 518 void _updateOutHandler() {
502 void firstWriteHandler() { 519 void firstWriteHandler() {
503 assert(!_seenFirstOutEvent); 520 assert(!_seenFirstOutEvent);
504 _seenFirstOutEvent = true; 521 _seenFirstOutEvent = true;
505 522
506 // From now on the write handler is only the client write 523 // From now on the write handler is only the client write
507 // handler (connect handler cannot be called again). Change this 524 // handler (connect handler cannot be called again). Change this
508 // before calling any handlers as handlers can change the 525 // before calling any handlers as handlers can change the
509 // handlers. 526 // handlers.
510 if (_clientWriteHandler === null) _onWrite = _clientWriteHandler; 527 if (_clientWriteHandler === null) _onWrite = _clientWriteHandler;
(...skipping 26 matching lines...) Expand all
537 } 554 }
538 555
539 bool _seenFirstOutEvent = false; 556 bool _seenFirstOutEvent = false;
540 bool _pipe = false; 557 bool _pipe = false;
541 Function _clientConnectHandler; 558 Function _clientConnectHandler;
542 Function _clientWriteHandler; 559 Function _clientWriteHandler;
543 SocketInputStream _inputStream; 560 SocketInputStream _inputStream;
544 SocketOutputStream _outputStream; 561 SocketOutputStream _outputStream;
545 static SendPort _socketService; 562 static SendPort _socketService;
546 } 563 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698