add locking for concurrent access

This commit is contained in:
Sam Saffron 2016-05-11 12:26:52 +10:00
parent 4dee1dc11c
commit 99cf7a690c
4 changed files with 29 additions and 8 deletions

View File

@ -34,8 +34,8 @@ LIBV8_COMPATIBILITY = '~> 5.0.71.35.0'
#
# Libv8.configure_makefile
NODE_PATH = "/home/sam/Source/libv8"
#NODE_PATH = "/Users/sam/Source/libv8"
#NODE_PATH = "/home/sam/Source/libv8"
NODE_PATH = "/Users/sam/Source/libv8"
#
NODE_LIBS = NODE_PATH + "/vendor/v8/out/x64.release"
NODE_INCLUDE = NODE_PATH + "/vendor/v8/include"

View File

@ -178,7 +178,7 @@ static Handle<Value> convert_ruby_to_v8(Isolate* isolate, VALUE value) {
}
static VALUE rb_context_eval(VALUE self, VALUE str) {
static VALUE rb_context_eval_unsafe(VALUE self, VALUE str) {
EvalParams eval_params;
EvalResult eval_result;
@ -408,10 +408,10 @@ extern "C" {
VALUE rb_mMiniRacer = rb_define_module("MiniRacer");
VALUE rb_cContext = rb_define_class_under(rb_mMiniRacer, "Context", rb_cObject);
VALUE rb_cExternalFunction = rb_define_class_under(rb_cContext, "ExternalFunction", rb_cObject);
rb_define_method(rb_cContext, "eval",(VALUE(*)(...))&rb_context_eval, 1);
rb_define_method(rb_cContext, "stop", (VALUE(*)(...))&rb_context_stop, 0);
rb_define_alloc_func(rb_cContext, allocate);
rb_define_private_method(rb_cContext, "eval_unsafe",(VALUE(*)(...))&rb_context_eval_unsafe, 1);
rb_define_private_method(rb_cExternalFunction, "notify_v8", (VALUE(*)(...))&rb_external_function_notify_v8, 0);
rb_define_alloc_func(rb_cExternalFunction, allocate_external_function);
}

View File

@ -1,5 +1,6 @@
require "mini_racer/version"
require "mini_racer_extension"
require "thread"
module MiniRacer
class JavaScriptError < StandardError; end
@ -18,14 +19,23 @@ module MiniRacer
def initialize(options = nil)
@functions = {}
@lock = Mutex.new
if options
@timeout = options[:timeout]
end
end
def eval(str)
@lock.synchronize do
eval_unsafe(str)
end
end
def attach(name, callback)
external = ExternalFunction.new(name, callback, self)
@functions[name.to_s] = external
@lock.synchronize do
external = ExternalFunction.new(name, callback, self)
@functions[name.to_s] = external
end
end
end

View File

@ -73,14 +73,25 @@ class MiniRacerTest < Minitest::Test
assert_equal 42, context.eval('adder=(x,y)=>x+y; adder(21,21);')
end
def test_attached_exceptions
def test_concurrent_access
context = MiniRacer::Context.new
context.eval('counter=0; plus=()=>counter++;')
(1..10).map do
Thread.new {
context.eval("plus()")
}
end.each(&:join)
assert_equal 10, context.eval("counter")
end
def test_attached_exceptions
context = MiniRacer::Context.new
context.attach("adder", proc{raise StandardError})
assert_raises do
context.eval('adder(1,2,3)')
end
end
end