I wrote a multithreaded V8 application where (in the normal case) every thread starts and executes in its own Isolate.
There is one phenomenon I do not understand and which probably is due to my lack of understanding how the global object and some thread local storage mechanism inside of V8 interact.
In the setup phase, a small number of my pthreads create their own Isolate, generate a fresh context and run some Javascript code consisting of function definitions. The function definitions then are available as properties of the global object of that context.
My problem shows up when thread X later uses an Isolate, which had been created by a different thread Y.
In this case obtaining a function from the global object of the active context and CALLING it WORKS nicely, basically using code similar to the following:
this->iso->Enter();
HandleScope handleScope;
TryCatch tryCatch;
Handle<Value> value = this->context->Global()->Get(String::New("nameOfFunction"));
Handle<Function>::Cast(value)->Call (this->context->Global(), 1, args);
However, listing the properties of the global object FAILS. When iterating the global object, it still find a property the key of which is the expected name of the Javascript function and the Local<Value> returned for that key IsFunction() - however attempting a conversion to a string value (which should contain the text of the Javascript function) FAILS. In below code, *utf is zero and tryCatch contains an exception without any useful information.
The code however performs as expected if it is executed by the SAME pthread in which the Isolate, the Context and the global object was constructed and the Javascript code had been run.
EXECUTION works for DIFFERENT pthreads, but stringification of the function DOES NOT.
I suspect there is some information which gets stored in a TLS whereas it probably should not ?!?
Please help.
The scond case is using code similar to:
this->iso->Enter();
HandleScope handle_scope;
TryCatch tryCatch;
Handle<Object> obj = this->context->Global();
const Handle<Array> props = obj->GetPropertyNames();
const uint32_t length = props->Length();
for (uint32_t i=0 ; i<length ; ++i) {
const Local<Value> key = props->Get(i);
const Local<Value> value = obj->Get(key);
string keys = V8ValueToString(key);
Local<String> locas = value->ToString();
String::Utf8Value utf (locas);
if ( *utf == 0 ) { printf ("Error"); }
else {printf ("%s",*utf);}
}
if (tryCatch.HasCaught()) {....}