Index: runtime/bin/socket_patch.dart |
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart |
index 94285aaaa02ed59b6eb0905770a60a066762bdf3..be459ba164dd2c653ae3b0e4ee2d8175db0d197e 100644 |
--- a/runtime/bin/socket_patch.dart |
+++ b/runtime/bin/socket_patch.dart |
@@ -280,9 +280,6 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { |
static const Duration _RETRY_DURATION_LOOPBACK = |
const Duration(milliseconds: 25); |
- // Use default Map so we keep order. |
- static Map<int, _NativeSocket> _sockets = new Map<int, _NativeSocket>(); |
- |
// Socket close state |
bool isClosed = false; |
bool isClosing = false; |
@@ -317,13 +314,9 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { |
bool writeAvailable = false; |
static final Stopwatch sw = new Stopwatch()..start(); |
- // Statistics. |
- int totalRead = 0; |
- int totalWritten = 0; |
- int readCount = 0; |
- int writeCount = 0; |
- double lastRead; |
- double lastWrite; |
+ |
+ static bool connectedResourceHandler = false; |
+ _ReadWriteResourceInfo resourceInfo; |
// The owner object is the object that the Socket is being used by, e.g. |
// a HttpServer, a WebSocket connection, a process pipe, etc. |
@@ -441,6 +434,8 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { |
_RETRY_DURATION_LOOPBACK : |
_RETRY_DURATION; |
var timer = new Timer(duration, connectNext); |
+ setupResourceInfo(socket); |
+ |
connecting[socket] = timer; |
// Setup handlers for receiving the first write event which |
// indicate that the socket is fully connected. |
@@ -492,7 +487,6 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { |
.then((address) { |
var socket = new _NativeSocket.listen(); |
socket.localAddress = address; |
- |
var result = socket.nativeCreateBindListen(address._in_addr, |
port, |
backlog, |
@@ -505,11 +499,16 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { |
port: port); |
} |
if (port != 0) socket.localPort = port; |
+ setupResourceInfo(socket); |
socket.connectToEventHandler(); |
return socket; |
}); |
} |
+ static void setupResourceInfo(_NativeSocket socket) { |
+ socket.resourceInfo = new _SocketResourceInfo(socket); |
+ } |
+ |
static Future<_NativeSocket> bindDatagram( |
host, int port, bool reuseAddress) { |
return new Future.value(host) |
@@ -534,6 +533,7 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { |
port: port); |
} |
if (port != 0) socket.localPort = port; |
+ setupResourceInfo(socket); |
return socket; |
}); |
} |
@@ -575,10 +575,18 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { |
} |
if (result != null) { |
available -= result.length; |
- totalRead += result.length; |
+ // TODO(ricow): Remove when we track internal and pipe uses. |
+ assert(resourceInfo != null || isPipe || isInternal); |
+ if (resourceInfo != null) { |
+ resourceInfo.totalRead += result.length; |
+ } |
+ } |
+ // TODO(ricow): Remove when we track internal and pipe uses. |
+ assert(resourceInfo != null || isPipe || isInternal); |
+ if (resourceInfo != null) { |
+ resourceInfo.readCount++; |
+ resourceInfo.lastRead = timestamp; |
} |
- readCount++; |
- lastRead = timestamp; |
return result; |
} |
@@ -595,10 +603,18 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { |
// receive. If available becomes > 0, the _NativeSocket will continue to |
// emit read events. |
available = nativeAvailable(); |
- totalRead += result.data.length; |
+ // TODO(ricow): Remove when we track internal and pipe uses. |
+ assert(resourceInfo != null || isPipe || isInternal); |
+ if (resourceInfo != null) { |
+ resourceInfo.totalRead += result.data.length; |
+ } |
+ } |
+ // TODO(ricow): Remove when we track internal and pipe uses. |
+ assert(resourceInfo != null || isPipe || isInternal); |
+ if (resourceInfo != null) { |
+ resourceInfo.readCount++; |
+ resourceInfo.lastRead = timestamp; |
} |
- readCount++; |
- lastRead = timestamp; |
return result; |
} |
@@ -637,9 +653,13 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { |
} |
// Negate the result, as stated above. |
if (result < 0) result = -result; |
- totalWritten += result; |
- writeCount++; |
- lastWrite = timestamp; |
+ // TODO(ricow): Remove when we track internal and pipe uses. |
+ assert(resourceInfo != null || isPipe || isInternal); |
+ if (resourceInfo != null) { |
+ resourceInfo.totalWritten += result; |
+ resourceInfo.writeCount++; |
+ resourceInfo.lastWrite = timestamp; |
+ } |
return result; |
} |
@@ -656,9 +676,13 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { |
scheduleMicrotask(() => reportError(result, "Send failed")); |
result = 0; |
} |
- totalWritten += result; |
- writeCount++; |
- lastWrite = timestamp; |
+ // TODO(ricow): Remove when we track internal and pipe uses. |
+ assert(resourceInfo != null || isPipe || isInternal); |
+ if (resourceInfo != null) { |
+ resourceInfo.totalWritten += result; |
+ resourceInfo.writeCount++; |
+ resourceInfo.lastWrite = timestamp; |
+ } |
return result; |
} |
@@ -673,8 +697,13 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { |
if (nativeAccept(socket) != true) return null; |
socket.localPort = localPort; |
socket.localAddress = address; |
- totalRead += 1; |
- lastRead = timestamp; |
+ setupResourceInfo(socket); |
+ // TODO(ricow): Remove when we track internal and pipe uses. |
+ assert(resourceInfo != null || isPipe || isInternal); |
+ if (resourceInfo != null) { |
+ resourceInfo.totalRead += 1; |
+ resourceInfo.lastRead = timestamp; |
+ } |
return socket; |
} |
@@ -787,6 +816,11 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { |
if (i == DESTROYED_EVENT) { |
assert(isClosing); |
assert(!isClosed); |
+ // TODO(ricow): Remove/update when we track internal and pipe uses. |
+ assert(resourceInfo != null || isPipe || isInternal); |
+ if (resourceInfo != null) { |
+ _SocketResourceInfo.SocketClosed(resourceInfo); |
+ } |
isClosed = true; |
closeCompleter.complete(); |
disconnectFromEventHandler(); |
@@ -904,7 +938,14 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { |
assert(!isClosed); |
if (eventPort == null) { |
eventPort = new RawReceivePort(multiplex); |
- _sockets[_serviceId] = this; |
+ } |
+ if (!connectedResourceHandler) { |
+ registerExtension('__getOpenSockets', |
+ _SocketResourceInfo.getOpenSockets); |
+ registerExtension('__getSocketByID', |
+ _SocketResourceInfo.getSocketInfoMapByID); |
+ |
+ connectedResourceHandler = true; |
} |
} |
@@ -912,7 +953,6 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { |
assert(eventPort != null); |
eventPort.close(); |
eventPort = null; |
- _sockets.remove(_serviceId); |
// Now that we don't track this Socket anymore, we can clear the owner |
// field. |
owner = null; |
@@ -1017,123 +1057,6 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { |
if (result is OSError) throw result; |
} |
- String get _serviceTypePath => 'io/sockets'; |
- String get _serviceTypeName => 'Socket'; |
- |
- String _JSONKind() { |
- return isListening ? "Listening" : |
- isPipe ? "Pipe" : |
- isInternal ? "Internal" : "Normal"; |
- } |
- |
- Map _toJSONPipe(bool ref) { |
- var name = 'Anonymous Pipe'; |
- var r = { |
- 'id': _servicePath, |
- 'type': _serviceType(ref), |
- 'name': name, |
- 'user_name': name, |
- 'kind': _JSONKind(), |
- }; |
- if (ref) { |
- return r; |
- } |
- r['readClosed'] = isClosedRead; |
- r['writeClosed'] = isClosedWrite; |
- r['closing'] = isClosing; |
- r['fd'] = nativeGetSocketId(); |
- if (owner != null) { |
- r['owner'] = owner._toJSON(true); |
- } |
- return r; |
- } |
- |
- Map _toJSONInternal(bool ref) { |
- var name = 'Internal'; |
- var r = { |
- 'id': _servicePath, |
- 'type': _serviceType(ref), |
- 'name': name, |
- 'user_name': name, |
- 'kind': _JSONKind(), |
- }; |
- if (ref) { |
- return r; |
- } |
- r['closing'] = isClosing; |
- r['fd'] = nativeGetSocketId(); |
- if (owner != null) { |
- r['owner'] = owner._toJSON(true); |
- } |
- return r; |
- } |
- |
- Map _toJSONNetwork(bool ref) { |
- var name = '${address.host}:$port'; |
- if (isTcp && !isListening) name += " <-> ${remoteAddress.host}:$remotePort"; |
- var r = { |
- 'id': _servicePath, |
- 'type': _serviceType(ref), |
- 'name': name, |
- 'user_name': name, |
- 'kind': _JSONKind(), |
- }; |
- if (ref) { |
- return r; |
- } |
- var protocol = isTcp ? "TCP" : isUdp ? "UDP" : null; |
- var localAddress; |
- var localPort; |
- var rAddress; |
- var rPort; |
- try { |
- localAddress = address.address; |
- } catch (e) { } |
- try { |
- localPort = port; |
- } catch (e) { } |
- try { |
- rAddress = this.remoteAddress.address; |
- } catch (e) { } |
- try { |
- rPort = remotePort; |
- } catch (e) { } |
- r['localAddress'] = localAddress; |
- r['localPort'] = localPort; |
- r['remoteAddress'] = rAddress; |
- r['remotePort'] = rPort; |
- r['protocol'] = protocol; |
- r['readClosed'] = isClosedRead; |
- r['writeClosed'] = isClosedWrite; |
- r['closing'] = isClosing; |
- r['listening'] = isListening; |
- r['fd'] = nativeGetSocketId(); |
- if (owner != null) { |
- r['owner'] = owner._toJSON(true); |
- } |
- return r; |
- } |
- |
- Map _toJSON(bool ref) { |
- var map; |
- if (isPipe) { |
- map = _toJSONPipe(ref); |
- } else if (isInternal) { |
- map = _toJSONInternal(ref); |
- } else { |
- map = _toJSONNetwork(ref); |
- } |
- if (!ref) { |
- map['available'] = available; |
- map['totalRead'] = totalRead; |
- map['totalWritten'] = totalWritten; |
- map['readCount'] = totalWritten; |
- map['writeCount'] = writeCount; |
- map['lastRead'] = lastRead; |
- map['lastWrite'] = lastWrite; |
- } |
- return map; |
- } |
void nativeSetSocketId(int id) native "Socket_SetSocketId"; |
nativeAvailable() native "Socket_Available"; |
@@ -1286,8 +1209,6 @@ class _RawServerSocket extends Stream<RawSocket> |
return new _RawServerSocketReference(_referencePort.sendPort); |
} |
- Map _toJSON(bool ref) => _socket._toJSON(ref); |
- |
void set _owner(owner) { _socket.owner = owner; } |
} |
@@ -1465,7 +1386,6 @@ class _RawSocket extends Stream<RawSocketEvent> |
} |
} |
- Map _toJSON(bool ref) => _socket._toJSON(ref); |
void set _owner(owner) { _socket.owner = owner; } |
} |
@@ -1528,8 +1448,6 @@ class _ServerSocket extends Stream<Socket> |
return new _ServerSocketReference(_socket.reference); |
} |
- Map _toJSON(bool ref) => _socket._toJSON(ref); |
- |
void set _owner(owner) { _socket._owner = owner; } |
} |
@@ -1843,7 +1761,6 @@ class _Socket extends Stream<List<int>> implements Socket { |
} |
} |
- Map _toJSON(bool ref) => _raw._toJSON(ref); |
void set _owner(owner) { _raw._owner = owner; } |
} |
@@ -1999,4 +1916,3 @@ Datagram _makeDatagram(List<int> data, |
port); |
} |
-String _socketsStats() => _SocketsObservatory.toJSON(); |