Feature #8215 ยป 0001-cont.c-fiber-local-accessors.patch
| cont.c | ||
|---|---|---|
|
return rb_fiber_transfer(fibval, argc, argv);
|
||
|
}
|
||
|
static VALUE
|
||
|
rb_fiber_aref(VALUE self, VALUE key)
|
||
|
{
|
||
|
rb_thread_t *th;
|
||
|
rb_fiber_t *fib;
|
||
|
st_data_t val;
|
||
|
ID id = rb_check_id(&key);
|
||
|
GetFiberPtr(self, fib);
|
||
|
if (rb_safe_level() >= 4 && self != rb_fiber_current()) {
|
||
|
rb_raise(rb_eSecurityError, "Insecure: fiber locals");
|
||
|
}
|
||
|
if (!id) return Qnil;
|
||
|
th = &fib->cont.saved_thread;
|
||
|
if (!th->local_storage) {
|
||
|
return Qnil;
|
||
|
}
|
||
|
if (st_lookup(th->local_storage, id, &val)) {
|
||
|
return (VALUE)val;
|
||
|
}
|
||
|
return Qnil;
|
||
|
}
|
||
|
static VALUE
|
||
|
rb_fiber_aset(VALUE self, VALUE key, VALUE val)
|
||
|
{
|
||
|
rb_thread_t *th;
|
||
|
rb_fiber_t *fib;
|
||
|
ID id = rb_check_id(&key);
|
||
|
GetFiberPtr(self, fib);
|
||
|
if (rb_safe_level() >= 4 && self != rb_fiber_current()) {
|
||
|
rb_raise(rb_eSecurityError, "Insecure: can't modify thread locals");
|
||
|
}
|
||
|
if (OBJ_FROZEN(self)) {
|
||
|
rb_error_frozen("thread locals");
|
||
|
}
|
||
|
if (!id) return Qnil;
|
||
|
th = &fib->cont.saved_thread;
|
||
|
if (NIL_P(val)) {
|
||
|
if (th->local_storage) {
|
||
|
st_data_t k = (st_data_t)id;
|
||
|
st_delete(th->local_storage, &k, 0);
|
||
|
}
|
||
|
return Qnil;
|
||
|
}
|
||
|
if (!th->local_storage) {
|
||
|
th->local_storage = st_init_numtable();
|
||
|
}
|
||
|
st_insert(th->local_storage, id, val);
|
||
|
return val;
|
||
|
}
|
||
|
/*
|
||
|
* call-seq:
|
||
|
* Fiber.yield(args, ...) -> obj
|
||
| ... | ... | |
|
rb_define_singleton_method(rb_cFiber, "yield", rb_fiber_s_yield, -1);
|
||
|
rb_define_method(rb_cFiber, "initialize", rb_fiber_init, 0);
|
||
|
rb_define_method(rb_cFiber, "resume", rb_fiber_m_resume, -1);
|
||
|
rb_define_method(rb_cFiber, "[]", rb_fiber_aref, 1);
|
||
|
rb_define_method(rb_cFiber, "[]=", rb_fiber_aset, 2);
|
||
|
}
|
||
|
RUBY_SYMBOL_EXPORT_BEGIN
|
||
| test/ruby/test_fiber.rb | ||
|---|---|---|
|
assert_equal("inner", s2)
|
||
|
assert_equal(s1, $_, bug7678)
|
||
|
end
|
||
|
def test_fiber_local
|
||
|
feature8215 = '[ruby-core:53974] [Feature #8215]'
|
||
|
Thread.current[:key] = "outside"
|
||
|
fiber = Fiber.new do
|
||
|
Thread.current[:key] = "inside"
|
||
|
Fiber.yield
|
||
|
end
|
||
|
fiber.resume
|
||
|
assert_equal("inside", fiber[:key], feature8215)
|
||
|
end
|
||
|
end
|
||