123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- Index: load.c
- ===================================================================
- --- a/load.c (revision 43513)
- +++ b/load.c (revision 43514)
- @@ -8,6 +8,7 @@
- #include "dln.h"
- #include "eval_intern.h"
- #include "probes.h"
- +#include "node.h"
-
- VALUE ruby_dln_librefs;
-
- @@ -482,6 +483,9 @@
- else {
- VALUE bufstr;
- char *buf;
- + static const char so_ext[][4] = {
- + ".so", ".o",
- + };
-
- if (ext && *ext) return 0;
- bufstr = rb_str_tmp_new(len + DLEXT_MAXLEN);
- @@ -495,6 +499,14 @@
- return i ? 's' : 'r';
- }
- }
- + for (i = 0; i < numberof(so_ext); i++) {
- + strlcpy(buf + len, so_ext[i], DLEXT_MAXLEN + 1);
- + if (st_get_key(loading_tbl, (st_data_t)buf, &data)) {
- + rb_str_resize(bufstr, 0);
- + if (fn) *fn = (const char*)data;
- + return 's';
- + }
- + }
- rb_str_resize(bufstr, 0);
- }
- }
- @@ -709,6 +721,14 @@
- st_insert(loading_tbl, (st_data_t)ftptr, data);
- return (char *)ftptr;
- }
- + else if (RB_TYPE_P((VALUE)data, T_NODE) && nd_type((VALUE)data) == NODE_MEMO) {
- + NODE *memo = RNODE(data);
- + void (*init)(void) = (void (*)(void))memo->nd_cfnc;
- + data = (st_data_t)rb_thread_shield_new();
- + st_insert(loading_tbl, (st_data_t)ftptr, data);
- + (*init)();
- + return (char *)"";
- + }
- if (RTEST(ruby_verbose)) {
- rb_warning("loading in progress, circular require considered harmful - %s", ftptr);
- rb_backtrace_print_to(rb_stderr);
- @@ -881,13 +901,16 @@
- switch (type) {
- case 0:
- if (ft)
- - break;
- + goto statically_linked;
- ftptr = RSTRING_PTR(tmp);
- return rb_feature_p(ftptr, 0, FALSE, TRUE, 0);
-
- default:
- - if (ft)
- - break;
- + if (ft) {
- + statically_linked:
- + if (loading) *path = rb_filesystem_str_new_cstr(loading);
- + return ft;
- + }
- case 1:
- ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
- if (rb_feature_p(ftptr, ext, !--type, TRUE, &loading) && !loading)
- @@ -957,6 +980,10 @@
- if (!path || !(ftptr = load_lock(RSTRING_PTR(path)))) {
- result = Qfalse;
- }
- + else if (!*ftptr) {
- + rb_provide_feature(path);
- + result = Qtrue;
- + }
- else {
- switch (found) {
- case 'r':
- @@ -1005,26 +1032,30 @@
- return rb_require_safe(fn, rb_safe_level());
- }
-
- -static VALUE
- -init_ext_call(VALUE arg)
- +static int
- +register_init_ext(st_data_t *key, st_data_t *value, st_data_t init, int existing)
- {
- - SCOPE_SET(NOEX_PUBLIC);
- - (*(void (*)(void))arg)();
- - return Qnil;
- + const char *name = (char *)*key;
- + if (existing) {
- + /* already registered */
- + rb_warn("%s is already registered", name);
- + }
- + else {
- + *value = (st_data_t)NEW_MEMO(init, 0, 0);
- + *key = (st_data_t)ruby_strdup(name);
- + }
- + return ST_CONTINUE;
- }
-
- RUBY_FUNC_EXPORTED void
- ruby_init_ext(const char *name, void (*init)(void))
- {
- - char* const lock_key = load_lock(name);
- - if (lock_key) {
- - VALUE feature = rb_usascii_str_new_cstr(name);
- - OBJ_FREEZE(feature);
- - rb_vm_call_cfunc(rb_vm_top_self(), init_ext_call, (VALUE)init,
- - 0, feature);
- - rb_provide_feature(feature);
- - load_unlock(lock_key, 1);
- + st_table *loading_tbl = get_loading_table();
- +
- + if (!loading_tbl) {
- + GET_VM()->loading_table = loading_tbl = st_init_strtable();
- }
- + st_update(loading_tbl, (st_data_t)name, register_init_ext, (st_data_t)init);
- }
-
- /*
|