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

Side by Side Diff: sdk/lib/vmservice/vmservice.dart

Issue 2120473004: Reimplement devfs in dart. Implementation now writes to disk. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: code review Created 4 years, 5 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
« no previous file with comments | « sdk/lib/vmservice/devfs.dart ('k') | sdk/lib/vmservice/vmservice_sources.gypi » ('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) 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 library dart._vmservice; 5 library dart._vmservice;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 import 'dart:convert'; 9 import 'dart:convert';
10 import 'dart:isolate'; 10 import 'dart:isolate';
11 import 'dart:typed_data'; 11 import 'dart:typed_data';
12 12
13 part 'asset.dart'; 13 part 'asset.dart';
14 part 'client.dart'; 14 part 'client.dart';
15 part 'devfs.dart';
15 part 'constants.dart'; 16 part 'constants.dart';
16 part 'running_isolate.dart'; 17 part 'running_isolate.dart';
17 part 'running_isolates.dart'; 18 part 'running_isolates.dart';
18 part 'message.dart'; 19 part 'message.dart';
19 part 'message_router.dart'; 20 part 'message_router.dart';
20 21
21 final RawReceivePort isolateLifecyclePort = new RawReceivePort(); 22 final RawReceivePort isolateLifecyclePort = new RawReceivePort();
22 final RawReceivePort scriptLoadPort = new RawReceivePort(); 23 final RawReceivePort scriptLoadPort = new RawReceivePort();
23 24
24 abstract class IsolateEmbedderData { 25 abstract class IsolateEmbedderData {
25 void cleanup(); 26 void cleanup();
26 } 27 }
27 28
28 // This is for use by the embedder. It is a map from the isolateId to 29 // This is for use by the embedder. It is a map from the isolateId to
29 // anything implementing IsolateEmbedderData. When an isolate goes away, 30 // anything implementing IsolateEmbedderData. When an isolate goes away,
30 // the cleanup method will be invoked after being removed from the map. 31 // the cleanup method will be invoked after being removed from the map.
31 final Map<int, IsolateEmbedderData> isolateEmbedderData = 32 final Map<int, IsolateEmbedderData> isolateEmbedderData =
32 new Map<int, IsolateEmbedderData>(); 33 new Map<int, IsolateEmbedderData>();
33 34
34 // These must be kept in sync with the declarations in vm/json_stream.h. 35 // These must be kept in sync with the declarations in vm/json_stream.h.
35 const kInvalidParams = -32602; 36 const kInvalidParams = -32602;
36 const kInternalError = -32603; 37 const kInternalError = -32603;
37 const kStreamAlreadySubscribed = 103; 38 const kFeatureDisabled = 100;
38 const kStreamNotSubscribed = 104; 39 const kStreamAlreadySubscribed = 103;
40 const kStreamNotSubscribed = 104;
41 const kFileSystemAlreadyExists = 1001;
42 const kFileSystemDoesNotExist = 1002;
43 const kFileDoesNotExist = 1003;
39 44
40 var _errorMessages = { 45 var _errorMessages = {
41 kInvalidParams: 'Invalid params', 46 kInvalidParams: 'Invalid params',
42 kInternalError: 'Internal error', 47 kInternalError: 'Internal error',
48 kFeatureDisabled: 'Feature is disabled',
43 kStreamAlreadySubscribed: 'Stream already subscribed', 49 kStreamAlreadySubscribed: 'Stream already subscribed',
44 kStreamNotSubscribed: 'Stream not subscribed', 50 kStreamNotSubscribed: 'Stream not subscribed',
51 kFileSystemAlreadyExists: 'File system already exists',
52 kFileSystemDoesNotExist: 'File system does not exist',
53 kFileDoesNotExist: 'File does not exist',
45 }; 54 };
46 55
47 String encodeRpcError(Message message, int code, {String details}) { 56 String encodeRpcError(Message message, int code, {String details}) {
48 var response = { 57 var response = {
49 'jsonrpc': '2.0', 58 'jsonrpc': '2.0',
50 'id' : message.serial, 59 'id' : message.serial,
51 'error' : { 60 'error' : {
52 'code': code, 61 'code': code,
53 'message': _errorMessages[code], 62 'message': _errorMessages[code],
54 }, 63 },
55 }; 64 };
56 if (details != null) { 65 if (details != null) {
57 response['error']['data'] = { 66 response['error']['data'] = {
58 'details': details, 67 'details': details,
59 }; 68 };
60 } 69 }
61 return JSON.encode(response); 70 return JSON.encode(response);
62 } 71 }
63 72
73 String encodeMissingParamError(Message message, String param) {
74 return encodeRpcError(
75 message, kInvalidParams,
76 details: "${message.method} expects the '${param}' parameter");
77 }
78
79 String encodeInvalidParamError(Message message, String param) {
80 var value = message.params[param];
81 return encodeRpcError(
82 message, kInvalidParams,
83 details: "${message.method}: invalid '${param}' parameter: ${value}");
84 }
85
64 String encodeResult(Message message, Map result) { 86 String encodeResult(Message message, Map result) {
65 var response = { 87 var response = {
66 'jsonrpc': '2.0', 88 'jsonrpc': '2.0',
67 'id' : message.serial, 89 'id' : message.serial,
68 'result' : result, 90 'result' : result,
69 }; 91 };
70 return JSON.encode(response); 92 return JSON.encode(response);
71 } 93 }
72 94
95 String encodeSuccess(Message message) {
96 return encodeResult(message, { 'type': 'Success' });
97 }
98
73 const shortDelay = const Duration(milliseconds: 10); 99 const shortDelay = const Duration(milliseconds: 10);
74 100
75 /// Called when the server should be started. 101 /// Called when the server should be started.
76 typedef Future ServerStartCallback(); 102 typedef Future ServerStartCallback();
77 103
78 /// Called when the server should be stopped. 104 /// Called when the server should be stopped.
79 typedef Future ServerStopCallback(); 105 typedef Future ServerStopCallback();
80 106
81 /// Called when the service is exiting. 107 /// Called when the service is exiting.
82 typedef Future CleanupCallback(); 108 typedef Future CleanupCallback();
83 109
110 /// Called to create a temporary directory
111 typedef Future<Uri> CreateTempDirCallback(String base);
112
113 /// Called to delete a directory
114 typedef Future DeleteDirCallback(Uri path);
115
116 /// Called to write a file.
117 typedef Future WriteFileCallback(Uri path, List<int> bytes);
118
119 /// Called to read a file.
120 typedef Future<List<int>> ReadFileCallback(Uri path);
121
122 /// Called to list all files under some path.
123 typedef Future<List<Map<String,String>>> ListFilesCallback(Uri path);
124
84 /// Hooks that are setup by the embedder. 125 /// Hooks that are setup by the embedder.
85 class VMServiceEmbedderHooks { 126 class VMServiceEmbedderHooks {
86 static ServerStartCallback serverStart; 127 static ServerStartCallback serverStart;
87 static ServerStopCallback serverStop; 128 static ServerStopCallback serverStop;
88 static CleanupCallback cleanup; 129 static CleanupCallback cleanup;
130 static CreateTempDirCallback createTempDir;
131 static DeleteDirCallback deleteDir;
132 static WriteFileCallback writeFile;
133 static ReadFileCallback readFile;
134 static ListFilesCallback listFiles;
89 } 135 }
90 136
91 class VMService extends MessageRouter { 137 class VMService extends MessageRouter {
92 static VMService _instance; 138 static VMService _instance;
93 139
94 /// Collection of currently connected clients. 140 /// Collection of currently connected clients.
95 final Set<Client> clients = new Set<Client>(); 141 final Set<Client> clients = new Set<Client>();
96 142
97 /// Collection of currently running isolates. 143 /// Collection of currently running isolates.
98 RunningIsolates runningIsolates = new RunningIsolates(); 144 RunningIsolates runningIsolates = new RunningIsolates();
99 145
100 /// A port used to receive events from the VM. 146 /// A port used to receive events from the VM.
101 final RawReceivePort eventPort; 147 final RawReceivePort eventPort;
102 148
149 final _devfs = new DevFS();
150
103 void _addClient(Client client) { 151 void _addClient(Client client) {
104 assert(client.streams.isEmpty); 152 assert(client.streams.isEmpty);
105 clients.add(client); 153 clients.add(client);
106 } 154 }
107 155
108 void _removeClient(Client client) { 156 void _removeClient(Client client) {
109 clients.remove(client); 157 clients.remove(client);
110 for (var streamId in client.streams) { 158 for (var streamId in client.streams) {
111 if (!_isAnyClientSubscribed(streamId)) { 159 if (!_isAnyClientSubscribed(streamId)) {
112 _vmCancelStream(streamId); 160 _vmCancelStream(streamId);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 // Close receive ports. 199 // Close receive ports.
152 isolateLifecyclePort.close(); 200 isolateLifecyclePort.close();
153 scriptLoadPort.close(); 201 scriptLoadPort.close();
154 202
155 // Create a copy of the set as a list because client.disconnect() will 203 // Create a copy of the set as a list because client.disconnect() will
156 // alter the connected clients set. 204 // alter the connected clients set.
157 var clientsList = clients.toList(); 205 var clientsList = clients.toList();
158 for (var client in clientsList) { 206 for (var client in clientsList) {
159 client.disconnect(); 207 client.disconnect();
160 } 208 }
209 _devfs.cleanup();
161 if (VMServiceEmbedderHooks.cleanup != null) { 210 if (VMServiceEmbedderHooks.cleanup != null) {
162 await VMServiceEmbedderHooks.cleanup(); 211 await VMServiceEmbedderHooks.cleanup();
163 } 212 }
164 // Notify the VM that we have exited. 213 // Notify the VM that we have exited.
165 _onExit(); 214 _onExit();
166 } 215 }
167 216
168 void messageHandler(message) { 217 void messageHandler(message) {
169 if (message is List) { 218 if (message is List) {
170 if (message.length == 2) { 219 if (message.length == 2) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 } 270 }
222 if (!_isAnyClientSubscribed(streamId)) { 271 if (!_isAnyClientSubscribed(streamId)) {
223 if (!_vmListenStream(streamId)) { 272 if (!_vmListenStream(streamId)) {
224 return encodeRpcError( 273 return encodeRpcError(
225 message, kInvalidParams, 274 message, kInvalidParams,
226 details:"streamListen: invalid 'streamId' parameter: ${streamId}"); 275 details:"streamListen: invalid 'streamId' parameter: ${streamId}");
227 } 276 }
228 } 277 }
229 client.streams.add(streamId); 278 client.streams.add(streamId);
230 279
231 var result = { 'type' : 'Success' }; 280 return encodeSuccess(message);
232 return encodeResult(message, result);
233 } 281 }
234 282
235 Future<String> _streamCancel(Message message) async { 283 Future<String> _streamCancel(Message message) async {
236 var client = message.client; 284 var client = message.client;
237 var streamId = message.params['streamId']; 285 var streamId = message.params['streamId'];
238 286
239 if (!client.streams.contains(streamId)) { 287 if (!client.streams.contains(streamId)) {
240 return encodeRpcError(message, kStreamNotSubscribed); 288 return encodeRpcError(message, kStreamNotSubscribed);
241 } 289 }
242 client.streams.remove(streamId); 290 client.streams.remove(streamId);
243 if (!_isAnyClientSubscribed(streamId)) { 291 if (!_isAnyClientSubscribed(streamId)) {
244 _vmCancelStream(streamId); 292 _vmCancelStream(streamId);
245 } 293 }
246 294
247 var result = { 'type' : 'Success' }; 295 return encodeSuccess(message);
248 return encodeResult(message, result);
249 } 296 }
250 297
251 // TODO(johnmccutchan): Turn this into a command line tool that uses the 298 // TODO(johnmccutchan): Turn this into a command line tool that uses the
252 // service library. 299 // service library.
253 Future<String> _getCrashDump(Message message) async { 300 Future<String> _getCrashDump(Message message) async {
254 var client = message.client; 301 var client = message.client;
255 final perIsolateRequests = [ 302 final perIsolateRequests = [
256 // ?isolateId=<isolate id> will be appended to each of these requests. 303 // ?isolateId=<isolate id> will be appended to each of these requests.
257 // Isolate information. 304 // Isolate information.
258 Uri.parse('getIsolate'), 305 Uri.parse('getIsolate'),
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 // TODO(turnidge): Update to json rpc. BEFORE SUBMIT. 360 // TODO(turnidge): Update to json rpc. BEFORE SUBMIT.
314 if (message.method == '_getCrashDump') { 361 if (message.method == '_getCrashDump') {
315 return _getCrashDump(message); 362 return _getCrashDump(message);
316 } 363 }
317 if (message.method == 'streamListen') { 364 if (message.method == 'streamListen') {
318 return _streamListen(message); 365 return _streamListen(message);
319 } 366 }
320 if (message.method == 'streamCancel') { 367 if (message.method == 'streamCancel') {
321 return _streamCancel(message); 368 return _streamCancel(message);
322 } 369 }
370 if (_devfs.shouldHandleMessage(message)) {
371 return _devfs.handleMessage(message);
372 }
323 if (message.params['isolateId'] != null) { 373 if (message.params['isolateId'] != null) {
324 return runningIsolates.route(message); 374 return runningIsolates.route(message);
325 } 375 }
326 return message.sendToVM(); 376 return message.sendToVM();
327 } 377 }
328 } 378 }
329 379
330 RawReceivePort boot() { 380 RawReceivePort boot() {
331 // Return the port we expect isolate startup and shutdown messages on. 381 // Return the port we expect isolate startup and shutdown messages on.
332 return isolateLifecyclePort; 382 return isolateLifecyclePort;
(...skipping 14 matching lines...) Expand all
347 external void onServerAddressChange(String address); 397 external void onServerAddressChange(String address);
348 398
349 /// Subscribe to a service stream. 399 /// Subscribe to a service stream.
350 external bool _vmListenStream(String streamId); 400 external bool _vmListenStream(String streamId);
351 401
352 /// Cancel a subscription to a service stream. 402 /// Cancel a subscription to a service stream.
353 external void _vmCancelStream(String streamId); 403 external void _vmCancelStream(String streamId);
354 404
355 /// Get the bytes to the tar archive. 405 /// Get the bytes to the tar archive.
356 external Uint8List _requestAssets(); 406 external Uint8List _requestAssets();
OLDNEW
« no previous file with comments | « sdk/lib/vmservice/devfs.dart ('k') | sdk/lib/vmservice/vmservice_sources.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698