| 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 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 &api_flags, | 332 &api_flags, |
| 333 NULL, | 333 NULL, |
| 334 &error)); | 334 &error)); |
| 335 if (isolate == NULL) { | 335 if (isolate == NULL) { |
| 336 OS::PrintErr("vm-service: Isolate creation error: %s\n", error); | 336 OS::PrintErr("vm-service: Isolate creation error: %s\n", error); |
| 337 ServiceIsolate::SetServiceIsolate(NULL); | 337 ServiceIsolate::SetServiceIsolate(NULL); |
| 338 ServiceIsolate::FinishedInitializing(); | 338 ServiceIsolate::FinishedInitializing(); |
| 339 return; | 339 return; |
| 340 } | 340 } |
| 341 | 341 |
| 342 bool got_unwind; |
| 342 { | 343 { |
| 343 ASSERT(Isolate::Current() == NULL); | 344 ASSERT(Isolate::Current() == NULL); |
| 344 StartIsolateScope start_scope(isolate); | 345 StartIsolateScope start_scope(isolate); |
| 345 ServiceIsolate::ConstructExitMessageAndCache(isolate); | 346 ServiceIsolate::ConstructExitMessageAndCache(isolate); |
| 346 RunMain(isolate); | 347 got_unwind = RunMain(isolate); |
| 348 } |
| 349 |
| 350 if (got_unwind) { |
| 351 ShutdownIsolate(reinterpret_cast<uword>(isolate)); |
| 352 return; |
| 347 } | 353 } |
| 348 | 354 |
| 349 ServiceIsolate::FinishedInitializing(); | 355 ServiceIsolate::FinishedInitializing(); |
| 350 | 356 |
| 351 isolate->message_handler()->Run(Dart::thread_pool(), | 357 isolate->message_handler()->Run(Dart::thread_pool(), |
| 352 NULL, | 358 NULL, |
| 353 ShutdownIsolate, | 359 ShutdownIsolate, |
| 354 reinterpret_cast<uword>(isolate)); | 360 reinterpret_cast<uword>(isolate)); |
| 355 } | 361 } |
| 356 | 362 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 378 Dart::RunShutdownCallback(); | 384 Dart::RunShutdownCallback(); |
| 379 } | 385 } |
| 380 // Shut the isolate down. | 386 // Shut the isolate down. |
| 381 Dart::ShutdownIsolate(I); | 387 Dart::ShutdownIsolate(I); |
| 382 if (FLAG_trace_service) { | 388 if (FLAG_trace_service) { |
| 383 OS::Print("vm-service: Shutdown.\n"); | 389 OS::Print("vm-service: Shutdown.\n"); |
| 384 } | 390 } |
| 385 ServiceIsolate::FinishedExiting(); | 391 ServiceIsolate::FinishedExiting(); |
| 386 } | 392 } |
| 387 | 393 |
| 388 void RunMain(Isolate* I) { | 394 bool RunMain(Isolate* I) { |
| 389 Thread* T = Thread::Current(); | 395 Thread* T = Thread::Current(); |
| 390 ASSERT(I == T->isolate()); | 396 ASSERT(I == T->isolate()); |
| 391 StackZone zone(T); | 397 StackZone zone(T); |
| 392 HANDLESCOPE(T); | 398 HANDLESCOPE(T); |
| 393 // Invoke main which will return the loadScriptPort. | 399 // Invoke main which will return the loadScriptPort. |
| 394 const Library& root_library = Library::Handle(Z, | 400 const Library& root_library = Library::Handle(Z, |
| 395 I->object_store()->root_library()); | 401 I->object_store()->root_library()); |
| 396 if (root_library.IsNull()) { | 402 if (root_library.IsNull()) { |
| 397 if (FLAG_trace_service) { | 403 if (FLAG_trace_service) { |
| 398 OS::Print("vm-service: Embedder did not install a script."); | 404 OS::Print("vm-service: Embedder did not install a script."); |
| 399 } | 405 } |
| 400 // Service isolate is not supported by embedder. | 406 // Service isolate is not supported by embedder. |
| 401 return; | 407 return false; |
| 402 } | 408 } |
| 403 ASSERT(!root_library.IsNull()); | 409 ASSERT(!root_library.IsNull()); |
| 404 const String& entry_name = String::Handle(Z, String::New("main")); | 410 const String& entry_name = String::Handle(Z, String::New("main")); |
| 405 ASSERT(!entry_name.IsNull()); | 411 ASSERT(!entry_name.IsNull()); |
| 406 const Function& entry = Function::Handle(Z, | 412 const Function& entry = Function::Handle(Z, |
| 407 root_library.LookupFunctionAllowPrivate(entry_name)); | 413 root_library.LookupFunctionAllowPrivate(entry_name)); |
| 408 if (entry.IsNull()) { | 414 if (entry.IsNull()) { |
| 409 // Service isolate is not supported by embedder. | 415 // Service isolate is not supported by embedder. |
| 410 if (FLAG_trace_service) { | 416 if (FLAG_trace_service) { |
| 411 OS::Print("vm-service: Embedder did not provide a main function."); | 417 OS::Print("vm-service: Embedder did not provide a main function."); |
| 412 } | 418 } |
| 413 return; | 419 return false; |
| 414 } | 420 } |
| 415 ASSERT(!entry.IsNull()); | 421 ASSERT(!entry.IsNull()); |
| 416 const Object& result = Object::Handle(Z, | 422 const Object& result = Object::Handle(Z, |
| 417 DartEntry::InvokeFunction(entry, Object::empty_array())); | 423 DartEntry::InvokeFunction(entry, Object::empty_array())); |
| 418 ASSERT(!result.IsNull()); | 424 ASSERT(!result.IsNull()); |
| 419 if (result.IsError()) { | 425 if (result.IsError()) { |
| 420 // Service isolate did not initialize properly. | 426 // Service isolate did not initialize properly. |
| 421 if (FLAG_trace_service) { | 427 if (FLAG_trace_service) { |
| 422 const Error& error = Error::Cast(result); | 428 const Error& error = Error::Cast(result); |
| 423 OS::Print("vm-service: Calling main resulted in an error: %s", | 429 OS::Print("vm-service: Calling main resulted in an error: %s", |
| 424 error.ToErrorCString()); | 430 error.ToErrorCString()); |
| 425 } | 431 } |
| 426 return; | 432 if (result.IsUnwindError()) { |
| 433 return true; |
| 434 } |
| 435 return false; |
| 427 } | 436 } |
| 428 ASSERT(result.IsReceivePort()); | 437 ASSERT(result.IsReceivePort()); |
| 429 const ReceivePort& rp = ReceivePort::Cast(result); | 438 const ReceivePort& rp = ReceivePort::Cast(result); |
| 430 ServiceIsolate::SetLoadPort(rp.Id()); | 439 ServiceIsolate::SetLoadPort(rp.Id()); |
| 440 return false; |
| 431 } | 441 } |
| 432 }; | 442 }; |
| 433 | 443 |
| 434 | 444 |
| 435 void ServiceIsolate::Run() { | 445 void ServiceIsolate::Run() { |
| 436 ASSERT(monitor_ == NULL); | 446 ASSERT(monitor_ == NULL); |
| 437 monitor_ = new Monitor(); | 447 monitor_ = new Monitor(); |
| 438 ASSERT(monitor_ != NULL); | 448 ASSERT(monitor_ != NULL); |
| 439 // Grab the isolate create callback here to avoid race conditions with tests | 449 // Grab the isolate create callback here to avoid race conditions with tests |
| 440 // that change this after Dart_Initialize returns. | 450 // that change this after Dart_Initialize returns. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 455 { | 465 { |
| 456 MonitorLocker ml(monitor_); | 466 MonitorLocker ml(monitor_); |
| 457 while (shutting_down_) { | 467 while (shutting_down_) { |
| 458 ml.Wait(); | 468 ml.Wait(); |
| 459 } | 469 } |
| 460 } | 470 } |
| 461 } | 471 } |
| 462 | 472 |
| 463 | 473 |
| 464 void ServiceIsolate::Shutdown() { | 474 void ServiceIsolate::Shutdown() { |
| 465 if (!IsRunning()) { | 475 if (IsRunning()) { |
| 476 { |
| 477 MonitorLocker ml(monitor_); |
| 478 shutting_down_ = true; |
| 479 } |
| 480 SendServiceExitMessage(); |
| 481 { |
| 482 MonitorLocker ml(monitor_); |
| 483 while (shutting_down_ && (port_ != ILLEGAL_PORT)) { |
| 484 ml.Wait(); |
| 485 } |
| 486 } |
| 487 } else { |
| 466 if (isolate_ != NULL) { | 488 if (isolate_ != NULL) { |
| 467 // TODO(johnmccutchan,turnidge) When it is possible to properly create | 489 // TODO(johnmccutchan,turnidge) When it is possible to properly create |
| 468 // the VMService object and set up its shutdown handler in the service | 490 // the VMService object and set up its shutdown handler in the service |
| 469 // isolate's main() function, this case will no longer be possible and | 491 // isolate's main() function, this case will no longer be possible and |
| 470 // can be removed. | 492 // can be removed. |
| 471 KillServiceIsolate(); | 493 KillServiceIsolate(); |
| 472 } | 494 } |
| 473 return; | |
| 474 } | |
| 475 { | |
| 476 MonitorLocker ml(monitor_); | |
| 477 shutting_down_ = true; | |
| 478 } | |
| 479 SendServiceExitMessage(); | |
| 480 { | |
| 481 MonitorLocker ml(monitor_); | |
| 482 while (shutting_down_ && (port_ != ILLEGAL_PORT)) { | |
| 483 ml.Wait(); | |
| 484 } | |
| 485 } | 495 } |
| 486 if (server_address_ != NULL) { | 496 if (server_address_ != NULL) { |
| 487 free(server_address_); | 497 free(server_address_); |
| 488 server_address_ = NULL; | 498 server_address_ = NULL; |
| 489 } | 499 } |
| 490 } | 500 } |
| 491 | 501 |
| 492 | 502 |
| 493 void ServiceIsolate::BootVmServiceLibrary() { | 503 void ServiceIsolate::BootVmServiceLibrary() { |
| 494 const Library& vmservice_library = | 504 const Library& vmservice_library = |
| (...skipping 10 matching lines...) Expand all Loading... |
| 505 ASSERT(!result.IsNull()); | 515 ASSERT(!result.IsNull()); |
| 506 Dart_Port port = ILLEGAL_PORT; | 516 Dart_Port port = ILLEGAL_PORT; |
| 507 if (result.IsReceivePort()) { | 517 if (result.IsReceivePort()) { |
| 508 port = ReceivePort::Cast(result).Id(); | 518 port = ReceivePort::Cast(result).Id(); |
| 509 } | 519 } |
| 510 ASSERT(port != ILLEGAL_PORT); | 520 ASSERT(port != ILLEGAL_PORT); |
| 511 ServiceIsolate::SetServicePort(port); | 521 ServiceIsolate::SetServicePort(port); |
| 512 } | 522 } |
| 513 | 523 |
| 514 } // namespace dart | 524 } // namespace dart |
| OLD | NEW |