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

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

Issue 10962012: Use native wrapper fields to store socket ids. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 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 extends NativeFieldWrapperClass1 {
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
11 // EVENT flags indicate the events that actually happened. The 11 // EVENT flags indicate the events that actually happened. The
12 // COMMAND flags are used to send commands from dart to the 12 // COMMAND flags are used to send commands from dart to the
13 // eventhandler. COMMAND flags are never received from the 13 // eventhandler. COMMAND flags are never received from the
14 // eventhandler. Additional flags are used to communicate other 14 // eventhandler. Additional flags are used to communicate other
15 // information. 15 // information.
16 static const int _IN_EVENT = 0; 16 static const int _IN_EVENT = 0;
(...skipping 13 matching lines...) Expand all
30 static const int _FIRST_EVENT = _IN_EVENT; 30 static const int _FIRST_EVENT = _IN_EVENT;
31 static const int _LAST_EVENT = _CLOSE_EVENT; 31 static const int _LAST_EVENT = _CLOSE_EVENT;
32 32
33 static const int _FIRST_COMMAND = _CLOSE_COMMAND; 33 static const int _FIRST_COMMAND = _CLOSE_COMMAND;
34 static const int _LAST_COMMAND = _SHUTDOWN_WRITE_COMMAND; 34 static const int _LAST_COMMAND = _SHUTDOWN_WRITE_COMMAND;
35 35
36 _SocketBase () { 36 _SocketBase () {
37 _handlerMap = new List(_LAST_EVENT + 1); 37 _handlerMap = new List(_LAST_EVENT + 1);
38 _handlerMask = 0; 38 _handlerMask = 0;
39 _canActivateHandlers = true; 39 _canActivateHandlers = true;
40 _id = -1; 40 _closed = true;
Søren Gjesse 2012/09/21 06:47:06 We could consider making this a state with 3 value
Mads Ager (google) 2012/09/21 08:18:25 Yes, we could do that to give better error message
41 _EventHandler._start(); 41 _EventHandler._start();
42 _hashCode = _nextHashCode; 42 _hashCode = _nextHashCode;
43 _nextHashCode = (_nextHashCode + 1) & 0xFFFFFFF; 43 _nextHashCode = (_nextHashCode + 1) & 0xFFFFFFF;
44 } 44 }
45 45
46 // Multiplexes socket events to the socket handlers. 46 // Multiplexes socket events to the socket handlers.
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 && !_closed) {
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 || i == _ERROR_EVENT) { 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
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 } 97 }
98 98
99 OSError _getError() native "Socket_GetError"; 99 OSError _getError() native "Socket_GetError";
100 int _getPort() native "Socket_GetPort"; 100 int _getPort() native "Socket_GetPort";
101 101
102 void set onError(void callback(e)) { 102 void set onError(void callback(e)) {
103 _setHandler(_ERROR_EVENT, callback); 103 _setHandler(_ERROR_EVENT, callback);
104 } 104 }
105 105
106 void _activateHandlers() { 106 void _activateHandlers() {
107 if (_canActivateHandlers && (_id >= 0)) { 107 if (_canActivateHandlers && !_closed) {
108 if (_handlerMask == 0) { 108 if (_handlerMask == 0) {
109 if (_handler != null) { 109 if (_handler != null) {
110 _handler.close(); 110 _handler.close();
111 _handler = null; 111 _handler = null;
112 } 112 }
113 return; 113 return;
114 } 114 }
115 int data = _handlerMask; 115 int data = _handlerMask;
116 if (_isListenSocket()) { 116 if (_isListenSocket()) {
117 data |= (1 << _LISTENING_SOCKET); 117 data |= (1 << _LISTENING_SOCKET);
118 } else { 118 } else {
119 if (_closedRead) { data &= ~(1 << _IN_EVENT); } 119 if (_closedRead) { data &= ~(1 << _IN_EVENT); }
120 if (_closedWrite) { data &= ~(1 << _OUT_EVENT); } 120 if (_closedWrite) { data &= ~(1 << _OUT_EVENT); }
121 if (_isPipe()) data |= (1 << _PIPE); 121 if (_isPipe()) data |= (1 << _PIPE);
122 } 122 }
123 _sendToEventHandler(data); 123 _sendToEventHandler(data);
124 } 124 }
125 } 125 }
126 126
127 int get port { 127 int get port {
128 if (_port === null) { 128 if (_port === null) {
129 _port = _getPort(); 129 _port = _getPort();
130 } 130 }
131 return _port; 131 return _port;
132 } 132 }
133 133
134 void close([bool halfClose = false]) { 134 void close([bool halfClose = false]) {
135 if (_id >= 0) { 135 if (!_closed) {
136 if (halfClose) { 136 if (halfClose) {
137 _closeWrite(); 137 _closeWrite();
138 } else { 138 } else {
139 _close(); 139 _close();
140 } 140 }
141 } else if (_handler != null) { 141 } else if (_handler != null) {
142 // This is to support closing sockets created but never assigned 142 // This is to support closing sockets created but never assigned
143 // any actual socket. 143 // any actual socket.
144 _handler.close(); 144 _handler.close();
145 _handler = null; 145 _handler = null;
146 } 146 }
147 } 147 }
148 148
149 void _closeWrite() { 149 void _closeWrite() {
150 if (_id >= 0) { 150 if (!_closed) {
151 if (_closedRead) { 151 if (_closedRead) {
152 _close(); 152 _close();
153 } else { 153 } else {
154 _sendToEventHandler(1 << _SHUTDOWN_WRITE_COMMAND); 154 _sendToEventHandler(1 << _SHUTDOWN_WRITE_COMMAND);
155 } 155 }
156 _closedWrite = true; 156 _closedWrite = true;
157 } 157 }
158 } 158 }
159 159
160 void _closeRead() { 160 void _closeRead() {
161 if (_id >= 0) { 161 if (!_closed) {
162 if (_closedWrite) { 162 if (_closedWrite) {
163 _close(); 163 _close();
164 } else { 164 } else {
165 _sendToEventHandler(1 << _SHUTDOWN_READ_COMMAND); 165 _sendToEventHandler(1 << _SHUTDOWN_READ_COMMAND);
166 } 166 }
167 _closedRead = true; 167 _closedRead = true;
168 } 168 }
169 } 169 }
170 170
171 void _close() { 171 void _close() {
172 if (_id >= 0) { 172 if (!_closed) {
173 _sendToEventHandler(1 << _CLOSE_COMMAND); 173 _sendToEventHandler(1 << _CLOSE_COMMAND);
174 _handler.close(); 174 _handler.close();
175 _handler = null; 175 _handler = null;
176 _id = -1; 176 _closed = true;
177 } 177 }
178 } 178 }
179 179
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(!_closed);
186 _EventHandler._sendData(_id, _handler, data); 186 _EventHandler._sendData(this, _handler, data);
187 } 187 }
188 188
189 bool _reportError(error, String message) { 189 bool _reportError(error, String message) {
190 void doReportError(Exception e) { 190 void doReportError(Exception e) {
191 // Invoke the socket error callback if any. 191 // Invoke the socket error callback if any.
192 bool reported = false; 192 bool reported = false;
193 if (_handlerMap[_ERROR_EVENT] != null) { 193 if (_handlerMap[_ERROR_EVENT] != null) {
194 _handlerMap[_ERROR_EVENT](e); 194 _handlerMap[_ERROR_EVENT](e);
195 reported = true; 195 reported = true;
196 } 196 }
(...skipping 26 matching lines...) Expand all
223 } 223 }
224 } 224 }
225 225
226 int hashCode() => _hashCode; 226 int hashCode() => _hashCode;
227 227
228 bool _propagateError(Exception e) => false; 228 bool _propagateError(Exception e) => false;
229 229
230 abstract bool _isListenSocket(); 230 abstract bool _isListenSocket();
231 abstract bool _isPipe(); 231 abstract bool _isPipe();
232 232
233 // Socket id is set from native. -1 indicates that the socket was closed. 233 // Is this socket closed.
234 int _id; 234 bool _closed;
235 235
236 // Dedicated ReceivePort for socket events. 236 // Dedicated ReceivePort for socket events.
237 ReceivePort _handler; 237 ReceivePort _handler;
238 238
239 // Poll event to handler map. 239 // Poll event to handler map.
240 List _handlerMap; 240 List _handlerMap;
241 241
242 // Indicates for which poll events the socket registered handlers. 242 // Indicates for which poll events the socket registered handlers.
243 int _handlerMask; 243 int _handlerMask;
244 244
(...skipping 17 matching lines...) Expand all
262 // is called which creates a file descriptor and binds the given address 262 // is called which creates a file descriptor and binds the given address
263 // and port to the socket. Null is returned if file descriptor creation or 263 // and port to the socket. Null is returned if file descriptor creation or
264 // bind failed. 264 // bind failed.
265 factory _ServerSocket(String bindAddress, int port, int backlog) { 265 factory _ServerSocket(String bindAddress, int port, int backlog) {
266 _ServerSocket socket = new _ServerSocket._internal(); 266 _ServerSocket socket = new _ServerSocket._internal();
267 var result = socket._createBindListen(bindAddress, port, backlog); 267 var result = socket._createBindListen(bindAddress, port, backlog);
268 if (result is OSError) { 268 if (result is OSError) {
269 socket.close(); 269 socket.close();
270 throw new SocketIOException("Failed to create server socket", result); 270 throw new SocketIOException("Failed to create server socket", result);
271 } 271 }
272 socket._closed = false;
272 assert(result); 273 assert(result);
273 if (port != 0) { 274 if (port != 0) {
274 socket._port = port; 275 socket._port = port;
275 } 276 }
276 return socket; 277 return socket;
277 } 278 }
278 279
279 _ServerSocket._internal(); 280 _ServerSocket._internal();
280 281
281 _accept(Socket socket) native "ServerSocket_Accept"; 282 _accept(Socket socket) native "ServerSocket_Accept";
282 283
283 _createBindListen(String bindAddress, int port, int backlog) 284 _createBindListen(String bindAddress, int port, int backlog)
284 native "ServerSocket_CreateBindListen"; 285 native "ServerSocket_CreateBindListen";
285 286
286 void set onConnection(void callback(Socket connection)) { 287 void set onConnection(void callback(Socket connection)) {
287 _clientConnectionHandler = callback; 288 _clientConnectionHandler = callback;
288 _setHandler(_SocketBase._IN_EVENT, 289 _setHandler(_SocketBase._IN_EVENT,
289 _clientConnectionHandler != null ? _connectionHandler : null); 290 _clientConnectionHandler != null ? _connectionHandler : null);
290 } 291 }
291 292
292 void _connectionHandler() { 293 void _connectionHandler() {
293 if (_id >= 0) { 294 if (!_closed) {
294 _Socket socket = new _Socket._internal(); 295 _Socket socket = new _Socket._internal();
295 var result = _accept(socket); 296 var result = _accept(socket);
296 if (result is OSError) { 297 if (result is OSError) {
297 _reportError(result, "Accept failed"); 298 _reportError(result, "Accept failed");
298 } else if (result) { 299 } else if (result) {
300 socket._closed = false;
299 _clientConnectionHandler(socket); 301 _clientConnectionHandler(socket);
300 } else { 302 } else {
301 // Temporary failure accepting the connection. Ignoring 303 // Temporary failure accepting the connection. Ignoring
302 // temporary failures lets us retry when we wake up with data 304 // temporary failures lets us retry when we wake up with data
303 // on the listening socket again. 305 // on the listening socket again.
304 } 306 }
305 } 307 }
306 } 308 }
307 309
308 bool _isListenSocket() => true; 310 bool _isListenSocket() => true;
(...skipping 17 matching lines...) Expand all
326 request[1] = host; 328 request[1] = host;
327 _socketService.call(request).then((response) { 329 _socketService.call(request).then((response) {
328 if (socket._isErrorResponse(response)) { 330 if (socket._isErrorResponse(response)) {
329 socket._reportError(response, "Failed host name lookup"); 331 socket._reportError(response, "Failed host name lookup");
330 } else{ 332 } else{
331 var result = socket._createConnect(response, port); 333 var result = socket._createConnect(response, port);
332 if (result is OSError) { 334 if (result is OSError) {
333 socket.close(); 335 socket.close();
334 socket._reportError(result, "Connection failed"); 336 socket._reportError(result, "Connection failed");
335 } else { 337 } else {
338 socket._closed = false;
336 socket._activateHandlers(); 339 socket._activateHandlers();
337 } 340 }
338 } 341 }
339 }); 342 });
340 return socket; 343 return socket;
341 } 344 }
342 345
343 _Socket._internal(); 346 _Socket._internal();
344 _Socket._internalReadOnly() : _pipe = true { super._closedWrite = true; } 347 _Socket._internalReadOnly() : _pipe = true { super._closedWrite = true; }
345 _Socket._internalWriteOnly() : _pipe = true { super._closedRead = true; } 348 _Socket._internalWriteOnly() : _pipe = true { super._closedRead = true; }
346 349
347 int available() { 350 int available() {
348 if (_id >= 0) { 351 if (!_closed) {
349 var result = _available(); 352 var result = _available();
350 if (result is OSError) { 353 if (result is OSError) {
351 _reportError(result, "Available failed"); 354 _reportError(result, "Available failed");
352 return 0; 355 return 0;
353 } else { 356 } else {
354 return result; 357 return result;
355 } 358 }
356 } 359 }
357 throw new 360 throw new
358 SocketIOException("Error: available failed - invalid socket handle"); 361 SocketIOException("Error: available failed - invalid socket handle");
359 } 362 }
360 363
361 _available() native "Socket_Available"; 364 _available() native "Socket_Available";
362 365
363 int readList(List<int> buffer, int offset, int bytes) { 366 int readList(List<int> buffer, int offset, int bytes) {
364 if (_id >= 0) { 367 if (!_closed) {
365 if (bytes == 0) { 368 if (bytes == 0) {
366 return 0; 369 return 0;
367 } 370 }
368 if (offset < 0) { 371 if (offset < 0) {
369 throw new IndexOutOfRangeException(offset); 372 throw new IndexOutOfRangeException(offset);
370 } 373 }
371 if (bytes < 0) { 374 if (bytes < 0) {
372 throw new IndexOutOfRangeException(bytes); 375 throw new IndexOutOfRangeException(bytes);
373 } 376 }
374 if ((offset + bytes) > buffer.length) { 377 if ((offset + bytes) > buffer.length) {
375 throw new IndexOutOfRangeException(offset + bytes); 378 throw new IndexOutOfRangeException(offset + bytes);
376 } 379 }
377 var result = _readList(buffer, offset, bytes); 380 var result = _readList(buffer, offset, bytes);
378 if (result is OSError) { 381 if (result is OSError) {
379 _reportError(result, "Read failed"); 382 _reportError(result, "Read failed");
380 return -1; 383 return -1;
381 } 384 }
382 return result; 385 return result;
383 } 386 }
384 throw new 387 throw new
385 SocketIOException("Error: readList failed - invalid socket handle"); 388 SocketIOException("Error: readList failed - invalid socket handle");
386 } 389 }
387 390
388 _readList(List<int> buffer, int offset, int bytes) 391 _readList(List<int> buffer, int offset, int bytes) native "Socket_ReadList";
389 native "Socket_ReadList";
390 392
391 int writeList(List<int> buffer, int offset, int bytes) { 393 int writeList(List<int> buffer, int offset, int bytes) {
392 if (_id >= 0) { 394 if (!_closed) {
393 if (bytes == 0) { 395 if (bytes == 0) {
394 return 0; 396 return 0;
395 } 397 }
396 if (offset < 0) { 398 if (offset < 0) {
397 throw new IndexOutOfRangeException(offset); 399 throw new IndexOutOfRangeException(offset);
398 } 400 }
399 if (bytes < 0) { 401 if (bytes < 0) {
400 throw new IndexOutOfRangeException(bytes); 402 throw new IndexOutOfRangeException(bytes);
401 } 403 }
402 if ((offset + bytes) > buffer.length) { 404 if ((offset + bytes) > buffer.length) {
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 bool _seenFirstOutEvent = false; 587 bool _seenFirstOutEvent = false;
586 bool _pipe = false; 588 bool _pipe = false;
587 Function _clientConnectHandler; 589 Function _clientConnectHandler;
588 Function _clientWriteHandler; 590 Function _clientWriteHandler;
589 SocketInputStream _inputStream; 591 SocketInputStream _inputStream;
590 SocketOutputStream _outputStream; 592 SocketOutputStream _outputStream;
591 String _remoteHost; 593 String _remoteHost;
592 int _remotePort; 594 int _remotePort;
593 static SendPort _socketService; 595 static SendPort _socketService;
594 } 596 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698