mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
parent
6a24fdb09d
commit
bb1f1c5782
4 changed files with 104 additions and 35 deletions
11
ChangeLog
11
ChangeLog
|
@ -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.
|
||||
|
|
108
eval_load.c
108
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 int
|
||||
rb_feature_p(const char *feature, const char *ext, int rb)
|
||||
static VALUE
|
||||
loaded_feature_path(const char *name, long vlen, const char *feature, long len)
|
||||
{
|
||||
VALUE v, features;
|
||||
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, int expanded)
|
||||
{
|
||||
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)))) {
|
||||
|
|
14
thread.c
14
thread.c
|
@ -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[];
|
||||
|
|
Loading…
Reference in a new issue