[前][次][番号順一覧][スレッド一覧]

ruby-changes:2335

From: ko1@a...
Date: 6 Nov 2007 15:52:32 +0900
Subject: [ruby-changes:2335] nobu - Ruby:r13826 (trunk): * eval_load.c (rb_feature_p): check if the feature is loading with

nobu	2007-11-06 15:52:01 +0900 (Tue, 06 Nov 2007)

  New Revision: 13826

  Modified files:
    trunk/ChangeLog
    trunk/eval_load.c
    trunk/thread.c
    trunk/version.h

  Log:
    * 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.


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/version.h?r1=13826&r2=13825
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/eval_load.c?r1=13826&r2=13825
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=13826&r2=13825
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/thread.c?r1=13826&r2=13825

Index: eval_load.c
===================================================================
--- eval_load.c	(revision 13825)
+++ eval_load.c	(revision 13826)
@@ -22,6 +22,8 @@
     0
 };
 
+VALUE rb_load_path;		/* to be moved to VM */
+
 static VALUE
 get_loaded_features(void)
 {
@@ -34,12 +36,48 @@
     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
-rb_feature_p(const char *feature, const char *ext, int rb)
+loaded_feature_path_i(st_data_t v, st_data_t b, st_data_t f)
 {
-    VALUE v, features;
+    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 @@
     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 @@
     }
     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 @@
 
     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_feature(rb_str_new2(feature));
 }
 
-VALUE rb_load_path;
-
 NORETURN(static void load_failed _((VALUE)));
 
 void
@@ -134,10 +182,13 @@
     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 @@
     }
     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 @@
 	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 @@
     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 @@
 	    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 @@
 	    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 @@
 	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_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)))) {
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 13825)
+++ ChangeLog	(revision 13826)
@@ -1,3 +1,14 @@
+Tue Nov  6 15:52:01 2007  Nobuyoshi Nakada  <nobu@r...>
+
+	* 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@r...>
 
 	* eval.c (Init_eval): move #send to Kernel module from BasicObject.
Index: thread.c
===================================================================
--- thread.c	(revision 13825)
+++ thread.c	(revision 13826)
@@ -2435,7 +2435,7 @@
 }
 
 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 @@
 	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 @@
     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 @@
 	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 @@
     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;
 }
 
Index: version.h
===================================================================
--- version.h	(revision 13825)
+++ version.h	(revision 13826)
@@ -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[];

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml

[前][次][番号順一覧][スレッド一覧]