Project

General

Profile

Feature #8215 ยป 0001-cont.c-fiber-local-accessors.patch

nobu (Nobuyoshi Nakada), 04/16/2013 05:03 PM

View differences:

cont.c
1471 1471
    return rb_fiber_transfer(fibval, argc, argv);
1472 1472
}
1473 1473

  
1474
static VALUE
1475
rb_fiber_aref(VALUE self, VALUE key)
1476
{
1477
    rb_thread_t *th;
1478
    rb_fiber_t *fib;
1479
    st_data_t val;
1480
    ID id = rb_check_id(&key);
1481

  
1482
    GetFiberPtr(self, fib);
1483
    if (rb_safe_level() >= 4 && self != rb_fiber_current()) {
1484
	rb_raise(rb_eSecurityError, "Insecure: fiber locals");
1485
    }
1486
    if (!id) return Qnil;
1487
    th = &fib->cont.saved_thread;
1488
    if (!th->local_storage) {
1489
	return Qnil;
1490
    }
1491
    if (st_lookup(th->local_storage, id, &val)) {
1492
	return (VALUE)val;
1493
    }
1494
    return Qnil;
1495
}
1496

  
1497
static VALUE
1498
rb_fiber_aset(VALUE self, VALUE key, VALUE val)
1499
{
1500
    rb_thread_t *th;
1501
    rb_fiber_t *fib;
1502
    ID id = rb_check_id(&key);
1503

  
1504
    GetFiberPtr(self, fib);
1505
    if (rb_safe_level() >= 4 && self != rb_fiber_current()) {
1506
	rb_raise(rb_eSecurityError, "Insecure: can't modify thread locals");
1507
    }
1508
    if (OBJ_FROZEN(self)) {
1509
	rb_error_frozen("thread locals");
1510
    }
1511
    if (!id) return Qnil;
1512
    th = &fib->cont.saved_thread;
1513
    if (NIL_P(val)) {
1514
	if (th->local_storage) {
1515
	    st_data_t k = (st_data_t)id;
1516
	    st_delete(th->local_storage, &k, 0);
1517
	}
1518
	return Qnil;
1519
    }
1520
    if (!th->local_storage) {
1521
	th->local_storage = st_init_numtable();
1522
    }
1523
    st_insert(th->local_storage, id, val);
1524
    return val;
1525
}
1526

  
1474 1527
/*
1475 1528
 *  call-seq:
1476 1529
 *     Fiber.yield(args, ...) -> obj
......
1538 1591
    rb_define_singleton_method(rb_cFiber, "yield", rb_fiber_s_yield, -1);
1539 1592
    rb_define_method(rb_cFiber, "initialize", rb_fiber_init, 0);
1540 1593
    rb_define_method(rb_cFiber, "resume", rb_fiber_m_resume, -1);
1594
    rb_define_method(rb_cFiber, "[]", rb_fiber_aref, 1);
1595
    rb_define_method(rb_cFiber, "[]=", rb_fiber_aset, 2);
1541 1596
}
1542 1597

  
1543 1598
RUBY_SYMBOL_EXPORT_BEGIN
test/ruby/test_fiber.rb
341 341
    assert_equal("inner", s2)
342 342
    assert_equal(s1, $_, bug7678)
343 343
  end
344

  
345
  def test_fiber_local
346
    feature8215 = '[ruby-core:53974] [Feature #8215]'
347
    Thread.current[:key] = "outside"
348
    fiber = Fiber.new do
349
      Thread.current[:key] = "inside"
350
      Fiber.yield
351
    end
352
    fiber.resume
353
    assert_equal("inside", fiber[:key], feature8215)
354
  end
344 355
end
345 356

  
346
-