| Index: runtime/vm/isolate.cc
|
| diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
|
| index 1635611db09dbe7b63b428fd87eedaf380e34d54..3b4de3be5e81355abae387dcf5b6c0f85086a7f0 100644
|
| --- a/runtime/vm/isolate.cc
|
| +++ b/runtime/vm/isolate.cc
|
| @@ -792,7 +792,9 @@ Isolate::Isolate(const Dart_IsolateFlags& api_flags)
|
| pause_loop_monitor_(NULL),
|
| cha_invalidation_gen_(kInvalidGen),
|
| field_invalidation_gen_(kInvalidGen),
|
| - prefix_invalidation_gen_(kInvalidGen) {
|
| + prefix_invalidation_gen_(kInvalidGen),
|
| + spawn_count_monitor_(new Monitor()),
|
| + spawn_count_(0) {
|
| flags_.CopyFrom(api_flags);
|
| // TODO(asiva): A Thread is not available here, need to figure out
|
| // how the vm_tag (kEmbedderTagId) can be set, these tags need to
|
| @@ -824,6 +826,8 @@ Isolate::~Isolate() {
|
| object_id_ring_ = NULL;
|
| delete pause_loop_monitor_;
|
| pause_loop_monitor_ = NULL;
|
| + ASSERT(spawn_count_ == 0);
|
| + delete spawn_count_monitor_;
|
| if (compiler_stats_ != NULL) {
|
| delete compiler_stats_;
|
| compiler_stats_ = NULL;
|
| @@ -1399,6 +1403,9 @@ static MessageHandler::MessageStatus RunIsolate(uword parameter) {
|
|
|
| static void ShutdownIsolate(uword parameter) {
|
| Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
|
| + // We must wait for any outstanding spawn calls to complete before
|
| + // running the shutdown callback.
|
| + isolate->WaitForOutstandingSpawns();
|
| {
|
| // Print the error if there is one. This may execute dart code to
|
| // print the exception object, so we need to use a StartIsolateScope.
|
| @@ -2304,6 +2311,20 @@ void Isolate::KillIfExists(Isolate* isolate, LibMsgId msg_id) {
|
| }
|
|
|
|
|
| +void Isolate::IncrementSpawnCount() {
|
| + MonitorLocker ml(spawn_count_monitor_);
|
| + spawn_count_++;
|
| +}
|
| +
|
| +
|
| +void Isolate::WaitForOutstandingSpawns() {
|
| + MonitorLocker ml(spawn_count_monitor_);
|
| + while (spawn_count_ > 0) {
|
| + ml.Wait();
|
| + }
|
| +}
|
| +
|
| +
|
| static RawInstance* DeserializeObject(Thread* thread,
|
| uint8_t* obj_data,
|
| intptr_t obj_len) {
|
| @@ -2333,6 +2354,8 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
|
| void* init_data,
|
| const Function& func,
|
| const Instance& message,
|
| + Monitor* spawn_count_monitor,
|
| + intptr_t* spawn_count,
|
| bool paused,
|
| bool errors_are_fatal,
|
| Dart_Port on_exit_port,
|
| @@ -2353,6 +2376,8 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
|
| serialized_args_len_(0),
|
| serialized_message_(NULL),
|
| serialized_message_len_(0),
|
| + spawn_count_monitor_(spawn_count_monitor),
|
| + spawn_count_(spawn_count),
|
| isolate_flags_(),
|
| paused_(paused),
|
| errors_are_fatal_(errors_are_fatal) {
|
| @@ -2384,6 +2409,8 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
|
| const char** package_map,
|
| const Instance& args,
|
| const Instance& message,
|
| + Monitor* spawn_count_monitor,
|
| + intptr_t* spawn_count,
|
| bool paused,
|
| bool errors_are_fatal,
|
| Dart_Port on_exit_port,
|
| @@ -2404,6 +2431,8 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
|
| serialized_args_len_(0),
|
| serialized_message_(NULL),
|
| serialized_message_len_(0),
|
| + spawn_count_monitor_(spawn_count_monitor),
|
| + spawn_count_(spawn_count),
|
| isolate_flags_(),
|
| paused_(paused),
|
| errors_are_fatal_(errors_are_fatal) {
|
| @@ -2521,4 +2550,13 @@ RawInstance* IsolateSpawnState::BuildMessage(Thread* thread) {
|
| }
|
|
|
|
|
| +void IsolateSpawnState::DecrementSpawnCount() {
|
| + ASSERT(spawn_count_monitor_ != NULL);
|
| + ASSERT(spawn_count_ != NULL);
|
| + MonitorLocker ml(spawn_count_monitor_);
|
| + ASSERT(*spawn_count_ > 0);
|
| + *spawn_count_ = *spawn_count_ - 1;
|
| + ml.Notify();
|
| +}
|
| +
|
| } // namespace dart
|
|
|