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

Side by Side Diff: runtime/vm/isolate.cc

Issue 1560853002: Fix Shutdown race. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 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
« no previous file with comments | « runtime/vm/isolate.h ('k') | runtime/vm/service_isolate.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/isolate.h" 5 #include "vm/isolate.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "include/dart_native_api.h" 8 #include "include/dart_native_api.h"
9 #include "platform/assert.h" 9 #include "platform/assert.h"
10 #include "platform/text_buffer.h" 10 #include "platform/text_buffer.h"
(...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 background_compiler_(NULL), 785 background_compiler_(NULL),
786 pending_service_extension_calls_(GrowableObjectArray::null()), 786 pending_service_extension_calls_(GrowableObjectArray::null()),
787 registered_service_extension_handlers_(GrowableObjectArray::null()), 787 registered_service_extension_handlers_(GrowableObjectArray::null()),
788 metrics_list_head_(NULL), 788 metrics_list_head_(NULL),
789 compilation_allowed_(true), 789 compilation_allowed_(true),
790 all_classes_finalized_(false), 790 all_classes_finalized_(false),
791 next_(NULL), 791 next_(NULL),
792 pause_loop_monitor_(NULL), 792 pause_loop_monitor_(NULL),
793 cha_invalidation_gen_(kInvalidGen), 793 cha_invalidation_gen_(kInvalidGen),
794 field_invalidation_gen_(kInvalidGen), 794 field_invalidation_gen_(kInvalidGen),
795 prefix_invalidation_gen_(kInvalidGen) { 795 prefix_invalidation_gen_(kInvalidGen),
796 spawn_count_monitor_(new Monitor()),
797 spawn_count_(0) {
796 flags_.CopyFrom(api_flags); 798 flags_.CopyFrom(api_flags);
797 // TODO(asiva): A Thread is not available here, need to figure out 799 // TODO(asiva): A Thread is not available here, need to figure out
798 // how the vm_tag (kEmbedderTagId) can be set, these tags need to 800 // how the vm_tag (kEmbedderTagId) can be set, these tags need to
799 // move to the OSThread structure. 801 // move to the OSThread structure.
800 set_user_tag(UserTags::kDefaultUserTag); 802 set_user_tag(UserTags::kDefaultUserTag);
801 } 803 }
802 804
803 #undef REUSABLE_HANDLE_SCOPE_INIT 805 #undef REUSABLE_HANDLE_SCOPE_INIT
804 #undef REUSABLE_HANDLE_INITIALIZERS 806 #undef REUSABLE_HANDLE_INITIALIZERS
805 807
(...skipping 11 matching lines...) Expand all
817 delete mutex_; 819 delete mutex_;
818 mutex_ = NULL; // Fail fast if interrupts are scheduled on a dead isolate. 820 mutex_ = NULL; // Fail fast if interrupts are scheduled on a dead isolate.
819 delete message_handler_; 821 delete message_handler_;
820 message_handler_ = NULL; // Fail fast if we send messages to a dead isolate. 822 message_handler_ = NULL; // Fail fast if we send messages to a dead isolate.
821 ASSERT(deopt_context_ == NULL); // No deopt in progress when isolate deleted. 823 ASSERT(deopt_context_ == NULL); // No deopt in progress when isolate deleted.
822 delete spawn_state_; 824 delete spawn_state_;
823 delete object_id_ring_; 825 delete object_id_ring_;
824 object_id_ring_ = NULL; 826 object_id_ring_ = NULL;
825 delete pause_loop_monitor_; 827 delete pause_loop_monitor_;
826 pause_loop_monitor_ = NULL; 828 pause_loop_monitor_ = NULL;
829 ASSERT(spawn_count_ == 0);
830 delete spawn_count_monitor_;
827 if (compiler_stats_ != NULL) { 831 if (compiler_stats_ != NULL) {
828 delete compiler_stats_; 832 delete compiler_stats_;
829 compiler_stats_ = NULL; 833 compiler_stats_ = NULL;
830 } 834 }
831 delete thread_registry_; 835 delete thread_registry_;
832 } 836 }
833 837
834 838
835 #if defined(DEBUG) 839 #if defined(DEBUG)
836 bool Isolate::IsIsolateOf(Thread* thread) { 840 bool Isolate::IsIsolateOf(Thread* thread) {
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after
1392 if (result.IsError()) { 1396 if (result.IsError()) {
1393 return StoreError(isolate, Error::Cast(result)); 1397 return StoreError(isolate, Error::Cast(result));
1394 } 1398 }
1395 } 1399 }
1396 return MessageHandler::kOK; 1400 return MessageHandler::kOK;
1397 } 1401 }
1398 1402
1399 1403
1400 static void ShutdownIsolate(uword parameter) { 1404 static void ShutdownIsolate(uword parameter) {
1401 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); 1405 Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
1406 // We must wait for any outstanding spawn calls to complete before
1407 // running the shutdown callback.
1408 isolate->WaitForOutstandingSpawns();
1402 { 1409 {
1403 // Print the error if there is one. This may execute dart code to 1410 // Print the error if there is one. This may execute dart code to
1404 // print the exception object, so we need to use a StartIsolateScope. 1411 // print the exception object, so we need to use a StartIsolateScope.
1405 StartIsolateScope start_scope(isolate); 1412 StartIsolateScope start_scope(isolate);
1406 Thread* thread = Thread::Current(); 1413 Thread* thread = Thread::Current();
1407 ASSERT(thread->isolate() == isolate); 1414 ASSERT(thread->isolate() == isolate);
1408 StackZone zone(thread); 1415 StackZone zone(thread);
1409 HandleScope handle_scope(thread); 1416 HandleScope handle_scope(thread);
1410 const Error& error = Error::Handle(isolate->object_store()->sticky_error()); 1417 const Error& error = Error::Handle(isolate->object_store()->sticky_error());
1411 if (!error.IsNull() && !error.IsUnwindError()) { 1418 if (!error.IsNull() && !error.IsUnwindError()) {
(...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after
2297 VisitIsolates(&visitor); 2304 VisitIsolates(&visitor);
2298 } 2305 }
2299 2306
2300 2307
2301 void Isolate::KillIfExists(Isolate* isolate, LibMsgId msg_id) { 2308 void Isolate::KillIfExists(Isolate* isolate, LibMsgId msg_id) {
2302 IsolateKillerVisitor visitor(isolate, msg_id); 2309 IsolateKillerVisitor visitor(isolate, msg_id);
2303 VisitIsolates(&visitor); 2310 VisitIsolates(&visitor);
2304 } 2311 }
2305 2312
2306 2313
2314 void Isolate::IncrementSpawnCount() {
2315 MonitorLocker ml(spawn_count_monitor_);
2316 spawn_count_++;
2317 }
2318
2319
2320 void Isolate::WaitForOutstandingSpawns() {
2321 MonitorLocker ml(spawn_count_monitor_);
2322 while (spawn_count_ > 0) {
2323 ml.Wait();
2324 }
2325 }
2326
2327
2307 static RawInstance* DeserializeObject(Thread* thread, 2328 static RawInstance* DeserializeObject(Thread* thread,
2308 uint8_t* obj_data, 2329 uint8_t* obj_data,
2309 intptr_t obj_len) { 2330 intptr_t obj_len) {
2310 if (obj_data == NULL) { 2331 if (obj_data == NULL) {
2311 return Instance::null(); 2332 return Instance::null();
2312 } 2333 }
2313 MessageSnapshotReader reader(obj_data, obj_len, thread); 2334 MessageSnapshotReader reader(obj_data, obj_len, thread);
2314 Zone* zone = thread->zone(); 2335 Zone* zone = thread->zone();
2315 const Object& obj = Object::Handle(zone, reader.ReadObject()); 2336 const Object& obj = Object::Handle(zone, reader.ReadObject());
2316 ASSERT(!obj.IsError()); 2337 ASSERT(!obj.IsError());
2317 Instance& instance = Instance::Handle(zone); 2338 Instance& instance = Instance::Handle(zone);
2318 instance ^= obj.raw(); // Can't use Instance::Cast because may be null. 2339 instance ^= obj.raw(); // Can't use Instance::Cast because may be null.
2319 return instance.raw(); 2340 return instance.raw();
2320 } 2341 }
2321 2342
2322 2343
2323 static const char* NewConstChar(const char* chars) { 2344 static const char* NewConstChar(const char* chars) {
2324 size_t len = strlen(chars); 2345 size_t len = strlen(chars);
2325 char* mem = new char[len + 1]; 2346 char* mem = new char[len + 1];
2326 memmove(mem, chars, len + 1); 2347 memmove(mem, chars, len + 1);
2327 return mem; 2348 return mem;
2328 } 2349 }
2329 2350
2330 2351
2331 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port, 2352 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
2332 Dart_Port origin_id, 2353 Dart_Port origin_id,
2333 void* init_data, 2354 void* init_data,
2334 const Function& func, 2355 const Function& func,
2335 const Instance& message, 2356 const Instance& message,
2357 Monitor* spawn_count_monitor,
2358 intptr_t* spawn_count,
2336 bool paused, 2359 bool paused,
2337 bool errors_are_fatal, 2360 bool errors_are_fatal,
2338 Dart_Port on_exit_port, 2361 Dart_Port on_exit_port,
2339 Dart_Port on_error_port) 2362 Dart_Port on_error_port)
2340 : isolate_(NULL), 2363 : isolate_(NULL),
2341 parent_port_(parent_port), 2364 parent_port_(parent_port),
2342 origin_id_(origin_id), 2365 origin_id_(origin_id),
2343 init_data_(init_data), 2366 init_data_(init_data),
2344 on_exit_port_(on_exit_port), 2367 on_exit_port_(on_exit_port),
2345 on_error_port_(on_error_port), 2368 on_error_port_(on_error_port),
2346 script_url_(NULL), 2369 script_url_(NULL),
2347 package_root_(NULL), 2370 package_root_(NULL),
2348 package_map_(NULL), 2371 package_map_(NULL),
2349 library_url_(NULL), 2372 library_url_(NULL),
2350 class_name_(NULL), 2373 class_name_(NULL),
2351 function_name_(NULL), 2374 function_name_(NULL),
2352 serialized_args_(NULL), 2375 serialized_args_(NULL),
2353 serialized_args_len_(0), 2376 serialized_args_len_(0),
2354 serialized_message_(NULL), 2377 serialized_message_(NULL),
2355 serialized_message_len_(0), 2378 serialized_message_len_(0),
2379 spawn_count_monitor_(spawn_count_monitor),
2380 spawn_count_(spawn_count),
2356 isolate_flags_(), 2381 isolate_flags_(),
2357 paused_(paused), 2382 paused_(paused),
2358 errors_are_fatal_(errors_are_fatal) { 2383 errors_are_fatal_(errors_are_fatal) {
2359 const Class& cls = Class::Handle(func.Owner()); 2384 const Class& cls = Class::Handle(func.Owner());
2360 const Library& lib = Library::Handle(cls.library()); 2385 const Library& lib = Library::Handle(cls.library());
2361 const String& lib_url = String::Handle(lib.url()); 2386 const String& lib_url = String::Handle(lib.url());
2362 library_url_ = NewConstChar(lib_url.ToCString()); 2387 library_url_ = NewConstChar(lib_url.ToCString());
2363 2388
2364 const String& func_name = String::Handle(func.name()); 2389 const String& func_name = String::Handle(func.name());
2365 function_name_ = NewConstChar(func_name.ToCString()); 2390 function_name_ = NewConstChar(func_name.ToCString());
(...skipping 11 matching lines...) Expand all
2377 } 2402 }
2378 2403
2379 2404
2380 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port, 2405 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
2381 void* init_data, 2406 void* init_data,
2382 const char* script_url, 2407 const char* script_url,
2383 const char* package_root, 2408 const char* package_root,
2384 const char** package_map, 2409 const char** package_map,
2385 const Instance& args, 2410 const Instance& args,
2386 const Instance& message, 2411 const Instance& message,
2412 Monitor* spawn_count_monitor,
2413 intptr_t* spawn_count,
2387 bool paused, 2414 bool paused,
2388 bool errors_are_fatal, 2415 bool errors_are_fatal,
2389 Dart_Port on_exit_port, 2416 Dart_Port on_exit_port,
2390 Dart_Port on_error_port) 2417 Dart_Port on_error_port)
2391 : isolate_(NULL), 2418 : isolate_(NULL),
2392 parent_port_(parent_port), 2419 parent_port_(parent_port),
2393 origin_id_(ILLEGAL_PORT), 2420 origin_id_(ILLEGAL_PORT),
2394 init_data_(init_data), 2421 init_data_(init_data),
2395 on_exit_port_(on_exit_port), 2422 on_exit_port_(on_exit_port),
2396 on_error_port_(on_error_port), 2423 on_error_port_(on_error_port),
2397 script_url_(script_url), 2424 script_url_(script_url),
2398 package_root_(package_root), 2425 package_root_(package_root),
2399 package_map_(package_map), 2426 package_map_(package_map),
2400 library_url_(NULL), 2427 library_url_(NULL),
2401 class_name_(NULL), 2428 class_name_(NULL),
2402 function_name_(NULL), 2429 function_name_(NULL),
2403 serialized_args_(NULL), 2430 serialized_args_(NULL),
2404 serialized_args_len_(0), 2431 serialized_args_len_(0),
2405 serialized_message_(NULL), 2432 serialized_message_(NULL),
2406 serialized_message_len_(0), 2433 serialized_message_len_(0),
2434 spawn_count_monitor_(spawn_count_monitor),
2435 spawn_count_(spawn_count),
2407 isolate_flags_(), 2436 isolate_flags_(),
2408 paused_(paused), 2437 paused_(paused),
2409 errors_are_fatal_(errors_are_fatal) { 2438 errors_are_fatal_(errors_are_fatal) {
2410 function_name_ = NewConstChar("main"); 2439 function_name_ = NewConstChar("main");
2411 bool can_send_any_object = false; 2440 bool can_send_any_object = false;
2412 SerializeObject(args, 2441 SerializeObject(args,
2413 &serialized_args_, 2442 &serialized_args_,
2414 &serialized_args_len_, 2443 &serialized_args_len_,
2415 can_send_any_object); 2444 can_send_any_object);
2416 SerializeObject(message, 2445 SerializeObject(message,
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
2514 return DeserializeObject(thread, serialized_args_, serialized_args_len_); 2543 return DeserializeObject(thread, serialized_args_, serialized_args_len_);
2515 } 2544 }
2516 2545
2517 2546
2518 RawInstance* IsolateSpawnState::BuildMessage(Thread* thread) { 2547 RawInstance* IsolateSpawnState::BuildMessage(Thread* thread) {
2519 return DeserializeObject(thread, 2548 return DeserializeObject(thread,
2520 serialized_message_, serialized_message_len_); 2549 serialized_message_, serialized_message_len_);
2521 } 2550 }
2522 2551
2523 2552
2553 void IsolateSpawnState::DecrementSpawnCount() {
2554 ASSERT(spawn_count_monitor_ != NULL);
2555 ASSERT(spawn_count_ != NULL);
2556 MonitorLocker ml(spawn_count_monitor_);
2557 ASSERT(*spawn_count_ > 0);
2558 *spawn_count_ = *spawn_count_ - 1;
2559 ml.Notify();
2560 }
2561
2524 } // namespace dart 2562 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/isolate.h ('k') | runtime/vm/service_isolate.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698