Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
isolates: add process.tid property, pass args to isolate
Browse files Browse the repository at this point in the history
  • Loading branch information
bnoordhuis committed Dec 9, 2011
1 parent 2821c8b commit 274ea91
Showing 1 changed file with 103 additions and 18 deletions.
121 changes: 103 additions & 18 deletions src/node.cc
Expand Up @@ -134,6 +134,8 @@ extern char **environ;

namespace node {

#define TICK_TIME(n) tick_times[(tick_time_head - (n)) % RPM_SAMPLES]

static int option_end_index;
static unsigned long max_stack_size;
static unsigned short debug_port = 5858;
Expand All @@ -142,11 +144,14 @@ static bool use_debug_agent;
static const char* eval_string;
static bool print_eval;

static void CheckStatus(uv_timer_t* watcher, int status);
static unsigned long NewThreadId();

void StartThread(unsigned long thread_id,
Isolate* isolate,
int argc,
char** argv);

#define TICK_TIME(n) tick_times[(tick_time_head - (n)) % RPM_SAMPLES]

static void CheckStatus(uv_timer_t* watcher, int status);

static void StartGCTimer () {
if (!uv_is_active((uv_handle_t*) &gc_timer)) {
Expand Down Expand Up @@ -1819,9 +1824,71 @@ static Handle<Value> Binding(const Arguments& args) {
}


static struct {
uv_mutex_t lock_;
unsigned long counter_;
} thread_id_generator_;


static unsigned long NewThreadId() {
unsigned long thread_id;

uv_mutex_lock(&thread_id_generator_.lock_);
thread_id = ++thread_id_generator_.counter_;
uv_mutex_unlock(&thread_id_generator_.lock_);

return thread_id;
}


struct ThreadInfo {
unsigned long thread_id_;
uv_thread_t thread_;
char** argv_;
int argc_;

ThreadInfo(int argc, char** argv) {
argc_ = argc;
argv_ = new char*[argc_ + 1];

for (int i = 0; i < argc_; ++i) {
size_t size = 1 + strlen(argv[i]);
argv_[i] = new char[size];
memcpy(argv_[i], argv[i], size);
}
argv_[argc_] = NULL;
}

ThreadInfo(Handle<Array> args) {
argc_ = args->Length();
argv_ = new char*[argc_ + 1];

for (int i = 0; i < argc_; ++i) {
String::Utf8Value str(args->Get(i));
size_t size = 1 + strlen(*str);
argv_[i] = new char[size];
memcpy(argv_[i], *str, size);
}
argv_[argc_] = NULL;
}

~ThreadInfo() {
for (int i = 0; i < argc_; ++i) {
delete[] argv_[i];
}
delete argv_;
}
};


static void RunIsolate(void* arg) {
ThreadInfo* ti = reinterpret_cast<ThreadInfo*>(arg);

uv_loop_t* loop = uv_loop_new();
Isolate* isolate = Isolate::New(loop);

StartThread(ti->thread_id_, isolate, ti->argc_, ti->argv_);
delete ti;
}


Expand All @@ -1831,17 +1898,25 @@ static char magic_isolate_cookie_[] = "magic isolate cookie";
static Handle<Value> NewIsolate(const Arguments& args) {
HandleScope scope;

uv_thread_t* tid = new uv_thread_t;
assert(args[0]->IsArray());

Local<Array> argv = args[0].As<Array>();
assert(argv->Length() >= 2);

ThreadInfo* ti = new ThreadInfo(argv);
ti->thread_id_ = NewThreadId();

if (uv_thread_create(tid, RunIsolate, NULL))
if (uv_thread_create(&ti->thread_, RunIsolate, ti)) {
delete ti;
return Null();
}

Local<ObjectTemplate> tpl = ObjectTemplate::New();
tpl->SetInternalFieldCount(2);

Local<Object> obj = tpl->NewInstance();
obj->SetPointerInInternalField(0, magic_isolate_cookie_);
obj->SetPointerInInternalField(1, tid);
obj->SetPointerInInternalField(1, ti);

return scope.Close(obj);
}
Expand All @@ -1856,9 +1931,10 @@ static Handle<Value> JoinIsolate(const Arguments& args) {
assert(obj->InternalFieldCount() == 2);
assert(obj->GetPointerFromInternalField(0) == magic_isolate_cookie_);

uv_thread_t* tid = (uv_thread_t*) obj->GetPointerFromInternalField(1);
ThreadInfo* ti = reinterpret_cast<ThreadInfo*>(
obj->GetPointerFromInternalField(1));

if (uv_thread_join(tid))
if (uv_thread_join(&ti->thread_))
return False(); // error
else
return True(); // ok
Expand Down Expand Up @@ -2009,7 +2085,6 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {

process = Persistent<Object>::New(process_template->GetFunction()->NewInstance());


process->SetAccessor(String::New("title"),
ProcessTitleGetter,
ProcessTitleSetter);
Expand Down Expand Up @@ -2594,9 +2669,17 @@ void EmitExit(v8::Handle<v8::Object> process_l) {
}


void StartThread(Isolate* isolate, int argc, char** argv) {
uv_loop_t* loop = isolate->GetLoop();
// Create a new isolate with node::Isolate::New() before you call this function
void StartThread(unsigned long thread_id,
Isolate* isolate,
int argc,
char** argv) {
HandleScope scope;

v8::Isolate::Scope isolate_scope(isolate->GetV8Isolate());
v8::Context::Scope context_scope(isolate->GetV8Context());

uv_loop_t* loop = isolate->GetLoop();
uv_prepare_init(loop, &prepare_tick_watcher);
uv_prepare_start(&prepare_tick_watcher, PrepareTick);
uv_unref(loop);
Expand Down Expand Up @@ -2648,7 +2731,12 @@ void StartThread(Isolate* isolate, int argc, char** argv) {
}

Handle<Object> process_l = SetupProcessObject(argc, argv);
v8_typed_array::AttachBindings(v8::Context::GetCurrent()->Global());

process_l->Set(String::NewSymbol("tid"),
Integer::NewFromUnsigned(thread_id));

// FIXME crashes with "CHECK(heap->isolate() == Isolate::Current()) failed"
//v8_typed_array::AttachBindings(v8::Context::GetCurrent()->Global());

// Create all the objects, load modules, do everything.
// so your next reading stop should be node::Load()!
Expand All @@ -2666,24 +2754,21 @@ void StartThread(Isolate* isolate, int argc, char** argv) {


int Start(int argc, char *argv[]) {
if (uv_mutex_init(&thread_id_generator_.lock_)) abort();

// This needs to run *before* V8::Initialize()
argv = ProcessInit(argc, argv);

v8::V8::Initialize();
v8::HandleScope handle_scope;

// Create the one and only Context.
Persistent<v8::Context> context = v8::Context::New();
v8::Context::Scope context_scope(context);

// Create the main node::Isolate object
Isolate* isolate = Isolate::New(uv_default_loop());
StartThread(isolate, argc, argv);
StartThread(NewThreadId(), isolate, argc, argv);
isolate->Dispose();

#ifndef NDEBUG
// Clean up.
context.Dispose();
V8::Dispose();
#endif // NDEBUG

Expand Down

0 comments on commit 274ea91

Please sign in to comment.