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);
|
||
}
|
||