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 #include "vm/service.h" | 5 #include "vm/service.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "platform/globals.h" | 8 #include "platform/globals.h" |
9 | 9 |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
11 #include "vm/coverage.h" | 11 #include "vm/coverage.h" |
12 #include "vm/cpu.h" | 12 #include "vm/cpu.h" |
13 #include "vm/dart_api_impl.h" | 13 #include "vm/dart_api_impl.h" |
14 #include "vm/dart_entry.h" | 14 #include "vm/dart_entry.h" |
15 #include "vm/debugger.h" | 15 #include "vm/debugger.h" |
16 #include "vm/isolate.h" | 16 #include "vm/isolate.h" |
17 #include "vm/lockers.h" | |
17 #include "vm/message.h" | 18 #include "vm/message.h" |
18 #include "vm/message_handler.h" | 19 #include "vm/message_handler.h" |
19 #include "vm/native_entry.h" | 20 #include "vm/native_entry.h" |
20 #include "vm/native_arguments.h" | 21 #include "vm/native_arguments.h" |
21 #include "vm/object.h" | 22 #include "vm/object.h" |
22 #include "vm/object_graph.h" | 23 #include "vm/object_graph.h" |
23 #include "vm/object_id_ring.h" | 24 #include "vm/object_id_ring.h" |
24 #include "vm/object_store.h" | 25 #include "vm/object_store.h" |
25 #include "vm/parser.h" | 26 #include "vm/parser.h" |
26 #include "vm/port.h" | 27 #include "vm/port.h" |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
240 static void SendRootServiceMessage(Dart_NativeArguments args) { | 241 static void SendRootServiceMessage(Dart_NativeArguments args) { |
241 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); | 242 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); |
242 Isolate* isolate = arguments->isolate(); | 243 Isolate* isolate = arguments->isolate(); |
243 StackZone zone(isolate); | 244 StackZone zone(isolate); |
244 HANDLESCOPE(isolate); | 245 HANDLESCOPE(isolate); |
245 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(0)); | 246 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(0)); |
246 Service::HandleRootMessage(message); | 247 Service::HandleRootMessage(message); |
247 } | 248 } |
248 | 249 |
249 | 250 |
251 Dart_Port Service::WaitForLoadPort() { | |
252 MonitorLocker ml(monitor_); | |
253 | |
254 while (initializing_ && (load_port_ == ILLEGAL_PORT)) { | |
255 ml.Wait(); | |
256 } | |
257 | |
258 return load_port_; | |
259 } | |
260 | |
261 | |
262 Dart_Port Service::LoadPort() { | |
263 MonitorLocker ml(monitor_); | |
264 return load_port_; | |
265 } | |
266 | |
267 | |
268 void Service::SetLoadPort(Dart_Port port) { | |
269 MonitorLocker ml(monitor_); | |
270 load_port_ = port; | |
271 ml.NotifyAll(); | |
272 } | |
273 | |
274 | |
250 void Service::SetEventMask(uint32_t mask) { | 275 void Service::SetEventMask(uint32_t mask) { |
251 event_mask_ = mask; | 276 event_mask_ = mask; |
252 } | 277 } |
253 | 278 |
254 | 279 |
255 static void SetEventMask(Dart_NativeArguments args) { | 280 static void SetEventMask(Dart_NativeArguments args) { |
256 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); | 281 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); |
257 Isolate* isolate = arguments->isolate(); | 282 Isolate* isolate = arguments->isolate(); |
258 StackZone zone(isolate); | 283 StackZone zone(isolate); |
259 HANDLESCOPE(isolate); | 284 HANDLESCOPE(isolate); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
317 const SendPort& send_port = SendPort::Handle(SendPort::New(port_id)); | 342 const SendPort& send_port = SendPort::Handle(SendPort::New(port_id)); |
318 const String& name = String::Handle(String::New(isolate->name())); | 343 const String& name = String::Handle(String::New(isolate->name())); |
319 ASSERT(!name.IsNull()); | 344 ASSERT(!name.IsNull()); |
320 const Array& args = Array::Handle(Array::New(3)); | 345 const Array& args = Array::Handle(Array::New(3)); |
321 ASSERT(!args.IsNull()); | 346 ASSERT(!args.IsNull()); |
322 args.SetAt(0, port_int); | 347 args.SetAt(0, port_int); |
323 args.SetAt(1, send_port); | 348 args.SetAt(1, send_port); |
324 args.SetAt(2, name); | 349 args.SetAt(2, name); |
325 Object& r = Object::Handle(service_isolate_); | 350 Object& r = Object::Handle(service_isolate_); |
326 r = DartEntry::InvokeFunction(register_function_, args); | 351 r = DartEntry::InvokeFunction(register_function_, args); |
352 if (FLAG_trace_service) { | |
353 OS::Print("Isolate %s %" Pd64 " registered with service \n", | |
354 name.ToCString(), | |
355 port_id); | |
356 } | |
327 ASSERT(!r.IsError()); | 357 ASSERT(!r.IsError()); |
328 } | 358 } |
329 | 359 |
330 private: | 360 private: |
331 Function& register_function_; | 361 Function& register_function_; |
332 Isolate* service_isolate_; | 362 Isolate* service_isolate_; |
333 }; | 363 }; |
334 | 364 |
335 | 365 |
336 static Dart_Port ExtractPort(Isolate* isolate, Dart_Handle receivePort) { | 366 static Dart_Port ExtractPort(Isolate* isolate, Dart_Handle receivePort) { |
337 const ReceivePort& rp = Api::UnwrapReceivePortHandle(isolate, receivePort); | 367 const ReceivePort& rp = Api::UnwrapReceivePortHandle(isolate, receivePort); |
338 if (rp.IsNull()) { | 368 if (rp.IsNull()) { |
339 return ILLEGAL_PORT; | 369 return ILLEGAL_PORT; |
340 } | 370 } |
341 return rp.Id(); | 371 return rp.Id(); |
342 } | 372 } |
343 | 373 |
344 | 374 |
345 static void OnStart(Dart_NativeArguments args) { | 375 static void OnStart(Dart_NativeArguments args) { |
346 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); | 376 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); |
347 Isolate* isolate = arguments->isolate(); | 377 Isolate* isolate = arguments->isolate(); |
348 StackZone zone(isolate); | 378 StackZone zone(isolate); |
349 HANDLESCOPE(isolate); | 379 HANDLESCOPE(isolate); |
350 { | 380 { |
381 if (FLAG_trace_service) { | |
382 OS::Print("Booting dart:vmservice library\n"); | |
383 } | |
351 // Boot the dart:vmservice library. | 384 // Boot the dart:vmservice library. |
352 Dart_EnterScope(); | 385 Dart_EnterScope(); |
353 Dart_Handle url_str = | 386 Dart_Handle url_str = |
354 Dart_NewStringFromCString(Symbols::Name(Symbols::kDartVMServiceId)); | 387 Dart_NewStringFromCString(Symbols::Name(Symbols::kDartVMServiceId)); |
355 Dart_Handle library = Dart_LookupLibrary(url_str); | 388 Dart_Handle library = Dart_LookupLibrary(url_str); |
356 ASSERT(Dart_IsLibrary(library)); | 389 ASSERT(Dart_IsLibrary(library)); |
357 Dart_Handle result = | 390 Dart_Handle result = |
358 Dart_Invoke(library, Dart_NewStringFromCString("boot"), 0, NULL); | 391 Dart_Invoke(library, Dart_NewStringFromCString("boot"), 0, NULL); |
359 ASSERT(!Dart_IsError(result)); | 392 ASSERT(!Dart_IsError(result)); |
360 Dart_Port port = ExtractPort(isolate, result); | 393 Dart_Port port = ExtractPort(isolate, result); |
361 ASSERT(port != ILLEGAL_PORT); | 394 ASSERT(port != ILLEGAL_PORT); |
362 Service::set_port(port); | 395 Service::set_port(port); |
363 Dart_ExitScope(); | 396 Dart_ExitScope(); |
364 } | 397 } |
398 | |
365 { | 399 { |
400 if (FLAG_trace_service) { | |
401 OS::Print("Registering running isolates\n"); | |
402 } | |
366 // Register running isolates with service. | 403 // Register running isolates with service. |
367 RegisterRunningIsolatesVisitor register_isolates(isolate); | 404 RegisterRunningIsolatesVisitor register_isolates(isolate); |
368 Isolate::VisitIsolates(®ister_isolates); | 405 Isolate::VisitIsolates(®ister_isolates); |
369 } | 406 } |
370 } | 407 } |
371 | 408 |
372 | 409 |
373 struct VmServiceNativeEntry { | 410 struct VmServiceNativeEntry { |
374 const char* name; | 411 const char* name; |
375 int num_arguments; | 412 int num_arguments; |
(...skipping 25 matching lines...) Expand all Loading... | |
401 for (intptr_t i = 0; i < n; i++) { | 438 for (intptr_t i = 0; i < n; i++) { |
402 VmServiceNativeEntry entry = _VmServiceNativeEntries[i]; | 439 VmServiceNativeEntry entry = _VmServiceNativeEntries[i]; |
403 if ((strcmp(function_name, entry.name) == 0) && | 440 if ((strcmp(function_name, entry.name) == 0) && |
404 (num_arguments == entry.num_arguments)) { | 441 (num_arguments == entry.num_arguments)) { |
405 return entry.function; | 442 return entry.function; |
406 } | 443 } |
407 } | 444 } |
408 return NULL; | 445 return NULL; |
409 } | 446 } |
410 | 447 |
411 | 448 const char* Service::kServiceIsolateName = "vm-service"; |
412 EmbedderServiceHandler* Service::isolate_service_handler_head_ = NULL; | 449 EmbedderServiceHandler* Service::isolate_service_handler_head_ = NULL; |
413 EmbedderServiceHandler* Service::root_service_handler_head_ = NULL; | 450 EmbedderServiceHandler* Service::root_service_handler_head_ = NULL; |
414 Isolate* Service::service_isolate_ = NULL; | 451 Isolate* Service::service_isolate_ = NULL; |
415 Dart_LibraryTagHandler Service::embedder_provided_handler_ = NULL; | |
416 Dart_Port Service::port_ = ILLEGAL_PORT; | 452 Dart_Port Service::port_ = ILLEGAL_PORT; |
453 Dart_Port Service::load_port_ = ILLEGAL_PORT; | |
454 Monitor* Service::monitor_ = NULL; | |
455 bool Service::initializing_ = true; | |
417 uint32_t Service::event_mask_ = 0; | 456 uint32_t Service::event_mask_ = 0; |
418 | 457 |
419 Isolate* Service::GetServiceIsolate(void* callback_data) { | |
420 if (service_isolate_ != NULL) { | |
421 // Already initialized, return service isolate. | |
422 return service_isolate_; | |
423 } | |
424 Dart_ServiceIsolateCreateCalback create_callback = | |
425 Isolate::ServiceCreateCallback(); | |
426 if (create_callback == NULL) { | |
427 return NULL; | |
428 } | |
429 Isolate::SetCurrent(NULL); | |
430 char* error = NULL; | |
431 Isolate* isolate = | |
432 reinterpret_cast<Isolate*>(create_callback(callback_data, &error)); | |
433 if (isolate == NULL) { | |
434 return NULL; | |
435 } | |
436 StartIsolateScope isolate_scope(isolate); | |
437 { | |
438 // Install the dart:vmservice library. | |
439 StackZone zone(isolate); | |
440 HANDLESCOPE(isolate); | |
441 Library& library = | |
442 Library::Handle(isolate, isolate->object_store()->root_library()); | |
443 // Isolate is empty. | |
444 ASSERT(library.IsNull()); | |
445 // Grab embedder tag handler. | |
446 embedder_provided_handler_ = isolate->library_tag_handler(); | |
447 // Temporarily install our own. | |
448 isolate->set_library_tag_handler(LibraryTagHandler); | |
449 // Get script resource. | |
450 const char* resource = NULL; | |
451 const char* path = "/vmservice.dart"; | |
452 intptr_t r = Resources::ResourceLookup(path, &resource); | |
453 ASSERT(r != Resources::kNoSuchInstance); | |
454 ASSERT(resource != NULL); | |
455 const String& source_str = String::Handle( | |
456 String::FromUTF8(reinterpret_cast<const uint8_t*>(resource), r)); | |
457 ASSERT(!source_str.IsNull()); | |
458 const String& url_str = String::Handle(Symbols::DartVMService().raw()); | |
459 library ^= Library::LookupLibrary(url_str); | |
460 ASSERT(library.IsNull()); | |
461 // Setup library. | |
462 library = Library::New(url_str); | |
463 library.Register(); | |
464 const Script& script = Script::Handle( | |
465 isolate, Script::New(url_str, source_str, RawScript::kLibraryTag)); | |
466 library.SetLoadInProgress(); | |
467 Dart_EnterScope(); // Need to enter scope for tag handler. | |
468 const Error& error = Error::Handle(isolate, | |
469 Compiler::Compile(library, script)); | |
470 ASSERT(error.IsNull()); | |
471 Dart_Handle result = Dart_FinalizeLoading(false); | |
472 ASSERT(!Dart_IsError(result)); | |
473 Dart_ExitScope(); | |
474 | 458 |
475 // Install embedder default library tag handler again. | 459 bool Service::IsServiceIsolateName(const char* name) { |
476 isolate->set_library_tag_handler(embedder_provided_handler_); | 460 ASSERT(name != NULL); |
477 embedder_provided_handler_ = NULL; | 461 return strcmp(name, kServiceIsolateName) == 0; |
478 library.set_native_entry_resolver(VmServiceNativeResolver); | |
479 } | |
480 service_isolate_ = reinterpret_cast<Isolate*>(isolate); | |
481 return service_isolate_; | |
482 } | 462 } |
483 | 463 |
484 | 464 |
485 bool Service::SendIsolateStartupMessage() { | 465 bool Service::SendIsolateStartupMessage() { |
486 if (!IsRunning()) { | 466 if (!IsRunning()) { |
487 return false; | 467 return false; |
488 } | 468 } |
489 Isolate* isolate = Isolate::Current(); | 469 Isolate* isolate = Isolate::Current(); |
470 if (IsServiceIsolate(isolate)) { | |
471 return false; | |
472 } | |
490 ASSERT(isolate != NULL); | 473 ASSERT(isolate != NULL); |
491 HANDLESCOPE(isolate); | 474 HANDLESCOPE(isolate); |
492 const String& name = String::Handle(String::New(isolate->name())); | 475 const String& name = String::Handle(String::New(isolate->name())); |
493 ASSERT(!name.IsNull()); | 476 ASSERT(!name.IsNull()); |
494 const Array& list = Array::Handle( | 477 const Array& list = Array::Handle( |
495 MakeServiceControlMessage(Dart_GetMainPortId(), | 478 MakeServiceControlMessage(Dart_GetMainPortId(), |
496 VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID, | 479 VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID, |
497 name)); | 480 name)); |
498 ASSERT(!list.IsNull()); | 481 ASSERT(!list.IsNull()); |
499 uint8_t* data = NULL; | 482 uint8_t* data = NULL; |
500 MessageWriter writer(&data, &allocator, false); | 483 MessageWriter writer(&data, &allocator, false); |
501 writer.WriteMessage(list); | 484 writer.WriteMessage(list); |
502 intptr_t len = writer.BytesWritten(); | 485 intptr_t len = writer.BytesWritten(); |
503 if (FLAG_trace_service) { | 486 if (FLAG_trace_service) { |
504 OS::Print("Isolate %s %" Pd64 " registered with service \n", | 487 OS::Print("Isolate %s %" Pd64 " registered with service \n", |
505 name.ToCString(), | 488 name.ToCString(), |
506 Dart_GetMainPortId()); | 489 Dart_GetMainPortId()); |
507 } | 490 } |
508 return PortMap::PostMessage( | 491 return PortMap::PostMessage( |
509 new Message(port_, data, len, Message::kNormalPriority)); | 492 new Message(port_, data, len, Message::kNormalPriority)); |
510 } | 493 } |
511 | 494 |
512 | 495 |
513 bool Service::SendIsolateShutdownMessage() { | 496 bool Service::SendIsolateShutdownMessage() { |
514 if (!IsRunning()) { | 497 if (!IsRunning()) { |
515 return false; | 498 return false; |
516 } | 499 } |
517 Isolate* isolate = Isolate::Current(); | 500 Isolate* isolate = Isolate::Current(); |
501 if (IsServiceIsolate(isolate)) { | |
502 return false; | |
503 } | |
518 ASSERT(isolate != NULL); | 504 ASSERT(isolate != NULL); |
519 HANDLESCOPE(isolate); | 505 HANDLESCOPE(isolate); |
520 const String& name = String::Handle(String::New(isolate->name())); | 506 const String& name = String::Handle(String::New(isolate->name())); |
521 ASSERT(!name.IsNull()); | 507 ASSERT(!name.IsNull()); |
522 const Array& list = Array::Handle( | 508 const Array& list = Array::Handle( |
523 MakeServiceControlMessage(Dart_GetMainPortId(), | 509 MakeServiceControlMessage(Dart_GetMainPortId(), |
524 VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID, | 510 VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID, |
525 name)); | 511 name)); |
526 ASSERT(!list.IsNull()); | 512 ASSERT(!list.IsNull()); |
527 uint8_t* data = NULL; | 513 uint8_t* data = NULL; |
(...skipping 25 matching lines...) Expand all Loading... | |
553 const uint8_t* str = Resources::Resource(i); | 539 const uint8_t* str = Resources::Resource(i); |
554 intptr_t length = Resources::Length(i); | 540 intptr_t length = Resources::Length(i); |
555 return Dart_NewStringFromUTF8(str, length); | 541 return Dart_NewStringFromUTF8(str, length); |
556 } | 542 } |
557 i++; | 543 i++; |
558 } | 544 } |
559 return Dart_Null(); | 545 return Dart_Null(); |
560 } | 546 } |
561 | 547 |
562 | 548 |
563 Dart_Handle Service::LibraryTagHandler(Dart_LibraryTag tag, Dart_Handle library, | 549 Dart_Handle Service::LibraryTagHandler(Dart_LibraryTag tag, |
550 Dart_Handle library, | |
564 Dart_Handle url) { | 551 Dart_Handle url) { |
565 if (!Dart_IsLibrary(library)) { | 552 if (!Dart_IsLibrary(library)) { |
566 return Dart_NewApiError("not a library"); | 553 return Dart_NewApiError("not a library"); |
567 } | 554 } |
568 if (!Dart_IsString(url)) { | 555 if (!Dart_IsString(url)) { |
569 return Dart_NewApiError("url is not a string"); | 556 return Dart_NewApiError("url is not a string"); |
570 } | 557 } |
571 const char* url_string = NULL; | 558 const char* url_string = NULL; |
572 Dart_Handle result = Dart_StringToCString(url, &url_string); | 559 Dart_Handle result = Dart_StringToCString(url, &url_string); |
573 if (Dart_IsError(result)) { | 560 if (Dart_IsError(result)) { |
574 return result; | 561 return result; |
575 } | 562 } |
576 if (tag == Dart_kImportTag) { | 563 if (tag == Dart_kImportTag) { |
577 // Embedder handles all requests for external libraries. | 564 OS::Print("Attempting to import %s\n", url_string); |
578 if (embedder_provided_handler_ == NULL) { | 565 return Dart_NewApiError("Unable to import module as no library tag " |
579 return Dart_NewApiError("Unable to import module as no library tag " | 566 "is available"); |
580 "handler has been provided by embedder"); | |
581 } | |
582 return embedder_provided_handler_(tag, library, url); | |
583 } | 567 } |
584 ASSERT((tag == Dart_kSourceTag) || (tag == Dart_kCanonicalizeUrl)); | 568 ASSERT((tag == Dart_kSourceTag) || (tag == Dart_kCanonicalizeUrl)); |
585 if (tag == Dart_kCanonicalizeUrl) { | 569 if (tag == Dart_kCanonicalizeUrl) { |
586 // url is already canonicalized. | 570 // url is already canonicalized. |
587 return url; | 571 return url; |
588 } | 572 } |
589 Dart_Handle source = GetSource(url_string); | 573 Dart_Handle source = GetSource(url_string); |
590 if (Dart_IsError(source)) { | 574 if (Dart_IsError(source)) { |
591 return source; | 575 return source; |
592 } | 576 } |
593 return Dart_LoadSource(library, url, source, 0, 0); | 577 return Dart_LoadSource(library, url, source, 0, 0); |
594 } | 578 } |
595 | 579 |
596 | 580 |
581 void Service::MaybeInjectVMServiceLibrary(Isolate* isolate) { | |
582 if (service_isolate_ != NULL) { | |
583 // Service isolate already exists. | |
584 return; | |
585 } | |
586 if (!Service::IsServiceIsolateName(isolate->name())) { | |
587 // Not service isolate. | |
588 return; | |
589 } | |
590 service_isolate_ = isolate; | |
591 ASSERT(isolate != NULL); | |
592 StackZone zone(isolate); | |
593 HANDLESCOPE(isolate); | |
594 | |
595 // Verify that isolate has no root library. | |
596 Library& library = | |
597 Library::Handle(isolate, isolate->object_store()->root_library()); | |
598 ASSERT(library.IsNull()); | |
599 | |
600 // Verify that isolate doesn't have the dart:vmservice library. | |
601 const String& url_str = String::Handle(Symbols::DartVMService().raw()); | |
602 library ^= Library::LookupLibrary(url_str); | |
603 ASSERT(library.IsNull()); | |
604 | |
605 // Register dart:vmservice library. | |
606 library = Library::New(url_str); | |
607 library.Register(); | |
608 library.set_native_entry_resolver(VmServiceNativeResolver); | |
609 | |
610 // Temporarily install our library tag handler. | |
611 isolate->set_library_tag_handler(LibraryTagHandler); | |
612 | |
613 // Get script source. | |
614 const char* resource = NULL; | |
615 const char* path = "/vmservice.dart"; | |
616 intptr_t r = Resources::ResourceLookup(path, &resource); | |
617 ASSERT(r != Resources::kNoSuchInstance); | |
618 ASSERT(resource != NULL); | |
619 const String& source_str = String::Handle( | |
620 String::FromUTF8(reinterpret_cast<const uint8_t*>(resource), r)); | |
621 ASSERT(!source_str.IsNull()); | |
622 const Script& script = Script::Handle( | |
623 isolate, Script::New(url_str, source_str, RawScript::kLibraryTag)); | |
624 | |
625 // Compile script. | |
626 Dart_EnterScope(); // Need to enter scope for tag handler. | |
627 library.SetLoadInProgress(); | |
628 const Error& error = Error::Handle(isolate, | |
629 Compiler::Compile(library, script)); | |
630 ASSERT(error.IsNull()); | |
631 Dart_Handle result = Dart_FinalizeLoading(false); | |
632 ASSERT(!Dart_IsError(result)); | |
633 Dart_ExitScope(); | |
634 | |
635 // Uninstall our library tag handler. | |
636 isolate->set_library_tag_handler(NULL); | |
637 } | |
638 | |
639 | |
640 void Service::FinishedInitializing() { | |
641 MonitorLocker ml(monitor_); | |
642 initializing_ = false; | |
643 ml.NotifyAll(); | |
644 } | |
645 | |
646 | |
647 static void ShutdownIsolate(uword parameter) { | |
648 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); | |
649 { | |
650 // Print the error if there is one. This may execute dart code to | |
651 // print the exception object, so we need to use a StartIsolateScope. | |
652 StartIsolateScope start_scope(isolate); | |
653 StackZone zone(isolate); | |
654 HandleScope handle_scope(isolate); | |
655 Error& error = Error::Handle(); | |
656 error = isolate->object_store()->sticky_error(); | |
657 if (!error.IsNull()) { | |
658 OS::PrintErr("Service shutting down: %s\n", error.ToErrorCString()); | |
659 } | |
660 Dart::RunShutdownCallback(); | |
661 } | |
662 { | |
663 // Shut the isolate down. | |
664 SwitchIsolateScope switch_scope(isolate); | |
665 Dart::ShutdownIsolate(); | |
666 } | |
667 } | |
668 | |
669 | |
670 class RunServiceTask : public ThreadPool::Task { | |
671 public: | |
672 virtual void Run() { | |
673 ASSERT(Isolate::Current() == NULL); | |
674 | |
675 Dart_IsolateCreateCallback create_callback = Isolate::CreateCallback(); | |
676 if (create_callback == NULL) { | |
677 Service::FinishedInitializing(); | |
siva
2015/01/22 22:39:31
on error cases a thread that is waiting on Service
Cutch
2015/01/26 18:59:30
No, the loop in WaitForLoadPort will break if init
| |
678 return; | |
679 } | |
680 | |
681 char* error = NULL; | |
682 Isolate* isolate = | |
683 reinterpret_cast<Isolate*>(create_callback(Service::kServiceIsolateName, | |
684 NULL, | |
685 NULL, | |
686 NULL, | |
687 &error)); | |
688 Isolate::SetCurrent(NULL); | |
689 | |
690 if (isolate == NULL) { | |
691 OS::PrintErr("Service startup error: %s\n", error); | |
692 Service::FinishedInitializing(); | |
693 return; | |
694 } | |
695 | |
696 RunMain(isolate); | |
697 | |
698 Service::FinishedInitializing(); | |
699 | |
700 isolate->message_handler()->Run(Dart::thread_pool(), | |
701 NULL, | |
702 ShutdownIsolate, | |
703 reinterpret_cast<uword>(isolate)); | |
704 } | |
705 | |
706 protected: | |
707 void RunMain(Isolate* isolate) { | |
708 StartIsolateScope iso_scope(isolate); | |
709 StackZone zone(isolate); | |
710 HANDLESCOPE(isolate); | |
711 // Invoke main which will return the loadScriptPort. | |
712 const Library& root_library = | |
713 Library::Handle(isolate, isolate->object_store()->root_library()); | |
714 if (root_library.IsNull()) { | |
715 // Service isolate is not supported by embedder. | |
716 return; | |
717 } | |
718 ASSERT(!root_library.IsNull()); | |
719 const String& entry_name = String::Handle(isolate, String::New("main")); | |
720 ASSERT(!entry_name.IsNull()); | |
721 const Function& entry = | |
722 Function::Handle(isolate, | |
723 root_library.LookupFunctionAllowPrivate(entry_name)); | |
724 if (entry.IsNull()) { | |
725 // Service isolate is not supported by embedder. | |
726 return; | |
727 } | |
728 ASSERT(!entry.IsNull()); | |
729 const Object& result = | |
730 Object::Handle(isolate, | |
731 DartEntry::InvokeFunction(entry, | |
732 Object::empty_array())); | |
733 ASSERT(!result.IsNull()); | |
734 if (result.IsError()) { | |
735 // Service isolate did not initialize properly. | |
736 return; | |
737 } | |
738 ASSERT(result.IsReceivePort()); | |
739 const ReceivePort& rp = ReceivePort::Cast(result); | |
740 Service::SetLoadPort(rp.Id()); | |
siva
2015/01/22 22:39:31
This is somewhat confusing, this function does a n
Cutch
2015/01/26 18:59:30
Removed notifyAll from SetLoadPort.
| |
741 } | |
742 }; | |
743 | |
744 | |
745 void Service::RunService() { | |
746 ASSERT(monitor_ == NULL); | |
747 monitor_ = new Monitor(); | |
748 ASSERT(monitor_ != NULL); | |
749 Dart::thread_pool()->Run(new RunServiceTask()); | |
750 } | |
751 | |
597 // A handler for a per-isolate request. | 752 // A handler for a per-isolate request. |
598 // | 753 // |
599 // If a handler returns true, the reply is complete and ready to be | 754 // If a handler returns true, the reply is complete and ready to be |
600 // posted. If a handler returns false, then it is responsible for | 755 // posted. If a handler returns false, then it is responsible for |
601 // posting the reply (this can be used for asynchronous delegation of | 756 // posting the reply (this can be used for asynchronous delegation of |
602 // the response handling). | 757 // the response handling). |
603 typedef bool (*IsolateMessageHandler)(Isolate* isolate, JSONStream* stream); | 758 typedef bool (*IsolateMessageHandler)(Isolate* isolate, JSONStream* stream); |
604 | 759 |
605 struct IsolateMessageHandlerEntry { | 760 struct IsolateMessageHandlerEntry { |
606 const char* command; | 761 const char* command; |
(...skipping 2173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2780 while (current != NULL) { | 2935 while (current != NULL) { |
2781 if (strcmp(name, current->name()) == 0) { | 2936 if (strcmp(name, current->name()) == 0) { |
2782 return current; | 2937 return current; |
2783 } | 2938 } |
2784 current = current->next(); | 2939 current = current->next(); |
2785 } | 2940 } |
2786 return NULL; | 2941 return NULL; |
2787 } | 2942 } |
2788 | 2943 |
2789 } // namespace dart | 2944 } // namespace dart |
OLD | NEW |