mirror of
https://github.com/rubyjs/therubyracer
synced 2023-03-27 23:21:42 -04:00
support for locking and unlocking v8
This commit is contained in:
parent
276653f830
commit
ec1d910b3d
4 changed files with 119 additions and 0 deletions
|
@ -27,5 +27,6 @@ extern "C" {
|
|||
Stack::Init();
|
||||
Message::Init();
|
||||
TryCatch::Init();
|
||||
Locker::Init();
|
||||
}
|
||||
}
|
77
ext/v8/locker.cc
Normal file
77
ext/v8/locker.cc
Normal file
|
@ -0,0 +1,77 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
void Locker::Init() {
|
||||
ClassBuilder("Locker").
|
||||
defineSingletonMethod("StartPreemption", &StartPreemption).
|
||||
defineSingletonMethod("StopPreemption", &StopPreemption).
|
||||
defineSingletonMethod("IsLocked", &IsLocked).
|
||||
defineSingletonMethod("IsActive", &IsActive);
|
||||
VALUE v8 = rb_define_module("V8");
|
||||
VALUE c = rb_define_module_under(v8, "C");
|
||||
rb_define_singleton_method(c, "Locker", (VALUE (*)(...))&doLock, -1);
|
||||
rb_define_singleton_method(c, "Unlocker",(VALUE (*)(...))&doUnlock, -1);
|
||||
}
|
||||
|
||||
VALUE Locker::StartPreemption(VALUE self, VALUE every_n_ms) {
|
||||
Void(v8::Locker::StartPreemption(NUM2INT(every_n_ms)));
|
||||
}
|
||||
|
||||
VALUE Locker::StopPreemption(VALUE self) {
|
||||
Void(v8::Locker::StopPreemption());
|
||||
}
|
||||
|
||||
VALUE Locker::IsLocked(VALUE self) {
|
||||
return Bool(v8::Locker::IsLocked());
|
||||
}
|
||||
|
||||
VALUE Locker::IsActive(VALUE self) {
|
||||
return Bool(v8::Locker::IsActive());
|
||||
}
|
||||
|
||||
VALUE Locker::doLock(int argc, VALUE* argv, VALUE self) {
|
||||
if (!rb_block_given_p()) {
|
||||
return Qnil;
|
||||
}
|
||||
int state = 0;
|
||||
VALUE code;
|
||||
rb_scan_args(argc,argv,"00&", &code);
|
||||
VALUE result = setupLockAndCall(&state, code);
|
||||
if (state != 0) {
|
||||
rb_jump_tag(state);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
VALUE Locker::setupLockAndCall(int* state, VALUE code) {
|
||||
v8::Locker locker;
|
||||
return rb_protect(&doLockCall, code, state);
|
||||
}
|
||||
|
||||
VALUE Locker::doLockCall(VALUE code) {
|
||||
return rb_funcall(code, rb_intern("call"), 0);
|
||||
}
|
||||
|
||||
VALUE Locker::doUnlock(int argc, VALUE* argv, VALUE self) {
|
||||
if (!rb_block_given_p()) {
|
||||
return Qnil;
|
||||
}
|
||||
int state = 0;
|
||||
VALUE code;
|
||||
rb_scan_args(argc,argv,"00&", &code);
|
||||
VALUE result = setupUnlockAndCall(&state, code);
|
||||
if (state != 0) {
|
||||
rb_jump_tag(state);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
VALUE Locker::setupUnlockAndCall(int* state, VALUE code) {
|
||||
v8::Unlocker unlocker;
|
||||
return rb_protect(&doUnlockCall, code, state);
|
||||
}
|
||||
|
||||
VALUE Locker::doUnlockCall(VALUE code) {
|
||||
return rb_funcall(code, rb_intern("call"), 0);
|
||||
}
|
||||
}
|
15
ext/v8/rr.h
15
ext/v8/rr.h
|
@ -602,6 +602,21 @@ private:
|
|||
bool allocated;
|
||||
};
|
||||
|
||||
class Locker {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE StartPreemption(VALUE self, VALUE every_n_ms);
|
||||
static VALUE StopPreemption(VALUE self);
|
||||
static VALUE IsLocked(VALUE self);
|
||||
static VALUE IsActive(VALUE self);
|
||||
static VALUE doLock(int argc, VALUE* argv, VALUE self);
|
||||
static VALUE setupLockAndCall(int* state, VALUE code);
|
||||
static VALUE doLockCall(VALUE code);
|
||||
static VALUE doUnlock(int argc, VALUE* argv, VALUE self);
|
||||
static VALUE setupUnlockAndCall(int* state, VALUE code);
|
||||
static VALUE doUnlockCall(VALUE code);
|
||||
};
|
||||
|
||||
class V8 {
|
||||
public:
|
||||
static void Init();
|
||||
|
|
26
spec/c/locker_spec.rb
Normal file
26
spec/c/locker_spec.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe V8::C::Locker do
|
||||
it "can lock and unlock the VM" do
|
||||
pending "need to figure out how to wrap rspec methods"
|
||||
V8::C::Locker::IsLocked().should be_false
|
||||
V8::C::Locker() do
|
||||
V8::C::Locker::IsLocked().should be_true
|
||||
V8::C::Unlocker() do
|
||||
V8::C::Locker::IsLocked().should be_false
|
||||
end
|
||||
end
|
||||
V8::C::Locker::IsLocked().should be_false
|
||||
end
|
||||
|
||||
it "properly unlocks if an exception is thrown inside a lock block" do
|
||||
pending "need to figure out how to wrap rspec methods"
|
||||
begin
|
||||
V8::C::Locker() do
|
||||
raise "boom!"
|
||||
end
|
||||
rescue
|
||||
V8::C::Locker::IsLocked().should be_false
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue