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

Side by Side Diff: runtime/bin/vmservice_impl.cc

Issue 19231005: Initial NOOP VM Service (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 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 | Annotate | Revision Log
« no previous file with comments | « runtime/bin/vmservice_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 #include "bin/vmservice_impl.h"
6
7 #include "include/dart_api.h"
8
9 #include "bin/builtin.h"
10 #include "bin/dartutils.h"
11 #include "bin/resources.h"
12 #include "bin/thread.h"
13 #include "bin/isolate_data.h"
14
15
16 namespace dart {
17 namespace bin {
18
19 // snapshot_buffer points to a snapshot if we link in a snapshot otherwise
20 // it is initialized to NULL.
21 extern const uint8_t* snapshot_buffer;
22 #define RETURN_ERROR_HANDLE(handle) \
23 if (Dart_IsError(handle)) { \
24 return handle; \
25 }
26
27 #define SHUTDOWN_ON_ERROR(handle) \
28 if (Dart_IsError(handle)) { \
29 error_msg_ = strdup(Dart_GetError(handle)); \
30 Dart_ExitScope(); \
31 Dart_ShutdownIsolate(); \
32 return false; \
33 }
34
35 #define kLibraryResourceNamePrefix "/vmservice"
36 static const char* kLibraryScriptResourceName =
37 kLibraryResourceNamePrefix "/vmservice.dart";
38 static const char* kLibrarySourceResourceNames[] = {
39 NULL
40 };
41
42 #define kClientResourceNamePrefix "/client/web/out"
43
44 Dart_Isolate VmService::isolate_ = NULL;
45 Dart_Port VmService::port_ = ILLEGAL_PORT;
46 dart::Monitor* VmService::monitor_ = NULL;
47 const char* VmService::error_msg_ = NULL;
48
49 // These must be kept in sync with vmservice/constants.dart
50 #define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1
51 #define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2
52
53
54 bool VmService::Start(intptr_t server_port) {
55 monitor_ = new dart::Monitor();
56 ASSERT(monitor_ != NULL);
57 error_msg_ = NULL;
58
59 // The VM service is initialized on a new thread.
60 dart::Thread::Start(ThreadMain, server_port);
61 {
62 // Wait until service is running.
63 MonitorLocker ml(monitor_);
64 ml.Wait();
65 }
66 return port_ != ILLEGAL_PORT;
67 }
68
69
70 bool VmService::_Start(intptr_t server_port) {
71 ASSERT(isolate_ == NULL);
72 char* error = NULL;
73 isolate_ = Dart_CreateIsolate("vmservice:", "main", snapshot_buffer,
74 new IsolateData(),
75 &error);
76 if (isolate_ == NULL) {
77 error_msg_ = error;
78 return false;
79 }
80
81 Dart_EnterScope();
82
83 if (snapshot_buffer != NULL) {
84 // Setup the native resolver as the snapshot does not carry it.
85 Builtin::SetNativeResolver(Builtin::kBuiltinLibrary);
86 Builtin::SetNativeResolver(Builtin::kIOLibrary);
87 }
88
89 // Set up the library tag handler for this isolate.
90 Dart_Handle result = Dart_SetLibraryTagHandler(DartUtils::LibraryTagHandler);
91 SHUTDOWN_ON_ERROR(result);
92
93 // Load the specified application script into the newly created isolate.
94
95 // Prepare builtin and its dependent libraries for use to resolve URIs.
96 // The builtin library is part of the core snapshot and would already be
97 // available here in the case of script snapshot loading.
98 Dart_Handle builtin_lib =
99 Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
100 SHUTDOWN_ON_ERROR(builtin_lib);
101
102 // Prepare for script loading by setting up the 'print' and 'timer'
103 // closures and setting up 'package root' for URI resolution.
104 result = DartUtils::PrepareForScriptLoading("", builtin_lib);
105 SHUTDOWN_ON_ERROR(result);
106
107 {
108 // Load source into service isolate.
109 Dart_Handle library = LoadScript(kLibraryScriptResourceName);
110 SHUTDOWN_ON_ERROR(library);
111 result = LoadSources(library, kLibrarySourceResourceNames);
112 SHUTDOWN_ON_ERROR(result);
113 }
114
115 // Make the isolate runnable so that it is ready to handle messages.
116 Dart_ExitScope();
117 Dart_ExitIsolate();
118
119 bool retval = Dart_IsolateMakeRunnable(isolate_);
120 if (!retval) {
121 Dart_EnterIsolate(isolate_);
122 Dart_ShutdownIsolate();
123 error_msg_ = "Invalid isolate state - Unable to make it runnable.";
124 return false;
125 }
126
127 Dart_EnterIsolate(isolate_);
128 Dart_EnterScope();
129
130 Dart_Handle library = Dart_RootLibrary();
131 result = Dart_Invoke(library, DartUtils::NewString("main"), 0, NULL);
132 SHUTDOWN_ON_ERROR(result);
133
134 result = LoadResources(library);
135 SHUTDOWN_ON_ERROR(result);
136
137 port_ = Dart_GetMainPortId();
138
139 Dart_ExitScope();
140 Dart_ExitIsolate();
141
142 return true;
143 }
144
145
146 void VmService::_Stop() {
147 port_ = ILLEGAL_PORT;
148 }
149
150
151 const char* VmService::GetErrorMessage() {
152 return error_msg_ == NULL ? "No error." : error_msg_;
153 }
154
155
156 Dart_Port VmService::port() {
157 return port_;
158 }
159
160
161 bool VmService::IsRunning() {
162 return port_ != ILLEGAL_PORT;
163 }
164
165
166 Dart_Handle VmService::LoadScript(const char* name) {
167 Dart_Handle url = Dart_NewStringFromCString(name);
168 const char* vmservice_source = NULL;
169 int r = Resources::ResourceLookup(name, &vmservice_source);
170 ASSERT(r != Resources::kNoSuchInstance);
171 Dart_Handle source = Dart_NewStringFromCString(vmservice_source);
172 return Dart_LoadScript(url, source, 0, 0);
173 }
174
175
176 Dart_Handle VmService::LoadSource(Dart_Handle library, const char* name) {
177 Dart_Handle url = Dart_NewStringFromCString(name);
178 const char* vmservice_source = NULL;
179 int r = Resources::ResourceLookup(name, &vmservice_source);
180 if (r == Resources::kNoSuchInstance) {
181 printf("Can't find %s\n", name);
182 }
183 ASSERT(r != Resources::kNoSuchInstance);
184 Dart_Handle source = Dart_NewStringFromCString(vmservice_source);
185 return Dart_LoadSource(library, url, source);
186 }
187
188
189 Dart_Handle VmService::LoadSources(Dart_Handle library, const char* names[]) {
190 Dart_Handle result = Dart_Null();
191 for (int i = 0; names[i] != NULL; i++) {
192 result = LoadSource(library, names[i]);
193 if (Dart_IsError(result)) {
194 break;
195 }
196 }
197 return result;
198 }
199
200
201 Dart_Handle VmService::LoadResource(Dart_Handle library,
202 const char* resource_name,
203 const char* prefix) {
204 intptr_t prefix_len = strlen(prefix);
205 // Prepare for invoke call.
206 Dart_Handle name = Dart_NewStringFromCString(resource_name+prefix_len);
207 RETURN_ERROR_HANDLE(name);
208 const char* data_buffer = NULL;
209 int data_buffer_length = Resources::ResourceLookup(resource_name,
210 &data_buffer);
211 if (data_buffer_length == Resources::kNoSuchInstance) {
212 printf("Could not find %s %s\n", resource_name, resource_name+prefix_len);
213 }
214 ASSERT(data_buffer_length != Resources::kNoSuchInstance);
215 Dart_Handle data_list = Dart_NewTypedData(Dart_TypedData_kUint8,
216 data_buffer_length);
217 RETURN_ERROR_HANDLE(data_list);
218 Dart_TypedData_Type type = Dart_TypedData_kInvalid;
219 void* data_list_buffer = NULL;
220 intptr_t data_list_buffer_length = 0;
221 Dart_Handle result = Dart_TypedDataAcquireData(data_list, &type,
222 &data_list_buffer,
223 &data_list_buffer_length);
224 RETURN_ERROR_HANDLE(result);
225 ASSERT(data_buffer_length == data_list_buffer_length);
226 ASSERT(data_list_buffer != NULL);
227 ASSERT(type = Dart_TypedData_kUint8);
228 memmove(data_list_buffer, &data_buffer[0], data_buffer_length);
229 result = Dart_TypedDataReleaseData(data_list);
230 RETURN_ERROR_HANDLE(result);
231
232 // Make invoke call.
233 const intptr_t kNumArgs = 2;
234 Dart_Handle args[kNumArgs] = { name, data_list };
235 result = Dart_Invoke(library, Dart_NewStringFromCString("_addResource"),
236 kNumArgs, args);
237 return result;
238 }
239
240
241 Dart_Handle VmService::LoadResources(Dart_Handle library) {
242 Dart_Handle result = Dart_Null();
243 intptr_t prefixLen = strlen(kClientResourceNamePrefix);
244 for (intptr_t i = 0; i < Resources::get_resource_count(); i++) {
245 const char* path = Resources::get_resource_path(i);
246 if (!strncmp(path, kClientResourceNamePrefix, prefixLen)) {
247 result = LoadResource(library, path, kClientResourceNamePrefix);
248 if (Dart_IsError(result)) {
249 break;
250 }
251 }
252 }
253 return result;
254 }
255
256
257 void VmService::ThreadMain(uword parameters) {
258 ASSERT(Dart_CurrentIsolate() == NULL);
259 ASSERT(isolate_ == NULL);
siva 2013/07/16 00:00:04 I think you would have to close the MonitorLocker
260 MonitorLocker ml(monitor_);
261 intptr_t server_port = static_cast<intptr_t>(parameters);
262 ASSERT(server_port >= 0);
263
264 bool r = _Start(server_port);
265 if (!r) {
266 port_ = ILLEGAL_PORT;
267 monitor_->Notify();
268 return;
269 }
270
271 Dart_EnterIsolate(isolate_);
272 Dart_EnterScope();
273
274 Dart_Handle receievePort = Dart_GetReceivePort(port_);
275 ASSERT(!Dart_IsError(receievePort));
276
277 monitor_->Notify();
siva 2013/07/16 00:00:04 }
278 // Keep handling messages until the last active receive port is closed.
279 Dart_Handle result = Dart_RunLoop();
280 if (Dart_IsError(result)) {
281 printf("VmService error %s\n", Dart_GetError(result));
282 }
283
284 _Stop();
285
286 Dart_ExitScope();
287 Dart_ExitIsolate();
288 }
289
290
291
292
293 static Dart_Handle MakeServiceControlMessage(Dart_Port port) {
294 Dart_Handle list = Dart_NewList(2);
295 ASSERT(!Dart_IsError(list));
296 Dart_Handle sendPort = Dart_NewSendPort(port);
297 ASSERT(!Dart_IsError(sendPort));
298 Dart_ListSetAt(list, 1, sendPort);
299 return list;
300 }
301
302
303 bool VmService::SendIsolateStartupMessage(Dart_Port port) {
304 if (!IsRunning()) {
305 return false;
306 }
307 Dart_Isolate isolate = Dart_CurrentIsolate();
308 ASSERT(isolate != NULL);
309 ASSERT(Dart_GetMainPortId() == port);
310 Dart_Handle list = MakeServiceControlMessage(port);
311 Dart_ListSetAt(list, 0,
312 Dart_NewInteger(VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID));
313 return Dart_Post(port_, list);
314 }
315
316
317 bool VmService::SendIsolateShutdownMessage(Dart_Port port) {
318 if (!IsRunning()) {
319 return false;
320 }
321 Dart_Isolate isolate = Dart_CurrentIsolate();
322 ASSERT(isolate != NULL);
323 ASSERT(Dart_GetMainPortId() == port);
324 Dart_Handle list = MakeServiceControlMessage(port);
325 Dart_ListSetAt(list, 0,
326 Dart_NewInteger(VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID));
327 return Dart_Post(port_, list);
328 }
329
330
331 } // namespace bin
332 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/bin/vmservice_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698