| OLD | NEW |
| 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 #include "vm/service_isolate.h" | 5 #include "vm/service_isolate.h" |
| 6 | 6 |
| 7 #include "vm/compiler.h" | 7 #include "vm/compiler.h" |
| 8 #include "vm/dart_api_impl.h" | 8 #include "vm/dart_api_impl.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 static Dart_Port ExtractPort(Isolate* isolate, Dart_Handle receivePort) { | 109 static Dart_Port ExtractPort(Isolate* isolate, Dart_Handle receivePort) { |
| 110 const ReceivePort& rp = Api::UnwrapReceivePortHandle(isolate, receivePort); | 110 const ReceivePort& rp = Api::UnwrapReceivePortHandle(isolate, receivePort); |
| 111 if (rp.IsNull()) { | 111 if (rp.IsNull()) { |
| 112 return ILLEGAL_PORT; | 112 return ILLEGAL_PORT; |
| 113 } | 113 } |
| 114 return rp.Id(); | 114 return rp.Id(); |
| 115 } | 115 } |
| 116 | 116 |
| 117 | 117 |
| 118 // These must be kept in sync with service/constants.dart | 118 // These must be kept in sync with service/constants.dart |
| 119 #define VM_SERVICE_ISOLATE_EXIT_MESSAGE_ID 0 |
| 119 #define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1 | 120 #define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1 |
| 120 #define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2 | 121 #define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2 |
| 121 | 122 |
| 122 static RawArray* MakeServiceControlMessage(Dart_Port port_id, intptr_t code, | 123 static RawArray* MakeServiceControlMessage(Dart_Port port_id, intptr_t code, |
| 123 const String& name) { | 124 const String& name) { |
| 124 const Array& list = Array::Handle(Array::New(4)); | 125 const Array& list = Array::Handle(Array::New(4)); |
| 125 ASSERT(!list.IsNull()); | 126 ASSERT(!list.IsNull()); |
| 126 const Integer& code_int = Integer::Handle(Integer::New(code)); | 127 const Integer& code_int = Integer::Handle(Integer::New(code)); |
| 127 const Integer& port_int = Integer::Handle(Integer::New(port_id)); | 128 const Integer& port_int = Integer::Handle(Integer::New(port_id)); |
| 128 const SendPort& send_port = SendPort::Handle(SendPort::New(port_id)); | 129 const SendPort& send_port = SendPort::Handle(SendPort::New(port_id)); |
| 129 list.SetAt(0, code_int); | 130 list.SetAt(0, code_int); |
| 130 list.SetAt(1, port_int); | 131 list.SetAt(1, port_int); |
| 131 list.SetAt(2, send_port); | 132 list.SetAt(2, send_port); |
| 132 list.SetAt(3, name); | 133 list.SetAt(3, name); |
| 133 return list.raw(); | 134 return list.raw(); |
| 134 } | 135 } |
| 135 | 136 |
| 136 | 137 |
| 138 static RawArray* MakeServiceExitMessage() { |
| 139 const Array& list = Array::Handle(Array::New(1)); |
| 140 ASSERT(!list.IsNull()); |
| 141 const intptr_t code = VM_SERVICE_ISOLATE_EXIT_MESSAGE_ID; |
| 142 const Integer& code_int = Integer::Handle(Integer::New(code)); |
| 143 list.SetAt(0, code_int); |
| 144 return list.raw(); |
| 145 } |
| 146 |
| 147 |
| 137 const char* ServiceIsolate::kName = "vm-service"; | 148 const char* ServiceIsolate::kName = "vm-service"; |
| 138 Isolate* ServiceIsolate::isolate_ = NULL; | 149 Isolate* ServiceIsolate::isolate_ = NULL; |
| 139 Dart_Port ServiceIsolate::port_ = ILLEGAL_PORT; | 150 Dart_Port ServiceIsolate::port_ = ILLEGAL_PORT; |
| 140 Dart_Port ServiceIsolate::load_port_ = ILLEGAL_PORT; | 151 Dart_Port ServiceIsolate::load_port_ = ILLEGAL_PORT; |
| 141 Dart_IsolateCreateCallback ServiceIsolate::create_callback_ = NULL; | 152 Dart_IsolateCreateCallback ServiceIsolate::create_callback_ = NULL; |
| 153 uint8_t* ServiceIsolate::exit_message_ = NULL; |
| 154 intptr_t ServiceIsolate::exit_message_length_ = 0; |
| 142 Monitor* ServiceIsolate::monitor_ = NULL; | 155 Monitor* ServiceIsolate::monitor_ = NULL; |
| 143 bool ServiceIsolate::initializing_ = true; | 156 bool ServiceIsolate::initializing_ = true; |
| 157 bool ServiceIsolate::shutting_down_ = false; |
| 144 | 158 |
| 145 | 159 |
| 146 class RegisterRunningIsolatesVisitor : public IsolateVisitor { | 160 class RegisterRunningIsolatesVisitor : public IsolateVisitor { |
| 147 public: | 161 public: |
| 148 explicit RegisterRunningIsolatesVisitor(Isolate* service_isolate) | 162 explicit RegisterRunningIsolatesVisitor(Isolate* service_isolate) |
| 149 : IsolateVisitor(), | 163 : IsolateVisitor(), |
| 150 register_function_(Function::Handle(service_isolate)), | 164 register_function_(Function::Handle(service_isolate)), |
| 151 service_isolate_(service_isolate) { | 165 service_isolate_(service_isolate) { |
| 152 ASSERT(ServiceIsolate::IsServiceIsolate(Isolate::Current())); | 166 ASSERT(ServiceIsolate::IsServiceIsolate(Isolate::Current())); |
| 153 // Get library. | 167 // Get library. |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 | 286 |
| 273 { | 287 { |
| 274 if (FLAG_trace_service) { | 288 if (FLAG_trace_service) { |
| 275 OS::Print("vm-service: Registering running isolates.\n"); | 289 OS::Print("vm-service: Registering running isolates.\n"); |
| 276 } | 290 } |
| 277 // Register running isolates with service. | 291 // Register running isolates with service. |
| 278 RegisterRunningIsolatesVisitor register_isolates(isolate); | 292 RegisterRunningIsolatesVisitor register_isolates(isolate); |
| 279 Isolate::VisitIsolates(®ister_isolates); | 293 Isolate::VisitIsolates(®ister_isolates); |
| 280 } | 294 } |
| 281 } | 295 } |
| 296 |
| 297 static void OnExit(Dart_NativeArguments args) { |
| 298 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); |
| 299 Isolate* isolate = arguments->isolate(); |
| 300 StackZone zone(isolate); |
| 301 HANDLESCOPE(isolate); |
| 302 { |
| 303 if (FLAG_trace_service) { |
| 304 OS::Print("vm-service: processed exit message.\n"); |
| 305 } |
| 306 } |
| 307 } |
| 282 }; | 308 }; |
| 283 | 309 |
| 284 | 310 |
| 285 struct ServiceNativeEntry { | 311 struct ServiceNativeEntry { |
| 286 const char* name; | 312 const char* name; |
| 287 int num_arguments; | 313 int num_arguments; |
| 288 Dart_NativeFunction function; | 314 Dart_NativeFunction function; |
| 289 }; | 315 }; |
| 290 | 316 |
| 291 | 317 |
| 292 static ServiceNativeEntry _ServiceNativeEntries[] = { | 318 static ServiceNativeEntry _ServiceNativeEntries[] = { |
| 293 {"VMService_SendIsolateServiceMessage", 2, | 319 {"VMService_SendIsolateServiceMessage", 2, |
| 294 ServiceIsolateNatives::SendIsolateServiceMessage}, | 320 ServiceIsolateNatives::SendIsolateServiceMessage}, |
| 295 {"VMService_SendRootServiceMessage", 1, | 321 {"VMService_SendRootServiceMessage", 1, |
| 296 ServiceIsolateNatives::SendRootServiceMessage}, | 322 ServiceIsolateNatives::SendRootServiceMessage}, |
| 297 {"VMService_SetEventMask", 1, | 323 {"VMService_SetEventMask", 1, |
| 298 ServiceIsolateNatives::SetEventMask}, | 324 ServiceIsolateNatives::SetEventMask}, |
| 299 {"VMService_OnStart", 0, | 325 {"VMService_OnStart", 0, |
| 300 ServiceIsolateNatives::OnStart }, | 326 ServiceIsolateNatives::OnStart }, |
| 327 {"VMService_OnExit", 0, |
| 328 ServiceIsolateNatives::OnExit }, |
| 301 }; | 329 }; |
| 302 | 330 |
| 303 | 331 |
| 304 static Dart_NativeFunction ServiceNativeResolver(Dart_Handle name, | 332 static Dart_NativeFunction ServiceNativeResolver(Dart_Handle name, |
| 305 int num_arguments, | 333 int num_arguments, |
| 306 bool* auto_setup_scope) { | 334 bool* auto_setup_scope) { |
| 307 const Object& obj = Object::Handle(Api::UnwrapHandle(name)); | 335 const Object& obj = Object::Handle(Api::UnwrapHandle(name)); |
| 308 if (!obj.IsString()) { | 336 if (!obj.IsString()) { |
| 309 return NULL; | 337 return NULL; |
| 310 } | 338 } |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 if (FLAG_trace_service) { | 455 if (FLAG_trace_service) { |
| 428 OS::Print("vm-service: Isolate %s %" Pd64 " deregistered.\n", | 456 OS::Print("vm-service: Isolate %s %" Pd64 " deregistered.\n", |
| 429 name.ToCString(), | 457 name.ToCString(), |
| 430 Dart_GetMainPortId()); | 458 Dart_GetMainPortId()); |
| 431 } | 459 } |
| 432 return PortMap::PostMessage( | 460 return PortMap::PostMessage( |
| 433 new Message(port_, data, len, Message::kNormalPriority)); | 461 new Message(port_, data, len, Message::kNormalPriority)); |
| 434 } | 462 } |
| 435 | 463 |
| 436 | 464 |
| 465 void ServiceIsolate::SendServiceExitMessage() { |
| 466 if (!IsRunning()) { |
| 467 return; |
| 468 } |
| 469 if ((exit_message_ == NULL) || (exit_message_length_ == 0)) { |
| 470 return; |
| 471 } |
| 472 if (FLAG_trace_service) { |
| 473 OS::Print("vm-service: sending service exit message.\n"); |
| 474 } |
| 475 PortMap::PostMessage(new Message(port_, |
| 476 exit_message_, |
| 477 exit_message_length_, |
| 478 Message::kNormalPriority)); |
| 479 } |
| 480 |
| 481 |
| 437 void ServiceIsolate::SetServicePort(Dart_Port port) { | 482 void ServiceIsolate::SetServicePort(Dart_Port port) { |
| 438 MonitorLocker ml(monitor_); | 483 MonitorLocker ml(monitor_); |
| 439 port_ = port; | 484 port_ = port; |
| 440 } | 485 } |
| 441 | 486 |
| 442 | 487 |
| 443 void ServiceIsolate::SetServiceIsolate(Isolate* isolate) { | 488 void ServiceIsolate::SetServiceIsolate(Isolate* isolate) { |
| 444 MonitorLocker ml(monitor_); | 489 MonitorLocker ml(monitor_); |
| 445 isolate_ = isolate; | 490 isolate_ = isolate; |
| 446 if (isolate_ != NULL) { | 491 if (isolate_ != NULL) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 ASSERT(error.IsNull()); | 544 ASSERT(error.IsNull()); |
| 500 Dart_Handle result = Dart_FinalizeLoading(false); | 545 Dart_Handle result = Dart_FinalizeLoading(false); |
| 501 ASSERT(!Dart_IsError(result)); | 546 ASSERT(!Dart_IsError(result)); |
| 502 Dart_ExitScope(); | 547 Dart_ExitScope(); |
| 503 | 548 |
| 504 // Uninstall our library tag handler. | 549 // Uninstall our library tag handler. |
| 505 isolate->set_library_tag_handler(NULL); | 550 isolate->set_library_tag_handler(NULL); |
| 506 } | 551 } |
| 507 | 552 |
| 508 | 553 |
| 554 void ServiceIsolate::ConstructExitMessageAndCache(Isolate* isolate) { |
| 555 // Construct and cache exit message here so we can send it without needing an |
| 556 // isolate. |
| 557 StartIsolateScope iso_scope(isolate); |
| 558 StackZone zone(isolate); |
| 559 HANDLESCOPE(isolate); |
| 560 ASSERT(exit_message_ == NULL); |
| 561 ASSERT(exit_message_length_ == 0); |
| 562 const Array& list = Array::Handle(MakeServiceExitMessage()); |
| 563 ASSERT(!list.IsNull()); |
| 564 MessageWriter writer(&exit_message_, &allocator, false); |
| 565 writer.WriteMessage(list); |
| 566 exit_message_length_ = writer.BytesWritten(); |
| 567 ASSERT(exit_message_ != NULL); |
| 568 ASSERT(exit_message_length_ != 0); |
| 569 } |
| 570 |
| 571 |
| 572 void ServiceIsolate::FinishedExiting() { |
| 573 MonitorLocker ml(monitor_); |
| 574 shutting_down_ = false; |
| 575 ml.NotifyAll(); |
| 576 } |
| 577 |
| 578 |
| 509 void ServiceIsolate::FinishedInitializing() { | 579 void ServiceIsolate::FinishedInitializing() { |
| 510 MonitorLocker ml(monitor_); | 580 MonitorLocker ml(monitor_); |
| 511 initializing_ = false; | 581 initializing_ = false; |
| 512 ml.NotifyAll(); | 582 ml.NotifyAll(); |
| 513 } | 583 } |
| 514 | 584 |
| 515 | 585 |
| 516 class RunServiceTask : public ThreadPool::Task { | 586 class RunServiceTask : public ThreadPool::Task { |
| 517 public: | 587 public: |
| 518 virtual void Run() { | 588 virtual void Run() { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 536 NULL, | 606 NULL, |
| 537 &error)); | 607 &error)); |
| 538 if (isolate == NULL) { | 608 if (isolate == NULL) { |
| 539 OS::PrintErr("vm-service: Isolate creation error: %s\n", error); | 609 OS::PrintErr("vm-service: Isolate creation error: %s\n", error); |
| 540 ServiceIsolate::FinishedInitializing(); | 610 ServiceIsolate::FinishedInitializing(); |
| 541 return; | 611 return; |
| 542 } | 612 } |
| 543 | 613 |
| 544 Isolate::SetCurrent(NULL); | 614 Isolate::SetCurrent(NULL); |
| 545 | 615 |
| 616 ServiceIsolate::ConstructExitMessageAndCache(isolate); |
| 617 |
| 546 RunMain(isolate); | 618 RunMain(isolate); |
| 547 | 619 |
| 548 ServiceIsolate::FinishedInitializing(); | 620 ServiceIsolate::FinishedInitializing(); |
| 549 | 621 |
| 550 isolate->message_handler()->Run(Dart::thread_pool(), | 622 isolate->message_handler()->Run(Dart::thread_pool(), |
| 551 NULL, | 623 NULL, |
| 552 ShutdownIsolate, | 624 ShutdownIsolate, |
| 553 reinterpret_cast<uword>(isolate)); | 625 reinterpret_cast<uword>(isolate)); |
| 554 } | 626 } |
| 555 | 627 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 573 { | 645 { |
| 574 // Shut the isolate down. | 646 // Shut the isolate down. |
| 575 SwitchIsolateScope switch_scope(isolate); | 647 SwitchIsolateScope switch_scope(isolate); |
| 576 Dart::ShutdownIsolate(); | 648 Dart::ShutdownIsolate(); |
| 577 } | 649 } |
| 578 ServiceIsolate::SetServiceIsolate(NULL); | 650 ServiceIsolate::SetServiceIsolate(NULL); |
| 579 ServiceIsolate::SetServicePort(ILLEGAL_PORT); | 651 ServiceIsolate::SetServicePort(ILLEGAL_PORT); |
| 580 if (FLAG_trace_service) { | 652 if (FLAG_trace_service) { |
| 581 OS::Print("vm-service: Shutdown.\n"); | 653 OS::Print("vm-service: Shutdown.\n"); |
| 582 } | 654 } |
| 655 ServiceIsolate::FinishedExiting(); |
| 583 } | 656 } |
| 584 | 657 |
| 585 void RunMain(Isolate* isolate) { | 658 void RunMain(Isolate* isolate) { |
| 586 StartIsolateScope iso_scope(isolate); | 659 StartIsolateScope iso_scope(isolate); |
| 587 StackZone zone(isolate); | 660 StackZone zone(isolate); |
| 588 HANDLESCOPE(isolate); | 661 HANDLESCOPE(isolate); |
| 589 // Invoke main which will return the loadScriptPort. | 662 // Invoke main which will return the loadScriptPort. |
| 590 const Library& root_library = | 663 const Library& root_library = |
| 591 Library::Handle(isolate, isolate->object_store()->root_library()); | 664 Library::Handle(isolate, isolate->object_store()->root_library()); |
| 592 if (root_library.IsNull()) { | 665 if (root_library.IsNull()) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 635 ASSERT(monitor_ == NULL); | 708 ASSERT(monitor_ == NULL); |
| 636 monitor_ = new Monitor(); | 709 monitor_ = new Monitor(); |
| 637 ASSERT(monitor_ != NULL); | 710 ASSERT(monitor_ != NULL); |
| 638 // Grab the isolate create callback here to avoid race conditions with tests | 711 // Grab the isolate create callback here to avoid race conditions with tests |
| 639 // that change this after Dart_Initialize returns. | 712 // that change this after Dart_Initialize returns. |
| 640 create_callback_ = Isolate::CreateCallback(); | 713 create_callback_ = Isolate::CreateCallback(); |
| 641 Dart::thread_pool()->Run(new RunServiceTask()); | 714 Dart::thread_pool()->Run(new RunServiceTask()); |
| 642 } | 715 } |
| 643 | 716 |
| 644 | 717 |
| 718 void ServiceIsolate::Shutdown() { |
| 719 if (!IsRunning()) { |
| 720 return; |
| 721 } |
| 722 { |
| 723 MonitorLocker ml(monitor_); |
| 724 shutting_down_ = true; |
| 725 } |
| 726 SendServiceExitMessage(); |
| 727 { |
| 728 MonitorLocker ml(monitor_); |
| 729 while (shutting_down_ && (port_ != ILLEGAL_PORT)) { |
| 730 ml.Wait(); |
| 731 } |
| 732 } |
| 733 } |
| 734 |
| 735 |
| 645 Dart_Handle ServiceIsolate::GetSource(const char* name) { | 736 Dart_Handle ServiceIsolate::GetSource(const char* name) { |
| 646 ASSERT(name != NULL); | 737 ASSERT(name != NULL); |
| 647 int i = 0; | 738 int i = 0; |
| 648 while (true) { | 739 while (true) { |
| 649 const char* path = Resources::Path(i); | 740 const char* path = Resources::Path(i); |
| 650 if (path == NULL) { | 741 if (path == NULL) { |
| 651 break; | 742 break; |
| 652 } | 743 } |
| 653 ASSERT(*path != '\0'); | 744 ASSERT(*path != '\0'); |
| 654 // Skip the '/'. | 745 // Skip the '/'. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 682 return result; | 773 return result; |
| 683 } | 774 } |
| 684 Dart_Handle source = GetSource(url_string); | 775 Dart_Handle source = GetSource(url_string); |
| 685 if (Dart_IsError(source)) { | 776 if (Dart_IsError(source)) { |
| 686 return source; | 777 return source; |
| 687 } | 778 } |
| 688 return Dart_LoadSource(library, url, source, 0, 0); | 779 return Dart_LoadSource(library, url, source, 0, 0); |
| 689 } | 780 } |
| 690 | 781 |
| 691 } // namespace dart | 782 } // namespace dart |
| OLD | NEW |