| // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| library vmservice_io; |
| |
| import 'dart:async'; |
| import 'dart:collection'; |
| import 'dart:convert'; |
| import 'dart:io'; |
| import 'dart:isolate'; |
| import 'dart:_vmservice'; |
| |
| part 'loader.dart'; |
| part 'server.dart'; |
| |
| // The TCP ip/port that the HTTP server listens on. |
| int _port; |
| String _ip; |
| // Should the HTTP server auto start? |
| bool _autoStart; |
| |
| bool _isWindows = false; |
| |
| var _signalWatch; |
| var _signalSubscription; |
| |
| // HTTP server. |
| Server server; |
| Future<Server> serverFuture; |
| HashMap<String, Asset> _assets; |
| HashMap<String, Asset> get assets { |
| if (_assets == null) { |
| try { |
| _assets = Asset.request(); |
| } catch (e) { |
| print('Could not load Observatory assets: $e'); |
| } |
| } |
| return _assets; |
| } |
| |
| _onShutdown() { |
| if (server != null) { |
| server.close(true).catchError((e, st) { |
| print("Error in vm-service shutdown: $e\n$st\n"); |
| }); |
| } |
| if (_signalSubscription != null) { |
| _signalSubscription.cancel(); |
| _signalSubscription = null; |
| } |
| } |
| |
| _bootServer() { |
| // Lazily create service. |
| var service = new VMService(); |
| service.onShutdown = _onShutdown; |
| // Lazily create server. |
| server = new Server(service, _ip, _port); |
| } |
| |
| _clearFuture(_) { |
| serverFuture = null; |
| } |
| |
| _onSignal(ProcessSignal signal) { |
| if (serverFuture != null) { |
| // Still waiting. |
| return; |
| } |
| if (server == null) { |
| _bootServer(); |
| } |
| // Toggle HTTP server. |
| if (server.running) { |
| serverFuture = server.shutdown(true).then(_clearFuture); |
| } else { |
| serverFuture = server.startup().then(_clearFuture); |
| } |
| } |
| |
| _registerSignalHandler() { |
| if (_isWindows) { |
| // Cannot register for signals on Windows. |
| return; |
| } |
| _signalSubscription = _signalWatch(ProcessSignal.SIGQUIT).listen(_onSignal); |
| } |
| |
| const _shortDelay = const Duration(milliseconds: 10); |
| |
| main() { |
| if (_autoStart) { |
| _bootServer(); |
| server.startup(); |
| // It's just here to push an event on the event loop so that we invoke the |
| // scheduled microtasks. |
| Timer.run(() {}); |
| } |
| // TODO(johnmccutchan, turnidge) Creating a VMService object here causes |
| // strange behavior from the legacy debug protocol and coverage tool. |
| // Enable this code, and remove the call to Isolate::KillIsolate() from |
| // service_isolate.cc when the strange behavior is solved. |
| // See: https://github.com/dart-lang/sdk/issues/23977 |
| // else { |
| // var service = new VMService(); |
| // service.onShutdown = _onShutdown; |
| // } |
| scriptLoadPort.handler = _processLoadRequest; |
| // Register signal handler after a small delay to avoid stalling main |
| // isolate startup. |
| new Timer(_shortDelay, _registerSignalHandler); |
| return scriptLoadPort; |
| } |