OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 part of dart.io; | 5 part of dart.io; |
6 | 6 |
7 abstract class _IOResourceInfo { | 7 abstract class _IOResourceInfo { |
8 final String type; | 8 final String type; |
9 final int id; | 9 final int id; |
10 String get name; | 10 String get name; |
11 static int _count = 0; | 11 static int _count = 0; |
12 | 12 |
13 static final Stopwatch _sw = new Stopwatch()..start(); | 13 static final Stopwatch _sw = new Stopwatch()..start(); |
14 static final _startTime = new DateTime.now().millisecondsSinceEpoch; | 14 static final _startTime = new DateTime.now().millisecondsSinceEpoch; |
15 | 15 |
16 static double get timestamp => _startTime + _sw.elapsedMicroseconds/1000; | 16 static double get timestamp => _startTime + _sw.elapsedMicroseconds / 1000; |
17 | 17 |
18 _IOResourceInfo(this.type) : id = _IOResourceInfo.getNextID(); | 18 _IOResourceInfo(this.type) : id = _IOResourceInfo.getNextID(); |
19 | 19 |
20 /// Get the full set of values for a specific implementation. This is normally | 20 /// Get the full set of values for a specific implementation. This is normally |
21 /// looked up based on an id from a referenceValueMap. | 21 /// looked up based on an id from a referenceValueMap. |
22 Map<String, dynamic> get fullValueMap; | 22 Map<String, dynamic> get fullValueMap; |
23 | 23 |
24 /// The reference map, used to return a list of values, e.g., getting | 24 /// The reference map, used to return a list of values, e.g., getting |
25 /// all open sockets. The structure of this is shared among all subclasses. | 25 /// all open sockets. The structure of this is shared among all subclasses. |
26 Map<String, dynamic> get referenceValueMap => | 26 Map<String, dynamic> get referenceValueMap => { |
27 { | |
28 // The type for a reference object is prefixed with @ in observatory. | 27 // The type for a reference object is prefixed with @ in observatory. |
29 'type': '@$type', | 28 'type': '@$type', |
30 'id': id, | 29 'id': id, |
31 'name': name, | 30 'name': name, |
32 }; | 31 }; |
33 | 32 |
34 static int getNextID() => _count++; | 33 static int getNextID() => _count++; |
35 } | 34 } |
36 | 35 |
37 abstract class _ReadWriteResourceInfo extends _IOResourceInfo { | 36 abstract class _ReadWriteResourceInfo extends _IOResourceInfo { |
38 int totalRead; | 37 int totalRead; |
39 int totalWritten; | 38 int totalWritten; |
40 int readCount; | 39 int readCount; |
41 int writeCount; | 40 int writeCount; |
42 double lastRead; | 41 double lastRead; |
43 double lastWrite; | 42 double lastWrite; |
44 | 43 |
45 // Not all call sites use this. In some cases, e.g., a socket, a read does | 44 // Not all call sites use this. In some cases, e.g., a socket, a read does |
46 // not always mean that we actually read some bytes (we may do a read to see | 45 // not always mean that we actually read some bytes (we may do a read to see |
47 // if there are some bytes available). | 46 // if there are some bytes available). |
48 void addRead(int bytes) { | 47 void addRead(int bytes) { |
49 totalRead += bytes; | 48 totalRead += bytes; |
50 readCount++; | 49 readCount++; |
51 lastRead = _IOResourceInfo.timestamp; | 50 lastRead = _IOResourceInfo.timestamp; |
52 } | 51 } |
53 | 52 |
54 // In cases where we read but did not necessarily get any bytes, use this to | 53 // In cases where we read but did not necessarily get any bytes, use this to |
55 // update the readCount and timestamp. Manually update totalRead if any bytes | 54 // update the readCount and timestamp. Manually update totalRead if any bytes |
56 // where actually read. | 55 // where actually read. |
57 void didRead() { addRead(0); } | 56 void didRead() { |
| 57 addRead(0); |
| 58 } |
58 | 59 |
59 void addWrite(int bytes) { | 60 void addWrite(int bytes) { |
60 totalWritten += bytes; | 61 totalWritten += bytes; |
61 writeCount++; | 62 writeCount++; |
62 lastWrite = _IOResourceInfo.timestamp; | 63 lastWrite = _IOResourceInfo.timestamp; |
63 } | 64 } |
64 | 65 |
65 _ReadWriteResourceInfo(String type) : | 66 _ReadWriteResourceInfo(String type) |
66 totalRead = 0, | 67 : totalRead = 0, |
67 totalWritten = 0, | 68 totalWritten = 0, |
68 readCount = 0, | 69 readCount = 0, |
69 writeCount = 0, | 70 writeCount = 0, |
70 lastRead = 0.0, | 71 lastRead = 0.0, |
71 lastWrite = 0.0, | 72 lastWrite = 0.0, |
72 super(type); | 73 super(type); |
73 | 74 |
74 Map<String, dynamic> get fullValueMap => | 75 Map<String, dynamic> get fullValueMap => { |
75 { | 76 'type': type, |
76 'type': type, | 77 'id': id, |
77 'id': id, | 78 'name': name, |
78 'name': name, | 79 'totalRead': totalRead, |
79 'totalRead': totalRead, | 80 'totalWritten': totalWritten, |
80 'totalWritten': totalWritten, | 81 'readCount': readCount, |
81 'readCount': readCount, | 82 'writeCount': writeCount, |
82 'writeCount': writeCount, | 83 'lastRead': lastRead, |
83 'lastRead': lastRead, | 84 'lastWrite': lastWrite |
84 'lastWrite': lastWrite | 85 }; |
85 }; | |
86 } | 86 } |
87 | 87 |
88 class _FileResourceInfo extends _ReadWriteResourceInfo { | 88 class _FileResourceInfo extends _ReadWriteResourceInfo { |
89 static const String TYPE = '_file'; | 89 static const String TYPE = '_file'; |
90 | 90 |
91 final file; | 91 final file; |
92 | 92 |
93 static Map<int, _FileResourceInfo> openFiles = | 93 static Map<int, _FileResourceInfo> openFiles = |
94 new Map<int, _FileResourceInfo>(); | 94 new Map<int, _FileResourceInfo>(); |
95 | 95 |
(...skipping 23 matching lines...) Expand all Loading... |
119 } | 119 } |
120 | 120 |
121 Map<String, dynamic> getFileInfoMap() { | 121 Map<String, dynamic> getFileInfoMap() { |
122 return fullValueMap; | 122 return fullValueMap; |
123 } | 123 } |
124 | 124 |
125 static Future<ServiceExtensionResponse> getFileInfoMapByID(function, params) { | 125 static Future<ServiceExtensionResponse> getFileInfoMapByID(function, params) { |
126 assert(params.containsKey('id')); | 126 assert(params.containsKey('id')); |
127 var id = int.parse(params['id']); | 127 var id = int.parse(params['id']); |
128 var result = | 128 var result = |
129 openFiles.containsKey(id) ? openFiles[id].getFileInfoMap() : {}; | 129 openFiles.containsKey(id) ? openFiles[id].getFileInfoMap() : {}; |
130 var json = JSON.encode(result); | 130 var json = JSON.encode(result); |
131 return new Future.value(new ServiceExtensionResponse.result(json)); | 131 return new Future.value(new ServiceExtensionResponse.result(json)); |
132 } | 132 } |
133 | 133 |
134 String get name { | 134 String get name { |
135 return '${file.path}'; | 135 return '${file.path}'; |
136 } | 136 } |
137 } | 137 } |
138 | 138 |
139 class _ProcessResourceInfo extends _IOResourceInfo{ | 139 class _ProcessResourceInfo extends _IOResourceInfo { |
140 static const String TYPE = '_process'; | 140 static const String TYPE = '_process'; |
141 final process; | 141 final process; |
142 final double startedAt; | 142 final double startedAt; |
143 | 143 |
144 static Map<int, _ProcessResourceInfo> startedProcesses = | 144 static Map<int, _ProcessResourceInfo> startedProcesses = |
145 new Map<int, _ProcessResourceInfo>(); | 145 new Map<int, _ProcessResourceInfo>(); |
146 | 146 |
147 _ProcessResourceInfo(this.process) : | 147 _ProcessResourceInfo(this.process) |
148 startedAt = _IOResourceInfo.timestamp, | 148 : startedAt = _IOResourceInfo.timestamp, |
149 super(TYPE) { | 149 super(TYPE) { |
150 ProcessStarted(this); | 150 ProcessStarted(this); |
151 } | 151 } |
152 | 152 |
153 String get name => process._path; | 153 String get name => process._path; |
154 | 154 |
155 void stopped() { ProcessStopped(this); } | 155 void stopped() { |
| 156 ProcessStopped(this); |
| 157 } |
156 | 158 |
157 Map<String, dynamic> get fullValueMap => | 159 Map<String, dynamic> get fullValueMap => { |
158 { | 160 'type': type, |
159 'type': type, | 161 'id': id, |
160 'id': id, | 162 'name': name, |
161 'name': name, | 163 'pid': process.pid, |
162 'pid': process.pid, | 164 'startedAt': startedAt, |
163 'startedAt': startedAt, | 165 'arguments': process._arguments, |
164 'arguments': process._arguments, | 166 'workingDirectory': |
165 'workingDirectory': | 167 process._workingDirectory == null ? '.' : process._workingDirectory, |
166 process._workingDirectory == null ? '.' : process._workingDirectory, | 168 }; |
167 }; | |
168 | 169 |
169 static ProcessStarted(_ProcessResourceInfo info) { | 170 static ProcessStarted(_ProcessResourceInfo info) { |
170 assert(!startedProcesses.containsKey(info.id)); | 171 assert(!startedProcesses.containsKey(info.id)); |
171 startedProcesses[info.id] = info; | 172 startedProcesses[info.id] = info; |
172 } | 173 } |
173 | 174 |
174 static ProcessStopped(_ProcessResourceInfo info) { | 175 static ProcessStopped(_ProcessResourceInfo info) { |
175 assert(startedProcesses.containsKey(info.id)); | 176 assert(startedProcesses.containsKey(info.id)); |
176 startedProcesses.remove(info.id); | 177 startedProcesses.remove(info.id); |
177 } | 178 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 | 215 |
215 String get name { | 216 String get name { |
216 if (socket.isListening) { | 217 if (socket.isListening) { |
217 return 'listening:${socket.address.host}:${socket.port}'; | 218 return 'listening:${socket.address.host}:${socket.port}'; |
218 } | 219 } |
219 var remote = ''; | 220 var remote = ''; |
220 try { | 221 try { |
221 var remoteHost = socket.remoteAddress.host; | 222 var remoteHost = socket.remoteAddress.host; |
222 var remotePort = socket.remotePort; | 223 var remotePort = socket.remotePort; |
223 remote = ' -> $remoteHost:$remotePort'; | 224 remote = ' -> $remoteHost:$remotePort'; |
224 } catch (e) { } // ignored if we can't get the information | 225 } catch (e) {} // ignored if we can't get the information |
225 return '${socket.address.host}:${socket.port}$remote'; | 226 return '${socket.address.host}:${socket.port}$remote'; |
226 } | 227 } |
227 | 228 |
228 static Iterable<Map<String, String>> getOpenSocketsList() { | 229 static Iterable<Map<String, String>> getOpenSocketsList() { |
229 return new List.from(openSockets.values.map((e) => e.referenceValueMap)); | 230 return new List.from(openSockets.values.map((e) => e.referenceValueMap)); |
230 } | 231 } |
231 | 232 |
232 Map<String, dynamic> getSocketInfoMap() { | 233 Map<String, dynamic> getSocketInfoMap() { |
233 var result = fullValueMap; | 234 var result = fullValueMap; |
234 result['socketType'] = socket.isTcp ? TCP_STRING : UDP_STRING; | 235 result['socketType'] = socket.isTcp ? TCP_STRING : UDP_STRING; |
(...skipping 15 matching lines...) Expand all Loading... |
250 } | 251 } |
251 result['addressType'] = socket.address.type.name; | 252 result['addressType'] = socket.address.type.name; |
252 return result; | 253 return result; |
253 } | 254 } |
254 | 255 |
255 static Future<ServiceExtensionResponse> getSocketInfoMapByID( | 256 static Future<ServiceExtensionResponse> getSocketInfoMapByID( |
256 String function, Map<String, String> params) { | 257 String function, Map<String, String> params) { |
257 assert(params.containsKey('id')); | 258 assert(params.containsKey('id')); |
258 var id = int.parse(params['id']); | 259 var id = int.parse(params['id']); |
259 var result = | 260 var result = |
260 openSockets.containsKey(id) ? openSockets[id].getSocketInfoMap() : {}; | 261 openSockets.containsKey(id) ? openSockets[id].getSocketInfoMap() : {}; |
261 var json = JSON.encode(result); | 262 var json = JSON.encode(result); |
262 return new Future.value(new ServiceExtensionResponse.result(json)); | 263 return new Future.value(new ServiceExtensionResponse.result(json)); |
263 } | 264 } |
264 | 265 |
265 static Future<ServiceExtensionResponse> getOpenSockets(function, params) { | 266 static Future<ServiceExtensionResponse> getOpenSockets(function, params) { |
266 assert(function == 'ext.dart.io.getOpenSockets'); | 267 assert(function == 'ext.dart.io.getOpenSockets'); |
267 var data = {'type': '_opensockets', 'data': getOpenSocketsList()}; | 268 var data = {'type': '_opensockets', 'data': getOpenSocketsList()}; |
268 var json = JSON.encode(data); | 269 var json = JSON.encode(data); |
269 return new Future.value(new ServiceExtensionResponse.result(json)); | 270 return new Future.value(new ServiceExtensionResponse.result(json)); |
270 } | 271 } |
271 | 272 |
272 static SocketOpened(_SocketResourceInfo info) { | 273 static SocketOpened(_SocketResourceInfo info) { |
273 assert(!openSockets.containsKey(info.id)); | 274 assert(!openSockets.containsKey(info.id)); |
274 openSockets[info.id] = info; | 275 openSockets[info.id] = info; |
275 } | 276 } |
276 | 277 |
277 static SocketClosed(_SocketResourceInfo info) { | 278 static SocketClosed(_SocketResourceInfo info) { |
278 assert(openSockets.containsKey(info.id)); | 279 assert(openSockets.containsKey(info.id)); |
279 openSockets.remove(info.id); | 280 openSockets.remove(info.id); |
280 } | 281 } |
281 } | 282 } |
OLD | NEW |