| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |