Home > Mobile >  Using V8 Isolate in separate thread
Using V8 Isolate in separate thread

Time:08-04

I have a program that uses a v8 isolate to execute javascript code. I would like to spawn a separate thread and execute code in the isolate there too. The thread does not need to run in parallel, I am only using the separate thread so I can cancel it from a signal handler on the main thread.

I am currently using pthreads to create the separate thread. Like this:

Isolate *isolate = Isolate::New(params);
int thread_id;
pthread_create(&thread_id, NULL, call, isolate);
pthread_join(thread_id, NULL);

Where call is the following very basic code to test locking the isolate.

void *call(void* vargs) {   
    Isolate *isolate = (thread_args *) vargs;
    try {
        v8::Locker lock(isolate);
        isolate->Enter();
        v8::HandleScope handle_scope(isolate);
        v8::Isolate::Scope scope(isolate);
        /* use isolate exclusively in here */
        isolate->Exit();
    } catch catch (int err) {
        /* log error */
    }
}

The above yields the following stack trace:

#
# Fatal error in ../src/api/api.h, line 409
# Debug check failed: blocks_.empty().
#
#
#
#FailureMessage Object: 0x16b612c88
==== C stack trace ===============================

            0x0000000115378eb0 v8::base::debug::StackTrace::StackTrace()   24
            0x0000000115354f3c v8::platform::(anonymous namespace)::PrintStackTrace()   116
            0x0000000115362d1c V8_Fatal(char const*, int, char const*, ...)   268
            0x0000000115362740 std::__1::enable_if<((!(std::is_function<std::__1::remove_pointer<char>::type>::value)) && (!(std::is_enum<char>::value))) && (has_output_operator<char, v8::base::CheckMessageStream>::value), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>::type v8::base::PrintCheckOperand<char>(char)   0
            0x00000001153f69e4 v8::internal::HandleScopeImplementer::Free()   216
            0x000000011567c02c v8::internal::ThreadManager::FreeThreadResources()   164
            0x000000011567c484 v8::Locker::~Locker()   76
            0x0000000115340ca0 call(void*)   144
            0x000000018f2e626c _pthread_start   148
            0x000000018f2e108c thread_start   8

It looks like the Locker destructor is trying to free resources that haven't been allocated properly. Is there a data structure or method I need to call to ensure these resources a properly allocated when using threads and lockers?

CodePudding user response:

  1. The thread does not need to run in parallel
    You do not need to lock with v8::Locker lock(isolate);

  2. Debug check failed: blocks_.empty().
    You don't seem to enter the isolate v8::Isolate::Scope scope(isolate); after the lock.

void *call(void* vargs) {   
    Isolate *isolate = (thread_args *) vargs;
    try {
        v8::Locker lock(isolate);
        v8::Isolate::Scope scope(isolate);
        /* use isolate exclusively in here */
    } catch catch (int err) {
        /* log error */
    }
    return nullptr;
}

Just tried. Can not reproduce. Works well.

void call(v8::Isolate *isolate) {
    v8::Locker lock(isolate);
    v8::Isolate::Scope scope(isolate);
}

int main(int argc, char *argv[]) {
    auto platform = v8::platform::NewDefaultPlatform();
    v8::V8::InitializePlatform(platform.get());
    v8::V8::Initialize();

    v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
    auto *allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
    v8::Isolate::CreateParams params;
    params.array_buffer_allocator = allocator;

    auto *isolate = v8::Isolate::New(params);
    std::thread thread(call, isolate);
    thread.join();

    isolate->Dispose();
    v8::V8::Dispose();
    v8::V8::DisposePlatform();
}
  • Related