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 ServiceIsolate::FinishedExiting(); | |
307 } | |
308 } | |
282 }; | 309 }; |
283 | 310 |
284 | 311 |
285 struct ServiceNativeEntry { | 312 struct ServiceNativeEntry { |
286 const char* name; | 313 const char* name; |
287 int num_arguments; | 314 int num_arguments; |
288 Dart_NativeFunction function; | 315 Dart_NativeFunction function; |
289 }; | 316 }; |
290 | 317 |
291 | 318 |
292 static ServiceNativeEntry _ServiceNativeEntries[] = { | 319 static ServiceNativeEntry _ServiceNativeEntries[] = { |
293 {"VMService_SendIsolateServiceMessage", 2, | 320 {"VMService_SendIsolateServiceMessage", 2, |
294 ServiceIsolateNatives::SendIsolateServiceMessage}, | 321 ServiceIsolateNatives::SendIsolateServiceMessage}, |
295 {"VMService_SendRootServiceMessage", 1, | 322 {"VMService_SendRootServiceMessage", 1, |
296 ServiceIsolateNatives::SendRootServiceMessage}, | 323 ServiceIsolateNatives::SendRootServiceMessage}, |
297 {"VMService_SetEventMask", 1, | 324 {"VMService_SetEventMask", 1, |
298 ServiceIsolateNatives::SetEventMask}, | 325 ServiceIsolateNatives::SetEventMask}, |
299 {"VMService_OnStart", 0, | 326 {"VMService_OnStart", 0, |
300 ServiceIsolateNatives::OnStart }, | 327 ServiceIsolateNatives::OnStart }, |
328 {"VMService_OnExit", 0, | |
329 ServiceIsolateNatives::OnExit }, | |
301 }; | 330 }; |
302 | 331 |
303 | 332 |
304 static Dart_NativeFunction ServiceNativeResolver(Dart_Handle name, | 333 static Dart_NativeFunction ServiceNativeResolver(Dart_Handle name, |
305 int num_arguments, | 334 int num_arguments, |
306 bool* auto_setup_scope) { | 335 bool* auto_setup_scope) { |
307 const Object& obj = Object::Handle(Api::UnwrapHandle(name)); | 336 const Object& obj = Object::Handle(Api::UnwrapHandle(name)); |
308 if (!obj.IsString()) { | 337 if (!obj.IsString()) { |
309 return NULL; | 338 return NULL; |
310 } | 339 } |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
427 if (FLAG_trace_service) { | 456 if (FLAG_trace_service) { |
428 OS::Print("vm-service: Isolate %s %" Pd64 " deregistered.\n", | 457 OS::Print("vm-service: Isolate %s %" Pd64 " deregistered.\n", |
429 name.ToCString(), | 458 name.ToCString(), |
430 Dart_GetMainPortId()); | 459 Dart_GetMainPortId()); |
431 } | 460 } |
432 return PortMap::PostMessage( | 461 return PortMap::PostMessage( |
433 new Message(port_, data, len, Message::kNormalPriority)); | 462 new Message(port_, data, len, Message::kNormalPriority)); |
434 } | 463 } |
435 | 464 |
436 | 465 |
466 void ServiceIsolate::SendServiceExitMessage() { | |
467 if (!IsRunning()) { | |
zra
2015/03/24 21:53:59
Should this be an ASSERT()?
Cutch
2015/03/24 23:39:07
No, we may have failed to startup the service isol
| |
468 return; | |
469 } | |
470 if ((exit_message_ == NULL) || (exit_message_length_ == 0)) { | |
zra
2015/03/24 21:53:59
ditto
Cutch
2015/03/24 23:39:07
Similarly.
| |
471 return; | |
472 } | |
473 if (FLAG_trace_service) { | |
474 OS::Print("vm-service: sending service exit message.\n"); | |
475 } | |
476 PortMap::PostMessage(new Message(port_, | |
477 exit_message_, | |
478 exit_message_length_, | |
479 Message::kNormalPriority)); | |
480 } | |
481 | |
482 | |
437 void ServiceIsolate::SetServicePort(Dart_Port port) { | 483 void ServiceIsolate::SetServicePort(Dart_Port port) { |
438 MonitorLocker ml(monitor_); | 484 MonitorLocker ml(monitor_); |
439 port_ = port; | 485 port_ = port; |
440 } | 486 } |
441 | 487 |
442 | 488 |
443 void ServiceIsolate::SetServiceIsolate(Isolate* isolate) { | 489 void ServiceIsolate::SetServiceIsolate(Isolate* isolate) { |
444 MonitorLocker ml(monitor_); | 490 MonitorLocker ml(monitor_); |
445 isolate_ = isolate; | 491 isolate_ = isolate; |
446 if (isolate_ != NULL) { | 492 if (isolate_ != NULL) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
499 ASSERT(error.IsNull()); | 545 ASSERT(error.IsNull()); |
500 Dart_Handle result = Dart_FinalizeLoading(false); | 546 Dart_Handle result = Dart_FinalizeLoading(false); |
501 ASSERT(!Dart_IsError(result)); | 547 ASSERT(!Dart_IsError(result)); |
502 Dart_ExitScope(); | 548 Dart_ExitScope(); |
503 | 549 |
504 // Uninstall our library tag handler. | 550 // Uninstall our library tag handler. |
505 isolate->set_library_tag_handler(NULL); | 551 isolate->set_library_tag_handler(NULL); |
506 } | 552 } |
507 | 553 |
508 | 554 |
555 void ServiceIsolate::ConstructExitMessageAndCache(Isolate* isolate) { | |
556 // Construct and cache exit message here so we can send it without needing an | |
557 // isolate. | |
558 StartIsolateScope iso_scope(isolate); | |
559 StackZone zone(isolate); | |
560 HANDLESCOPE(isolate); | |
561 ASSERT(exit_message_ == NULL); | |
562 ASSERT(exit_message_length_ == 0); | |
563 const Array& list = Array::Handle(MakeServiceExitMessage()); | |
564 ASSERT(!list.IsNull()); | |
565 MessageWriter writer(&exit_message_, &allocator, false); | |
566 writer.WriteMessage(list); | |
567 exit_message_length_ = writer.BytesWritten(); | |
568 ASSERT(exit_message_ != NULL); | |
569 ASSERT(exit_message_length_ != 0); | |
570 } | |
571 | |
572 | |
573 void ServiceIsolate::FinishedExiting() { | |
574 MonitorLocker ml(monitor_); | |
575 shutting_down_ = false; | |
576 ml.NotifyAll(); | |
577 } | |
578 | |
579 | |
509 void ServiceIsolate::FinishedInitializing() { | 580 void ServiceIsolate::FinishedInitializing() { |
510 MonitorLocker ml(monitor_); | 581 MonitorLocker ml(monitor_); |
511 initializing_ = false; | 582 initializing_ = false; |
512 ml.NotifyAll(); | 583 ml.NotifyAll(); |
513 } | 584 } |
514 | 585 |
515 | 586 |
516 class RunServiceTask : public ThreadPool::Task { | 587 class RunServiceTask : public ThreadPool::Task { |
517 public: | 588 public: |
518 virtual void Run() { | 589 virtual void Run() { |
(...skipping 17 matching lines...) Expand all Loading... | |
536 NULL, | 607 NULL, |
537 &error)); | 608 &error)); |
538 if (isolate == NULL) { | 609 if (isolate == NULL) { |
539 OS::PrintErr("vm-service: Isolate creation error: %s\n", error); | 610 OS::PrintErr("vm-service: Isolate creation error: %s\n", error); |
540 ServiceIsolate::FinishedInitializing(); | 611 ServiceIsolate::FinishedInitializing(); |
541 return; | 612 return; |
542 } | 613 } |
543 | 614 |
544 Isolate::SetCurrent(NULL); | 615 Isolate::SetCurrent(NULL); |
545 | 616 |
617 ServiceIsolate::ConstructExitMessageAndCache(isolate); | |
618 | |
546 RunMain(isolate); | 619 RunMain(isolate); |
547 | 620 |
548 ServiceIsolate::FinishedInitializing(); | 621 ServiceIsolate::FinishedInitializing(); |
549 | 622 |
550 isolate->message_handler()->Run(Dart::thread_pool(), | 623 isolate->message_handler()->Run(Dart::thread_pool(), |
551 NULL, | 624 NULL, |
552 ShutdownIsolate, | 625 ShutdownIsolate, |
553 reinterpret_cast<uword>(isolate)); | 626 reinterpret_cast<uword>(isolate)); |
554 } | 627 } |
555 | 628 |
(...skipping 79 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()) { | |
zra
2015/03/24 21:53:59
ditto
Cutch
2015/03/24 23:39:07
ditto.
| |
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)) { | |
zra
2015/03/24 21:53:59
Why would port_ be illegal?
Cutch
2015/03/24 23:39:07
Before the service isolate starts up and after it
| |
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 |