diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-11-06 06:52:01 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-11-06 06:52:01 +0000 |
commit | bb1f1c57823758d2450d184ce7c85beb0d538bf0 (patch) | |
tree | 70b894307235e67b88d28a72ecefcea0986f0c85 | |
parent | 6a24fdb09d8f92c8bebcebe13ca424bd64577a44 (diff) | |
download | ruby-bb1f1c57823758d2450d184ce7c85beb0d538bf0.tar.gz |
* eval_load.c (rb_feature_p): check if the feature is loading with
load path. [ruby-dev:31932]
* eval_load.c (load_lock): check the result of barrier waiting.
* thread.c (rb_barrier_wait): check if owned by the current thread.
* thread.c (rb_barrier_release): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13826 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | eval_load.c | 106 | ||||
-rw-r--r-- | thread.c | 14 | ||||
-rw-r--r-- | version.h | 6 |
4 files changed, 103 insertions, 34 deletions
@@ -1,3 +1,14 @@ +Tue Nov 6 15:52:01 2007 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * eval_load.c (rb_feature_p): check if the feature is loading with + load path. [ruby-dev:31932] + + * eval_load.c (load_lock): check the result of barrier waiting. + + * thread.c (rb_barrier_wait): check if owned by the current thread. + + * thread.c (rb_barrier_release): ditto. + Mon Nov 5 08:01:22 2007 Yukihiro Matsumoto <matz@ruby-lang.org> * eval.c (Init_eval): move #send to Kernel module from BasicObject. diff --git a/eval_load.c b/eval_load.c index d0cd5e2d41..c0deda9540 100644 --- a/eval_load.c +++ b/eval_load.c @@ -22,6 +22,8 @@ static const char *const loadable_ext[] = { 0 }; +VALUE rb_load_path; /* to be moved to VM */ + static VALUE get_loaded_features(void) { @@ -34,12 +36,48 @@ get_loading_table(void) return GET_VM()->loading_table; } +static VALUE +loaded_feature_path(const char *name, long vlen, const char *feature, long len) +{ + long i; + + for (i = 0; i < RARRAY_LEN(rb_load_path); ++i) { + VALUE p = RARRAY_PTR(rb_load_path)[i]; + const char *s = StringValuePtr(p); + long n = RSTRING_LEN(p); + + if (vlen < n + len + 1) continue; + if (n && (strncmp(name, s, n) || name[n] != '/')) continue; + if (strncmp(name + n + 1, feature, len)) continue; + if (name[n+len+1] && name[n+len+1] != '.') continue; + return p; + } + return 0; +} + +struct loaded_feature_searching { + const char *name; + long len; + const char *result; +}; + +static int +loaded_feature_path_i(st_data_t v, st_data_t b, st_data_t f) +{ + const char *s = (const char *)v; + struct loaded_feature_searching *fp = (struct loaded_feature_searching *)f; + VALUE p = loaded_feature_path(s, strlen(s), fp->name, fp->len); + if (!p) return ST_CONTINUE; + fp->result = s; + return ST_STOP; +} + static int -rb_feature_p(const char *feature, const char *ext, int rb) +rb_feature_p(const char *feature, const char *ext, int rb, int expanded) { - VALUE v, features; + VALUE v, features, p; const char *f, *e; - long i, len, elen; + long i, len, elen, n; st_table *loading_tbl; if (ext) { @@ -54,8 +92,12 @@ rb_feature_p(const char *feature, const char *ext, int rb) for (i = 0; i < RARRAY_LEN(features); ++i) { v = RARRAY_PTR(features)[i]; f = StringValuePtr(v); - if (RSTRING_LEN(v) < len || strncmp(f, feature, len) != 0) - continue; + if ((n = RSTRING_LEN(v)) < len) continue; + if (strncmp(f, feature, len) != 0) { + if (expanded || !(p = loaded_feature_path(f, n, feature, len))) + continue; + f += RSTRING_LEN(p) + 1; + } if (!*(e = f + len)) { if (ext) continue; return 'u'; @@ -70,7 +112,16 @@ rb_feature_p(const char *feature, const char *ext, int rb) } loading_tbl = get_loading_table(); if (loading_tbl) { + if (!expanded) { + struct loaded_feature_searching fs; + fs.name = feature; + fs.len = len; + fs.result = 0; + st_foreach(loading_tbl, loaded_feature_path_i, (st_data_t)&fs); + if (fs.result) goto loading; + } if (st_lookup(loading_tbl, (st_data_t)feature, 0)) { + loading: if (!ext) return 'u'; return strcmp(ext, ".rb") ? 's' : 'r'; } @@ -98,17 +149,16 @@ rb_provided(const char *feature) if (ext && !strchr(ext, '/')) { if (strcmp(".rb", ext) == 0) { - if (rb_feature_p(feature, ext, Qtrue)) return Qtrue; + if (rb_feature_p(feature, ext, Qtrue, Qfalse)) return Qtrue; return Qfalse; } else if (IS_SOEXT(ext) || IS_DLEXT(ext)) { - if (rb_feature_p(feature, ext, Qfalse)) return Qtrue; + if (rb_feature_p(feature, ext, Qfalse, Qfalse)) return Qtrue; return Qfalse; } } - if (rb_feature_p(feature, feature + strlen(feature), Qtrue)) + if (rb_feature_p(feature, feature + strlen(feature), Qtrue, Qfalse)) return Qtrue; - return Qfalse; } @@ -124,8 +174,6 @@ rb_provide(const char *feature) rb_provide_feature(rb_str_new2(feature)); } -VALUE rb_load_path; - NORETURN(static void load_failed _((VALUE))); void @@ -134,10 +182,13 @@ rb_load(VALUE fname, int wrap) VALUE tmp; int state; rb_thread_t *th = GET_THREAD(); - VALUE wrapper = th->top_wrapper; - VALUE self = th->top_self; + volatile VALUE wrapper = th->top_wrapper; + volatile VALUE self = th->top_self; volatile int parse_in_eval; volatile int loaded = Qfalse; +#ifndef __GNUC__ + rb_thread_t *volatile th0 = th; +#endif FilePathValue(fname); fname = rb_str_new4(fname); @@ -177,6 +228,10 @@ rb_load(VALUE fname, int wrap) } POP_TAG(); +#ifndef __GNUC__ + th = th0; + fname = RB_GC_GUARD(fname); +#endif th->parse_in_eval = parse_in_eval; th->top_self = self; th->top_wrapper = wrapper; @@ -252,8 +307,7 @@ load_lock(const char *ftptr) st_insert(loading_tbl, (st_data_t)ftptr, data); return (char *)ftptr; } - rb_barrier_wait((VALUE)data); - return 0; + return RTEST(rb_barrier_wait((VALUE)data)) ? (char *)ftptr : 0; } static void @@ -311,19 +365,19 @@ search_required(VALUE fname, volatile VALUE *path) ext = strrchr(ftptr = RSTRING_PTR(fname), '.'); if (ext && !strchr(ext, '/')) { if (strcmp(".rb", ext) == 0) { - if (rb_feature_p(ftptr, ext, Qtrue)) + if (rb_feature_p(ftptr, ext, Qtrue, Qfalse)) return 'r'; if ((tmp = rb_find_file(fname)) != 0) { tmp = rb_file_expand_path(tmp, Qnil); ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); - if (!rb_feature_p(ftptr, ext, Qtrue)) + if (!rb_feature_p(ftptr, ext, Qtrue, Qtrue)) *path = tmp; return 'r'; } return 0; } else if (IS_SOEXT(ext)) { - if (rb_feature_p(ftptr, ext, Qfalse)) + if (rb_feature_p(ftptr, ext, Qfalse, Qfalse)) return 's'; tmp = rb_str_new(RSTRING_PTR(fname), ext - RSTRING_PTR(fname)); #ifdef DLEXT2 @@ -331,7 +385,7 @@ search_required(VALUE fname, volatile VALUE *path) if (rb_find_file_ext(&tmp, loadable_ext + 1)) { tmp = rb_file_expand_path(tmp, Qnil); ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); - if (!rb_feature_p(ftptr, ext, Qfalse)) + if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue)) *path = tmp; return 's'; } @@ -341,25 +395,25 @@ search_required(VALUE fname, volatile VALUE *path) if ((tmp = rb_find_file(tmp)) != 0) { tmp = rb_file_expand_path(tmp, Qnil); ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); - if (!rb_feature_p(ftptr, ext, Qfalse)) + if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue)) *path = tmp; return 's'; } #endif } else if (IS_DLEXT(ext)) { - if (rb_feature_p(ftptr, ext, Qfalse)) + if (rb_feature_p(ftptr, ext, Qfalse, Qfalse)) return 's'; if ((tmp = rb_find_file(fname)) != 0) { tmp = rb_file_expand_path(tmp, Qnil); ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); - if (!rb_feature_p(ftptr, ext, Qfalse)) + if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue)) *path = tmp; return 's'; } } } - else if ((ft = rb_feature_p(ftptr, 0, Qfalse)) == 'r') { + else if ((ft = rb_feature_p(ftptr, 0, Qfalse, Qfalse)) == 'r') { return 'r'; } tmp = fname; @@ -370,14 +424,14 @@ search_required(VALUE fname, volatile VALUE *path) ftptr = RSTRING_PTR(tmp); if (ft) break; - return rb_feature_p(ftptr, 0, Qfalse); + return rb_feature_p(ftptr, 0, Qfalse, Qtrue); default: if (ft) break; case 1: ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); - if (rb_feature_p(ftptr, ext, !--type)) + if (rb_feature_p(ftptr, ext, !--type, Qtrue)) break; *path = tmp; } @@ -419,7 +473,7 @@ rb_require_safe(VALUE fname, int safe) rb_set_safe_level_force(safe); FilePathValue(fname); - *(volatile VALUE *)&fname = rb_str_new4(fname); + RB_GC_GUARD(fname) = rb_str_new4(fname); found = search_required(fname, &path); if (found) { if (!path || !(ftptr = load_lock(RSTRING_PTR(path)))) { @@ -2435,7 +2435,7 @@ thlist_free(void *ptr) } static int -thlist_signal(rb_thread_list_t **list, unsigned int maxth) +thlist_signal(rb_thread_list_t **list, unsigned int maxth, rb_thread_t **woken_thread) { int woken = 0; rb_thread_list_t *q; @@ -2447,6 +2447,7 @@ thlist_signal(rb_thread_list_t **list, unsigned int maxth) ruby_xfree(q); if (th->status != THREAD_KILLED) { rb_thread_ready(th); + if (!woken && woken_thread) *woken_thread = th; if (++woken >= maxth && maxth) break; } } @@ -2507,7 +2508,8 @@ rb_barrier_wait(VALUE self) Data_Get_Struct(self, rb_barrier_t, barrier); if (!barrier->owner || barrier->owner->status == THREAD_KILLED) { barrier->owner = 0; - thlist_signal(&barrier->waiting, 0); + if (thlist_signal(&barrier->waiting, 1, &barrier->owner)) return Qfalse; + return Qtrue; } else { *barrier->tail = q = ALLOC(rb_thread_list_t); @@ -2515,8 +2517,8 @@ rb_barrier_wait(VALUE self) q->next = 0; barrier->tail = &q->next; rb_thread_sleep_forever(); + return barrier->owner == GET_THREAD() ? Qtrue : Qfalse; } - return self; } VALUE @@ -2526,8 +2528,10 @@ rb_barrier_release(VALUE self) unsigned int n; Data_Get_Struct(self, rb_barrier_t, barrier); - barrier->owner = 0; - n = thlist_signal(&barrier->waiting, 0); + if (barrier->owner != GET_THREAD()) { + rb_raise(rb_eThreadError, "not owned"); + } + n = thlist_signal(&barrier->waiting, 0, &barrier->owner); return n ? UINT2NUM(n) : Qfalse; } @@ -1,7 +1,7 @@ #define RUBY_VERSION "1.9.0" -#define RUBY_RELEASE_DATE "2007-11-05" +#define RUBY_RELEASE_DATE "2007-11-06" #define RUBY_VERSION_CODE 190 -#define RUBY_RELEASE_CODE 20071105 +#define RUBY_RELEASE_CODE 20071106 #define RUBY_PATCHLEVEL 0 #define RUBY_VERSION_MAJOR 1 @@ -9,7 +9,7 @@ #define RUBY_VERSION_TEENY 0 #define RUBY_RELEASE_YEAR 2007 #define RUBY_RELEASE_MONTH 11 -#define RUBY_RELEASE_DAY 5 +#define RUBY_RELEASE_DAY 6 #ifdef RUBY_EXTERN RUBY_EXTERN const char ruby_version[]; |