Feature #3905 » 0001-error.c-rb_mod_sys_fail-use-subclass-and-cache.patch
| error.c | ||
|---|---|---|
|
extern const char ruby_description[];
|
||
|
static VALUE mod_sys_fail_cache;
|
||
|
static const char *
|
||
|
rb_strerrno(int err)
|
||
|
{
|
||
| ... | ... | |
|
void
|
||
|
rb_mod_sys_fail(VALUE mod, const char *mesg)
|
||
|
{
|
||
|
VALUE exc = make_errno_exc(mesg);
|
||
|
rb_extend_object(exc, mod);
|
||
|
int n = errno;
|
||
|
int need_aset_tmp = 0;
|
||
|
VALUE super_class;
|
||
|
VALUE cached_class;
|
||
|
VALUE per_class;
|
||
|
VALUE exc;
|
||
|
VALUE arg;
|
||
|
errno = 0;
|
||
|
if (n == 0) {
|
||
|
rb_bug("rb_mod_sys_fail(%s) - errno == 0", mesg ? mesg : "");
|
||
|
}
|
||
|
super_class = get_syserr(n);
|
||
|
if (! mod_sys_fail_cache) {
|
||
|
mod_sys_fail_cache = rb_hash_new();
|
||
|
rb_global_variable(&mod_sys_fail_cache);
|
||
|
}
|
||
|
per_class = rb_hash_aref(mod_sys_fail_cache, super_class);
|
||
|
if (NIL_P(per_class)) {
|
||
|
need_aset_tmp = 1;
|
||
|
per_class = rb_hash_new();
|
||
|
}
|
||
|
cached_class = rb_hash_aref(per_class, mod);
|
||
|
if (NIL_P(cached_class)) {
|
||
|
cached_class = rb_obj_dup(super_class);
|
||
|
rb_include_module(cached_class, mod);
|
||
|
rb_hash_aset(per_class, mod, cached_class);
|
||
|
if (need_aset_tmp)
|
||
|
rb_hash_aset(mod_sys_fail_cache, super_class, per_class);
|
||
|
}
|
||
|
arg = mesg ? rb_str_new2(mesg) : Qnil;
|
||
|
exc = rb_class_new_instance(1, &arg, cached_class);
|
||
|
rb_exc_raise(exc);
|
||
|
}
|
||