On Sun, Aug 18, 2013 at 4:13 PM, Clemens Cap <[email protected]> wrote: > 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()) {....}
It looks like you're not using a Locker to synchronize access to the Isolate. Create one before calling Isolate::Enter() (or use an Isolate::Scope, same thing except you don't need to call Isolate::Exit().) There is some documentation in include/v8.h that explains the rules around Isolates and Lockers. -- -- v8-users mailing list [email protected] http://groups.google.com/group/v8-users --- You received this message because you are subscribed to the Google Groups "v8-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/groups/opt_out.
