mirror of
https://github.com/rubyjs/therubyracer
synced 2023-03-27 23:21:42 -04:00
Add Locker and Unlocker
This commit is contained in:
parent
143bbb1232
commit
207158fcdb
6 changed files with 164 additions and 16 deletions
|
@ -17,7 +17,8 @@ extern "C" {
|
|||
Object::Init();
|
||||
Primitive::Init();
|
||||
String::Init();
|
||||
// v8::Locker lock();
|
||||
Locker::Init();
|
||||
|
||||
// GC::Init();
|
||||
// Accessor::Init();
|
||||
// Invocation::Init();
|
||||
|
@ -34,7 +35,6 @@ extern "C" {
|
|||
// Message::Init();
|
||||
// TryCatch::Init();
|
||||
// Exception::Init();
|
||||
// Locker::Init();
|
||||
// ResourceConstraints::Init();
|
||||
// HeapStatistics::Init();
|
||||
}
|
||||
|
|
83
ext/v8/locker.cc
Normal file
83
ext/v8/locker.cc
Normal file
|
@ -0,0 +1,83 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
|
||||
void Locker::Init() {
|
||||
ClassBuilder("Locker").
|
||||
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 (*)(...))&Lock, -1);
|
||||
rb_define_singleton_method(c, "Unlocker",(VALUE (*)(...))&Unlock, -1);
|
||||
}
|
||||
|
||||
VALUE Locker::IsLocked(VALUE self, VALUE isolate) {
|
||||
return Bool(v8::Locker::IsLocked(Isolate(isolate)));
|
||||
}
|
||||
|
||||
VALUE Locker::IsActive(VALUE self) {
|
||||
return Bool(v8::Locker::IsActive());
|
||||
}
|
||||
|
||||
VALUE Locker::Lock(int argc, VALUE* argv, VALUE self) {
|
||||
if (!rb_block_given_p()) {
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
int state = 0;
|
||||
|
||||
VALUE isolate, block;
|
||||
rb_scan_args(argc, argv, "10&", &isolate, &block);
|
||||
|
||||
VALUE result = setupLockAndCall(Isolate(isolate), &state, block);
|
||||
|
||||
if (state != 0) {
|
||||
rb_jump_tag(state);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
VALUE Locker::setupLockAndCall(Isolate isolate, int* state, VALUE block) {
|
||||
v8::Locker locker(isolate);
|
||||
|
||||
return rb_protect(&doLockCall, block, state);
|
||||
}
|
||||
|
||||
VALUE Locker::doLockCall(VALUE block) {
|
||||
return rb_funcall(block, rb_intern("call"), 0);
|
||||
}
|
||||
|
||||
VALUE Locker::Unlock(int argc, VALUE* argv, VALUE self) {
|
||||
if (!rb_block_given_p()) {
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
int state = 0;
|
||||
|
||||
VALUE isolate, block;
|
||||
rb_scan_args(argc, argv, "10&", &isolate, &block);
|
||||
|
||||
VALUE result = setupUnlockAndCall(Isolate(isolate), &state, block);
|
||||
|
||||
if (state != 0) {
|
||||
rb_jump_tag(state);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
VALUE Locker::setupUnlockAndCall(Isolate isolate, int* state, VALUE block) {
|
||||
v8::Unlocker unlocker(isolate);
|
||||
|
||||
return rb_protect(&doUnlockCall, block, state);
|
||||
}
|
||||
|
||||
VALUE Locker::doUnlockCall(VALUE block) {
|
||||
return rb_funcall(block, rb_intern("call"), 0);
|
||||
}
|
||||
|
||||
}
|
26
ext/v8/locker.h
Normal file
26
ext/v8/locker.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef RR_LOCKER
|
||||
#define RR_LOCKER
|
||||
|
||||
namespace rr {
|
||||
|
||||
class Locker {
|
||||
public:
|
||||
static void Init();
|
||||
|
||||
static VALUE IsLocked(VALUE self, VALUE isolate);
|
||||
static VALUE IsActive(VALUE self);
|
||||
|
||||
static VALUE Lock(int argc, VALUE* argv, VALUE self);
|
||||
static VALUE Unlock(int argc, VALUE* argv, VALUE self);
|
||||
|
||||
protected:
|
||||
static VALUE setupLockAndCall(Isolate isolate, int* state, VALUE code);
|
||||
static VALUE doLockCall(VALUE code);
|
||||
|
||||
static VALUE setupUnlockAndCall(Isolate isolate, int* state, VALUE code);
|
||||
static VALUE doUnlockCall(VALUE code);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "v8.h"
|
||||
#include "isolate.h"
|
||||
#include "locker.h"
|
||||
#include "handles.h"
|
||||
#include "context.h"
|
||||
|
||||
|
|
41
spec/c/locker_spec.rb
Normal file
41
spec/c/locker_spec.rb
Normal file
|
@ -0,0 +1,41 @@
|
|||
require 'c_spec_helper'
|
||||
|
||||
describe V8::C::Locker do
|
||||
let(:isolate) { V8::C::Isolate.New }
|
||||
|
||||
it 'can lock and unlock the VM' do
|
||||
expect(V8::C::Locker::IsLocked(isolate)).to eq false
|
||||
|
||||
V8::C::Locker(isolate) do
|
||||
expect(V8::C::Locker::IsLocked(isolate)).to eq true
|
||||
|
||||
V8::C::Unlocker(isolate) do
|
||||
expect(V8::C::Locker::IsLocked(isolate)).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
expect(V8::C::Locker::IsLocked(isolate)).to eq false
|
||||
end
|
||||
|
||||
it 'properly unlocks if an exception is thrown inside a lock block' do
|
||||
begin
|
||||
V8::C::Locker(isolate) do
|
||||
raise 'boom!'
|
||||
end
|
||||
rescue
|
||||
expect(V8::C::Locker::IsLocked(isolate)).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
it 'properly re-locks if an exception is thrown inside an un-lock block' do
|
||||
V8::C::Locker(isolate) do
|
||||
begin
|
||||
V8::C::Unlocker(isolate) do
|
||||
raise 'boom!'
|
||||
end
|
||||
rescue
|
||||
expect(V8::C::Locker::IsLocked(isolate)).to eq true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -11,24 +11,21 @@ module V8ContextHelpers
|
|||
end
|
||||
|
||||
def bootstrap_v8_context
|
||||
cleanup_isolates
|
||||
|
||||
isolate = V8::C::Isolate.New
|
||||
|
||||
begin
|
||||
cleanup_isolates
|
||||
V8::C::Locker(isolate) do
|
||||
isolate.Enter
|
||||
|
||||
# V8::C::Locker() do
|
||||
V8::C::HandleScope(isolate) do
|
||||
@cxt = V8::C::Context::New(isolate)
|
||||
begin
|
||||
@cxt.Enter
|
||||
yield
|
||||
ensure
|
||||
@cxt.Exit
|
||||
end
|
||||
V8::C::HandleScope(isolate) do
|
||||
@cxt = V8::C::Context::New(isolate)
|
||||
begin
|
||||
@cxt.Enter
|
||||
yield
|
||||
ensure
|
||||
@cxt.Exit
|
||||
end
|
||||
# end
|
||||
ensure
|
||||
end
|
||||
isolate.Exit
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue