OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 vmservice; | 5 library vmservice; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:convert'; | 8 import 'dart:convert'; |
9 import 'dart:isolate'; | 9 import 'dart:isolate'; |
10 import 'dart:typed_data'; | 10 import 'dart:typed_data'; |
11 | 11 |
12 part 'client.dart'; | 12 part 'client.dart'; |
13 part 'constants.dart'; | 13 part 'constants.dart'; |
14 part 'running_isolate.dart'; | 14 part 'running_isolate.dart'; |
15 part 'running_isolates.dart'; | 15 part 'running_isolates.dart'; |
16 part 'message.dart'; | 16 part 'message.dart'; |
17 part 'message_router.dart'; | 17 part 'message_router.dart'; |
18 | 18 |
19 class VMService extends MessageRouter { | 19 class VMService extends MessageRouter { |
20 static VMService _instance; | 20 static VMService _instance; |
21 /// Collection of currently connected clients. | 21 /// Collection of currently connected clients. |
22 final Set<Client> clients = new Set<Client>(); | 22 final Set<Client> clients = new Set<Client>(); |
| 23 |
| 24 // A map encoding which clients are interested in which kinds of events. |
| 25 final Map<int, Set<Client>> eventMap = new Map<int, Set<Client>>(); |
| 26 |
23 /// Collection of currently running isolates. | 27 /// Collection of currently running isolates. |
24 RunningIsolates runningIsolates = new RunningIsolates(); | 28 RunningIsolates runningIsolates = new RunningIsolates(); |
25 /// Isolate startup and shutdown messages are sent on this port. | |
26 final RawReceivePort receivePort; | |
27 | 29 |
28 void controlMessageHandler(int code, int port_id, SendPort sp, String name) { | 30 /// A port used to receive events from the VM. |
| 31 final RawReceivePort eventPort; |
| 32 |
| 33 void _addClient(Client client) { |
| 34 clients.add(client); |
| 35 } |
| 36 |
| 37 void _removeClient(Client client) { |
| 38 clients.remove(client); |
| 39 } |
| 40 |
| 41 int eventTypeCode(String eventType) { |
| 42 switch(eventType) { |
| 43 case 'debug': |
| 44 return Constants.EVENT_FAMILY_DEBUG; |
| 45 default: |
| 46 return -1; |
| 47 } |
| 48 } |
| 49 |
| 50 void _updateEventMask() { |
| 51 int mask = 0; |
| 52 for (var key in eventMap.keys) { |
| 53 var subscribers = eventMap[key]; |
| 54 if (subscribers.isNotEmpty) { |
| 55 mask |= (1 << key); |
| 56 } |
| 57 } |
| 58 _setEventMask(mask); |
| 59 } |
| 60 |
| 61 void subscribe(String eventType, Client client) { |
| 62 int eventCode = eventTypeCode(eventType); |
| 63 assert(eventCode >= 0); |
| 64 var subscribers = eventMap.putIfAbsent(eventCode, () => new Set<Client>()); |
| 65 subscribers.add(client); |
| 66 _updateEventMask(); |
| 67 } |
| 68 |
| 69 void _controlMessageHandler(int code, |
| 70 int port_id, |
| 71 SendPort sp, |
| 72 String name) { |
29 switch (code) { | 73 switch (code) { |
30 case Constants.ISOLATE_STARTUP_MESSAGE_ID: | 74 case Constants.ISOLATE_STARTUP_MESSAGE_ID: |
31 runningIsolates.isolateStartup(port_id, sp, name); | 75 runningIsolates.isolateStartup(port_id, sp, name); |
32 break; | 76 break; |
33 case Constants.ISOLATE_SHUTDOWN_MESSAGE_ID: | 77 case Constants.ISOLATE_SHUTDOWN_MESSAGE_ID: |
34 runningIsolates.isolateShutdown(port_id, sp); | 78 runningIsolates.isolateShutdown(port_id, sp); |
35 break; | 79 break; |
36 } | 80 } |
37 } | 81 } |
38 | 82 |
39 void _addClient(Client client) { | 83 void _eventMessageHandler(int eventType, String eventMessage) { |
40 clients.add(client); | 84 var subscribers = eventMap[eventType]; |
41 } | 85 if (subscribers == null) { |
42 | 86 return; |
43 void _removeClient(Client client) { | 87 } |
44 clients.remove(client); | 88 for (var subscriber in subscribers) { |
| 89 subscriber.post(null, eventMessage); |
| 90 } |
45 } | 91 } |
46 | 92 |
47 void messageHandler(message) { | 93 void messageHandler(message) { |
48 assert(message is List); | 94 assert(message is List); |
49 assert(message.length == 4); | |
50 if (message is List && message.length == 4) { | 95 if (message is List && message.length == 4) { |
51 controlMessageHandler(message[0], message[1], message[2], message[3]); | 96 _controlMessageHandler(message[0], message[1], message[2], message[3]); |
| 97 } else if (message is List && message.length == 2) { |
| 98 _eventMessageHandler(message[0], message[1]); |
| 99 } else { |
| 100 Logger.root.severe('Unexpected message: $message'); |
52 } | 101 } |
53 } | 102 } |
54 | 103 |
55 VMService._internal() : receivePort = new RawReceivePort() { | 104 VMService._internal() |
56 receivePort.handler = messageHandler; | 105 : eventPort = new RawReceivePort() { |
| 106 eventPort.handler = messageHandler; |
57 } | 107 } |
58 | 108 |
59 factory VMService() { | 109 factory VMService() { |
60 if (VMService._instance == null) { | 110 if (VMService._instance == null) { |
61 VMService._instance = new VMService._internal(); | 111 VMService._instance = new VMService._internal(); |
62 } | 112 } |
63 return _instance; | 113 return _instance; |
64 } | 114 } |
65 | 115 |
66 void _clientCollection(Message message) { | 116 void _clientCollection(Message message) { |
(...skipping 18 matching lines...) Expand all Loading... |
85 if (message.path[0] == 'isolates') { | 135 if (message.path[0] == 'isolates') { |
86 return runningIsolates.route(message); | 136 return runningIsolates.route(message); |
87 } | 137 } |
88 return message.sendToVM(); | 138 return message.sendToVM(); |
89 } | 139 } |
90 } | 140 } |
91 | 141 |
92 RawReceivePort boot() { | 142 RawReceivePort boot() { |
93 // Boot the VMService. | 143 // Boot the VMService. |
94 // Return the port we expect isolate startup and shutdown messages on. | 144 // Return the port we expect isolate startup and shutdown messages on. |
95 return new VMService().receivePort; | 145 return new VMService().eventPort; |
96 } | 146 } |
97 | 147 |
98 void _registerIsolate(int port_id, SendPort sp, String name) { | 148 void _registerIsolate(int port_id, SendPort sp, String name) { |
99 var service = new VMService(); | 149 var service = new VMService(); |
100 service.runningIsolates.isolateStartup(port_id, sp, name); | 150 service.runningIsolates.isolateStartup(port_id, sp, name); |
101 } | 151 } |
| 152 |
| 153 void _setEventMask(int mask) |
| 154 native "VMService_SetEventMask"; |
OLD | NEW |