| Index: runtime/lib/isolate.cc
|
| ===================================================================
|
| --- runtime/lib/isolate.cc (revision 39634)
|
| +++ runtime/lib/isolate.cc (working copy)
|
| @@ -2,7 +2,6 @@
|
| // for details. All rights reserved. Use of this source code is governed by a
|
| // BSD-style license that can be found in the LICENSE file.
|
|
|
| -#include "include/dart_native_api.h"
|
| #include "platform/assert.h"
|
| #include "vm/bootstrap_natives.h"
|
| #include "vm/class_finalizer.h"
|
| @@ -96,6 +95,13 @@
|
| }
|
|
|
|
|
| +static void ThrowIsolateSpawnException(const String& message) {
|
| + const Array& args = Array::Handle(Array::New(1));
|
| + args.SetAt(0, message);
|
| + Exceptions::ThrowByType(Exceptions::kIsolateSpawn, args);
|
| +}
|
| +
|
| +
|
| static bool CanonicalizeUri(Isolate* isolate,
|
| const Library& library,
|
| const String& uri,
|
| @@ -133,62 +139,60 @@
|
| }
|
|
|
|
|
| -class SpawnIsolateTask : public ThreadPool::Task {
|
| - public:
|
| - explicit SpawnIsolateTask(IsolateSpawnState* state)
|
| - : state_(state) {
|
| +static bool CreateIsolate(Isolate* parent_isolate,
|
| + IsolateSpawnState* state,
|
| + char** error) {
|
| + Dart_IsolateCreateCallback callback = Isolate::CreateCallback();
|
| + if (callback == NULL) {
|
| + *error = strdup("Null callback specified for isolate creation\n");
|
| + Isolate::SetCurrent(parent_isolate);
|
| + return false;
|
| }
|
|
|
| - virtual void Run() {
|
| - // Create a new isolate.
|
| - char* error = NULL;
|
| - Dart_IsolateCreateCallback callback = Isolate::CreateCallback();
|
| - if (callback == NULL) {
|
| - ReportError(
|
| - "Isolate spawn is not supported by this Dart implementation.\n");
|
| - delete state_;
|
| - return;
|
| - }
|
| + void* init_data = parent_isolate->init_callback_data();
|
| + Isolate* child_isolate = reinterpret_cast<Isolate*>(
|
| + (callback)(state->script_url(),
|
| + state->function_name(),
|
| + init_data,
|
| + error));
|
| + if (child_isolate == NULL) {
|
| + Isolate::SetCurrent(parent_isolate);
|
| + return false;
|
| + }
|
| + state->set_isolate(reinterpret_cast<Isolate*>(child_isolate));
|
|
|
| - Isolate* isolate = reinterpret_cast<Isolate*>(
|
| - (callback)(state_->script_url(),
|
| - state_->function_name(),
|
| - state_->init_data(),
|
| - &error));
|
| - if (isolate == NULL) {
|
| - // We were unable to create the child isolate. Report the error
|
| - // back to the parent isolate.
|
| - ReportError(error);
|
| - delete state_;
|
| - return;
|
| - }
|
| + Isolate::SetCurrent(parent_isolate);
|
| + return true;
|
| +}
|
|
|
| - MutexLocker ml(isolate->mutex());
|
| - state_->set_isolate(reinterpret_cast<Isolate*>(isolate));
|
| - isolate->set_spawn_state(state_);
|
| - if (isolate->is_runnable()) {
|
| - // Start the new isolate if it has been marked as runnable.
|
| - isolate->Run();
|
| - }
|
| - }
|
|
|
| - private:
|
| - void ReportError(const char* error) {
|
| - Dart_CObject error_cobj;
|
| - error_cobj.type = Dart_CObject_kString;
|
| - error_cobj.value.as_string = const_cast<char*>(error);
|
| - if (!Dart_PostCObject(state_->parent_port(), &error_cobj)) {
|
| - // Perhaps the parent isolate died or closed the port before we
|
| - // could report the error. Ignore.
|
| - }
|
| +static RawObject* Spawn(Isolate* parent_isolate,
|
| + IsolateSpawnState* state) {
|
| + // Create a new isolate.
|
| + char* error = NULL;
|
| + if (!CreateIsolate(parent_isolate, state, &error)) {
|
| + delete state;
|
| + const String& msg = String::Handle(String::New(error));
|
| + free(error);
|
| + ThrowIsolateSpawnException(msg);
|
| }
|
|
|
| - IsolateSpawnState* state_;
|
| + // Create a SendPort for the new isolate.
|
| + Isolate* spawned_isolate = state->isolate();
|
| + const SendPort& port = SendPort::Handle(
|
| + SendPort::New(spawned_isolate->main_port()));
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(SpawnIsolateTask);
|
| -};
|
| + // Start the new isolate if it is already marked as runnable.
|
| + MutexLocker ml(spawned_isolate->mutex());
|
| + spawned_isolate->set_spawn_state(state);
|
| + if (spawned_isolate->is_runnable()) {
|
| + spawned_isolate->Run();
|
| + }
|
|
|
| + return port.raw();
|
| +}
|
|
|
| +
|
| DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 3) {
|
| GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
|
| GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(1));
|
| @@ -202,11 +206,7 @@
|
| ctx = Closure::context(closure);
|
| ASSERT(ctx.num_variables() == 0);
|
| #endif
|
| - Dart::thread_pool()->Run(new SpawnIsolateTask(
|
| - new IsolateSpawnState(port.Id(),
|
| - isolate->init_callback_data(),
|
| - func, message)));
|
| - return Object::null();
|
| + return Spawn(isolate, new IsolateSpawnState(port.Id(), func, message));
|
| }
|
| }
|
| const String& msg = String::Handle(String::New(
|
| @@ -229,18 +229,12 @@
|
| Library::Handle(arguments->isolate()->object_store()->root_library());
|
| if (!CanonicalizeUri(arguments->isolate(), root_lib, uri,
|
| &canonical_uri, &error)) {
|
| - const String& message = String::Handle(String::New(error));
|
| - const Array& args = Array::Handle(Array::New(1));
|
| - args.SetAt(0, message);
|
| - Exceptions::ThrowByType(Exceptions::kIsolateSpawn, args);
|
| + const String& msg = String::Handle(String::New(error));
|
| + ThrowIsolateSpawnException(msg);
|
| }
|
|
|
| - Dart::thread_pool()->Run(new SpawnIsolateTask(
|
| - new IsolateSpawnState(port.Id(),
|
| - isolate->init_callback_data(),
|
| - canonical_uri,
|
| - args, message)));
|
| - return Object::null();
|
| + return Spawn(isolate, new IsolateSpawnState(port.Id(), canonical_uri,
|
| + args, message));
|
| }
|
|
|
|
|
|
|