0002-error.c-rb_mod_sys_fail-use-subclass-and-cache.patch

cache rb_mod_sys_fail to avoid expensive cache clearing with non-blocking I/O - Eric Wong, 04/07/2011 08:45 AM

Download (2.08 KB)

View differences:

error.c
35 35

  
36 36
extern const char ruby_description[];
37 37

  
38
static VALUE mod_sys_fail_cache;
39

  
38 40
static const char *
39 41
rb_strerrno(int err)
40 42
{
......
1595 1597
void
1596 1598
rb_mod_sys_fail(VALUE mod, const char *mesg)
1597 1599
{
1598
    VALUE exc = make_errno_exc(mesg);
1599
    rb_extend_object(exc, mod);
1600
    int n = errno;
1601
    int need_aset_tmp = 0;
1602
    VALUE super_class;
1603
    VALUE cached_class;
1604
    VALUE per_class;
1605
    VALUE exc;
1606
    VALUE arg;
1607

  
1608
    errno = 0;
1609
    if (n == 0) {
1610
       rb_bug("rb_mod_sys_fail(%s) - errno == 0", mesg ? mesg : "");
1611
    }
1612
    super_class = get_syserr(n);
1613

  
1614
    if (! mod_sys_fail_cache) {
1615
       mod_sys_fail_cache = rb_hash_new();
1616
       rb_global_variable(&mod_sys_fail_cache);
1617
    }
1618
    per_class = rb_hash_aref(mod_sys_fail_cache, super_class);
1619

  
1620
    if (NIL_P(per_class)) {
1621
       need_aset_tmp = 1;
1622
       per_class = rb_hash_new();
1623
    }
1624

  
1625
    cached_class = rb_hash_aref(per_class, mod);
1626
    if (NIL_P(cached_class)) {
1627
       cached_class = rb_obj_dup(super_class);
1628
       rb_include_module(cached_class, mod);
1629
       rb_hash_aset(per_class, mod, cached_class);
1630
       if (need_aset_tmp)
1631
           rb_hash_aset(mod_sys_fail_cache, super_class, per_class);
1632
    }
1633

  
1634
    arg = mesg ? rb_str_new2(mesg) : Qnil;
1635
    exc = rb_class_new_instance(1, &arg, cached_class);
1600 1636
    rb_exc_raise(exc);
1601 1637
}
1602 1638