現在V8で実験中です。あるスレッドで(おそらく長時間実行される)javascriptを実行し、別のスレッドから自由に「優雅に」実行を終了できるようにしたいと考えています。
ロッカーの概念と TerminateExecution の使用法をテストするために、次の簡単なスニペットを作成しました。
void breaker( Isolate* isolate, int tid ) {
getchar(); //wait for keyboard input on stdin
std::cout << "Breaking V8 execution" << std::endl;
v8::Locker locker( isolate ); //lock the isolate
v8::V8::TerminateExecution( tid ); //and terminate it
}
int main( int argc, char **argv ) {
if( argc != 2 ) {
std::cout << "No script name given" << std::endl;
return 1;
}
Isolate* isolate = Isolate::New(); //create a new isolate
Isolate::Scope isolateScope( isolate ); //enter it
v8::Locker locker( isolate ); //lock the isolate
v8::Locker::StartPreemption( 100 ); //and start preemption
v8::HandleScope handle_scope( isolate ); //open a new handle scope
/*** inject a console object into the global context ***/
v8::Handle<v8::ObjectTemplate> globalTemplate = v8::ObjectTemplate::New();
Handle<Context> context = Context::New( NULL, globalTemplate );
v8::Context::Scope context_scope( context );
Console* console = new Console;
Handle<Object> jsConsole = wrap_console( isolate, console );
expose_property( jsConsole, String::New( "log" ), InvocationCallback( Console::consoleLog ) );
context->Global()->Set( String::New( "console" ), jsConsole, v8::ReadOnly );
/*******************************************************/
//read a javascript file supplied via console
std::string contents = read_file( argv[1] );
v8::Handle<v8::String> js = v8::String::New( contents.c_str() );
v8::TryCatch try_catch;
v8::Handle<v8::Script> script = v8::Script::Compile( js );
if( script.IsEmpty() ) {
report_exception( try_catch );
}
//start the breaker thread
std::thread th( breaker, isolate, v8::V8::GetCurrentThreadId() );
log_info( "running script" );
script->Run();
log_info( "Script execution finished" );
th.join();
}
ただし、terminateExecution()
呼び出し時に常にセグメンテーション違反が発生します。ここで何が間違っていますか?
助けてくれてありがとう