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

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

Issue 9720045: Extend dart:io error handling to all socket functions (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed review comments 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
« no previous file with comments | « runtime/bin/socket.dart ('k') | runtime/bin/socket_linux.cc » ('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 (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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 if (eventHandler != null) { 57 if (eventHandler != null) {
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("")); 67 eventHandler(new SocketIOException("", _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 11 matching lines...) Expand all
89 _closedRead && 89 _closedRead &&
90 _handlerMask == 0 && 90 _handlerMask == 0 &&
91 _handler != null) { 91 _handler != null) {
92 _handler.close(); 92 _handler.close();
93 _handler = null; 93 _handler = null;
94 } else { 94 } else {
95 _activateHandlers(); 95 _activateHandlers();
96 } 96 }
97 } 97 }
98 98
99 OSError _getError() native "Socket_GetError";
99 int _getPort() native "Socket_GetPort"; 100 int _getPort() native "Socket_GetPort";
100 101
101 void set onError(void callback(Exception e)) { 102 void set onError(void callback(Exception e)) {
102 _setHandler(_ERROR_EVENT, callback); 103 _setHandler(_ERROR_EVENT, callback);
103 } 104 }
104 105
105 void _activateHandlers() { 106 void _activateHandlers() {
106 if (_canActivateHandlers && (_id >= 0)) { 107 if (_canActivateHandlers && (_id >= 0)) {
107 if (_handlerMask == 0) { 108 if (_handlerMask == 0) {
108 if (_handler != null) { 109 if (_handler != null) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 179
179 void _sendToEventHandler(int data) { 180 void _sendToEventHandler(int data) {
180 if (_handler === null) { 181 if (_handler === null) {
181 _handler = new ReceivePort(); 182 _handler = new ReceivePort();
182 _handler.receive((var message, ignored) { _multiplex(message); }); 183 _handler.receive((var message, ignored) { _multiplex(message); });
183 } 184 }
184 assert(_id >= 0); 185 assert(_id >= 0);
185 _EventHandler._sendData(_id, _handler, data); 186 _EventHandler._sendData(_id, _handler, data);
186 } 187 }
187 188
189 bool _reportError(error, String message) {
190 // For all errors we close the socket, call the error handler and
191 // disable further calls of the error handler.
192 close();
193 var onError = _handlerMap[_ERROR_EVENT];
194 if (onError != null) {
195 if (error is OSError) {
196 onError(new SocketIOException(message, error));
197 } else if (error is List) {
198 assert(_isErrorResponse(error));
199 switch (error[0]) {
200 case _FileUtils.kIllegalArgumentResponse:
201 onError(new IllegalArgumentException());
202 break;
203 case _FileUtils.kOSErrorResponse:
204 onError(new SocketIOException(
205 message, new OSError(error[2], error[1])));
206 break;
207 default:
208 onError(new Exception("Unknown error"));
209 break;
210 }
211 } else {
212 onError(new SocketIOException(message));
213 }
214 }
215 }
216
188 int hashCode() => _hashCode; 217 int hashCode() => _hashCode;
189 218
190 abstract bool _isListenSocket(); 219 abstract bool _isListenSocket();
191 abstract bool _isPipe(); 220 abstract bool _isPipe();
192 221
193 // Socket id is set from native. -1 indicates that the socket was closed. 222 // Socket id is set from native. -1 indicates that the socket was closed.
194 int _id; 223 int _id;
195 224
196 // Dedicated ReceivePort for socket events. 225 // Dedicated ReceivePort for socket events.
197 ReceivePort _handler; 226 ReceivePort _handler;
(...skipping 19 matching lines...) Expand all
217 246
218 247
219 class _ServerSocket extends _SocketBase implements ServerSocket { 248 class _ServerSocket extends _SocketBase implements ServerSocket {
220 // Constructor for server socket. First a socket object is allocated 249 // Constructor for server socket. First a socket object is allocated
221 // in which the native socket is stored. After that _createBind 250 // in which the native socket is stored. After that _createBind
222 // is called which creates a file descriptor and binds the given address 251 // is called which creates a file descriptor and binds the given address
223 // and port to the socket. Null is returned if file descriptor creation or 252 // and port to the socket. Null is returned if file descriptor creation or
224 // bind failed. 253 // bind failed.
225 factory _ServerSocket(String bindAddress, int port, int backlog) { 254 factory _ServerSocket(String bindAddress, int port, int backlog) {
226 _ServerSocket socket = new _ServerSocket._internal(); 255 _ServerSocket socket = new _ServerSocket._internal();
227 if (!socket._createBindListen(bindAddress, port, backlog)) { 256 var result = socket._createBindListen(bindAddress, port, backlog);
257 if (result is OSError) {
228 socket.close(); 258 socket.close();
229 return null; 259 throw new SocketIOException("Failed to create server socket", result);
230 } 260 }
261 assert(result);
231 if (port != 0) { 262 if (port != 0) {
232 socket._port = port; 263 socket._port = port;
233 } 264 }
234 return socket; 265 return socket;
235 } 266 }
236 267
237 _ServerSocket._internal(); 268 _ServerSocket._internal();
238 269
239 bool _accept(Socket socket) native "ServerSocket_Accept"; 270 bool _accept(Socket socket) native "ServerSocket_Accept";
240 271
241 bool _createBindListen(String bindAddress, int port, int backlog) 272 bool _createBindListen(String bindAddress, int port, int backlog)
242 native "ServerSocket_CreateBindListen"; 273 native "ServerSocket_CreateBindListen";
243 274
244 void set onConnection(void callback(Socket connection)) { 275 void set onConnection(void callback(Socket connection)) {
245 _clientConnectionHandler = callback; 276 _clientConnectionHandler = callback;
246 _setHandler(_IN_EVENT, 277 _setHandler(_IN_EVENT,
247 _clientConnectionHandler != null ? _connectionHandler : null); 278 _clientConnectionHandler != null ? _connectionHandler : null);
248 } 279 }
249 280
250 void _connectionHandler() { 281 void _connectionHandler() {
251 if (_id >= 0) { 282 if (_id >= 0) {
252 _Socket socket = new _Socket._internal(); 283 _Socket socket = new _Socket._internal();
253 if (_accept(socket)) _clientConnectionHandler(socket); 284 var result = _accept(socket);
285 if (result is OSError) {
286 _reportError(result, "Accept failed");
287 } else {
288 _clientConnectionHandler(socket);
289 }
254 } 290 }
255 } 291 }
256 292
257 bool _isListenSocket() => true; 293 bool _isListenSocket() => true;
258 bool _isPipe() => false; 294 bool _isPipe() => false;
259 295
260 var _clientConnectionHandler; 296 var _clientConnectionHandler;
261 } 297 }
262 298
263 299
264 class _Socket extends _SocketBase implements Socket { 300 class _Socket extends _SocketBase implements Socket {
265 static final kSuccessResponse = 0; 301 static final kSuccessResponse = 0;
266 static final kIllegalArgumentResponse = 1; 302 static final kIllegalArgumentResponse = 1;
267 static final kOSErrorResponse = 2; 303 static final kOSErrorResponse = 2;
268 304
269 static final kHostNameLookup = 0; 305 static final kHostNameLookup = 0;
270 306
271 // Constructs a new socket. During the construction an asynchronous 307 // Constructs a new socket. During the construction an asynchronous
272 // host name lookup is initiated. The returned socket is not yet 308 // host name lookup is initiated. The returned socket is not yet
273 // connected but ready for registration of callbacks. 309 // connected but ready for registration of callbacks.
274 factory _Socket(String host, int port) { 310 factory _Socket(String host, int port) {
275 Socket socket = new _Socket._internal(); 311 Socket socket = new _Socket._internal();
276 _ensureSocketService(); 312 _ensureSocketService();
277 List request = new List(2); 313 List request = new List(2);
278 request[0] = kHostNameLookup; 314 request[0] = kHostNameLookup;
279 request[1] = host; 315 request[1] = host;
280 _socketService.call(request).then((response) { 316 _socketService.call(request).then((response) {
281 if (socket._isErrorResponse(response)) { 317 if (socket._isErrorResponse(response)) {
282 socket._reportError(response, "Failed host name lookup"); 318 socket._reportError(response, "Failed host name lookup");
283 } else { 319 } else{
284 if (!socket._createConnect(response, port)) { 320 var result = socket._createConnect(response, port);
321 if (result is OSError) {
285 socket.close(); 322 socket.close();
286 socket._reportError(null, "Connection failed"); 323 socket._reportError(result, "Connection failed");
287 } else { 324 } else {
288 socket._activateHandlers(); 325 socket._activateHandlers();
289 } 326 }
290 } 327 }
291 }); 328 });
292 return socket; 329 return socket;
293 } 330 }
294 331
295 _Socket._internal(); 332 _Socket._internal();
296 _Socket._internalReadOnly() : _pipe = true { super._closedWrite = true; } 333 _Socket._internalReadOnly() : _pipe = true { super._closedWrite = true; }
(...skipping 17 matching lines...) Expand all
314 if (offset < 0) { 351 if (offset < 0) {
315 throw new IndexOutOfRangeException(offset); 352 throw new IndexOutOfRangeException(offset);
316 } 353 }
317 if (bytes < 0) { 354 if (bytes < 0) {
318 throw new IndexOutOfRangeException(bytes); 355 throw new IndexOutOfRangeException(bytes);
319 } 356 }
320 if ((offset + bytes) > buffer.length) { 357 if ((offset + bytes) > buffer.length) {
321 throw new IndexOutOfRangeException(offset + bytes); 358 throw new IndexOutOfRangeException(offset + bytes);
322 } 359 }
323 int result = _readList(buffer, offset, bytes); 360 int result = _readList(buffer, offset, bytes);
324 if (result < 0) { 361 if (result is OSError) {
325 _reportError(null, "Read failed"); 362 _reportError(result, "Read failed");
363 return -1;
326 } 364 }
327 return result; 365 return result;
328 } 366 }
329 throw new 367 throw new
330 SocketIOException("Error: readList failed - invalid socket handle"); 368 SocketIOException("Error: readList failed - invalid socket handle");
331 } 369 }
332 370
333 int _readList(List<int> buffer, int offset, int bytes) 371 int _readList(List<int> buffer, int offset, int bytes)
334 native "Socket_ReadList"; 372 native "Socket_ReadList";
335 373
(...skipping 25 matching lines...) Expand all
361 for (int i = 0; i < bytes; i++) { 399 for (int i = 0; i < bytes; i++) {
362 int value = buffer[j]; 400 int value = buffer[j];
363 if (value is! int) { 401 if (value is! int) {
364 throw new FileIOException( 402 throw new FileIOException(
365 "List element is not an integer at index $j"); 403 "List element is not an integer at index $j");
366 } 404 }
367 outBuffer[i] = value; 405 outBuffer[i] = value;
368 j++; 406 j++;
369 } 407 }
370 } 408 }
371 var bytes_written = _writeList(outBuffer, outOffset, bytes); 409 var result = _writeList(outBuffer, outOffset, bytes);
372 if (bytes_written < 0) { 410 if (result is OSError) {
373 // If writing fails we return 0 as the number of bytes and 411 // If writing fails we return 0 as the number of bytes and
374 // report the error on the error handler. 412 // report the error on the error handler.
375 bytes_written = 0; 413 result = 0;
376 _reportError(null, "Write failed"); 414 _reportError(result, "Write failed");
377 } 415 }
378 return bytes_written; 416 return result;
379 } 417 }
380 throw new 418 throw new SocketIOException("writeList failed - invalid socket handle");
381 SocketIOException("Error: writeList failed - invalid socket handle");
382 } 419 }
383 420
384 int _writeList(List<int> buffer, int offset, int bytes) 421 int _writeList(List<int> buffer, int offset, int bytes)
385 native "Socket_WriteList"; 422 native "Socket_WriteList";
386 423
387 bool _isErrorResponse(response) { 424 bool _isErrorResponse(response) {
388 return response is List && response[0] != _FileUtils.kSuccessResponse; 425 return response is List && response[0] != _FileUtils.kSuccessResponse;
389 } 426 }
390 427
391 bool _reportError(response, String message) {
392 if (response != null) {
393 assert(_isErrorResponse(response));
394 }
395 // For all errors we close the socket, call the error handler and
396 // disable further calls of the error handler.
397 close();
398 var onError = _handlerMap[_ERROR_EVENT];
399 if (onError != null) {
400 if (response != null) {
401 switch (response[0]) {
402 case _FileUtils.kIllegalArgumentResponse:
403 onError(new IllegalArgumentException());
404 break;
405 case _FileUtils.kOSErrorResponse:
406 onError(new SocketIOException(
407 message, new OSError(response[2], response[1])));
408 break;
409 default:
410 onError(new Exception("Unknown error"));
411 break;
412 }
413 } else {
414 onError(new SocketIOException(message));
415 }
416 }
417 }
418
419 bool _createConnect(String host, int port) native "Socket_CreateConnect"; 428 bool _createConnect(String host, int port) native "Socket_CreateConnect";
420 429
421 void set onWrite(void callback()) { 430 void set onWrite(void callback()) {
422 if (_outputStream != null) throw new StreamException( 431 if (_outputStream != null) throw new StreamException(
423 "Cannot set write handler when output stream is used"); 432 "Cannot set write handler when output stream is used");
424 _clientWriteHandler = callback; 433 _clientWriteHandler = callback;
425 _updateOutHandler(); 434 _updateOutHandler();
426 } 435 }
427 436
428 void set onConnect(void callback()) { 437 void set onConnect(void callback()) {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 } 537 }
529 538
530 bool _seenFirstOutEvent = false; 539 bool _seenFirstOutEvent = false;
531 bool _pipe = false; 540 bool _pipe = false;
532 Function _clientConnectHandler; 541 Function _clientConnectHandler;
533 Function _clientWriteHandler; 542 Function _clientWriteHandler;
534 SocketInputStream _inputStream; 543 SocketInputStream _inputStream;
535 SocketOutputStream _outputStream; 544 SocketOutputStream _outputStream;
536 static SendPort _socketService; 545 static SendPort _socketService;
537 } 546 }
OLDNEW
« no previous file with comments | « runtime/bin/socket.dart ('k') | runtime/bin/socket_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698