Bug #4289 » 0002-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); | ||
| } | ||