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

ruby-changes:19857

From: shyouhei <ko1@a...>
Date: Thu, 2 Jun 2011 19:02:30 +0900 (JST)
Subject: [ruby-changes:19857] shyouhei:r31904 (ruby_1_8_7): merge revision(s) 31731:31734:

shyouhei	2011-06-02 19:02:20 +0900 (Thu, 02 Jun 2011)

  New Revision: 31904

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=31904

  Log:
    merge revision(s) 31731:31734:
    
    * variable.c (rb_autoload_load):  There is a  race condition while
      autoloading.  When two or more threads touch a single autoloaded
      constant at  a time,  one of them  does the require,  but others
      behave  oddly.   To  fix  this  situation we  now  refrain  from
      deleting the autoload table while someone is doing the autoload.
      That  deletion is  deferred to  a  point where  a require  ended
      successfully.  Doing so make it possible for multiple threads to
      enter autoloading at the same  time but the require is protected
      against  multiple simultaneous  entrance anyway  so all  but one
      thread  gets blocked  at that  point.   So with  it, touching  a
      constant that gets autoloaded cause those threads to block until
      there is another one that does the same thing.
      [ruby-core:36308] (#921)
    
    * variable.c (rb_const_get_0): ditto.
    
    * variable.c (autoload_node): ditto.
    
    * variable.c (autoload_delete): ditto.
    
    git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@31732 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
    Signed-off-by: URABE, Shyouhei <shyouhei@r...>
    
    * variable.c (rb_const_get_0):  Fix  previous change.   There were
      possibilities   when   an   autoload-specified   library   lacks
      definition of  the constant  it was bound  to.  Once  after such
      library had  already beed loaded, the autoload  engine shall not
      reload  it.   Instead  the  interpreter have  to  consider  such
      constant nonexistent.  It results in a const_missing situation.
    
    * variable.c (rb_autoload_load): ditto.
    
    * variable.c (autoload_node): ditto.
    
    git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@31734 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
    Signed-off-by: URABE, Shyouhei <shyouhei@r...>

  Modified files:
    branches/ruby_1_8_7/ChangeLog
    branches/ruby_1_8_7/variable.c
    branches/ruby_1_8_7/version.h

Index: ruby_1_8_7/ChangeLog
===================================================================
--- ruby_1_8_7/ChangeLog	(revision 31903)
+++ ruby_1_8_7/ChangeLog	(revision 31904)
@@ -1,3 +1,38 @@
+Thu Jun  2 18:33:51 2011  URABE Shyouhei  <shyouhei@r...>
+
+	* variable.c (rb_const_get_0):  Fix  previous change.   There were
+	  possibilities   when   an   autoload-specified   library   lacks
+	  definition of  the constant  it was bound  to.  Once  after such
+	  library had  already beed loaded, the autoload  engine shall not
+	  reload  it.   Instead  the  interpreter have  to  consider  such
+	  constant nonexistent.  It results in a const_missing situation.
+
+	* variable.c (rb_autoload_load): ditto.
+
+	* variable.c (autoload_node): ditto.
+
+Thu Jun  2 18:28:58 2011  URABE Shyouhei  <shyouhei@r...>
+
+	* variable.c (rb_autoload_load):  There is a  race condition while
+	  autoloading.  When two or more threads touch a single autoloaded
+	  constant at  a time,  one of them  does the require,  but others
+	  behave  oddly.   To  fix  this  situation we  now  refrain  from
+	  deleting the autoload table while someone is doing the autoload.
+	  That  deletion is  deferred to  a  point where  a require  ended
+	  successfully.  Doing so make it possible for multiple threads to
+	  enter autoloading at the same  time but the require is protected
+	  against  multiple simultaneous  entrance anyway  so all  but one
+	  thread  gets blocked  at that  point.   So with  it, touching  a
+	  constant that gets autoloaded cause those threads to block until
+	  there is another one that does the same thing.
+	  [ruby-core:36308] (#921)
+
+	* variable.c (rb_const_get_0): ditto.
+
+	* variable.c (autoload_node): ditto.
+
+	* variable.c (autoload_delete): ditto.
+
 Mon May 30 10:58:17 2011  Hiroshi Nakamura  <nahi@r...>
 
 	* lib/logger.rb (Logger::ProgName): do not depend on subversion
Index: ruby_1_8_7/variable.c
===================================================================
--- ruby_1_8_7/variable.c	(revision 31903)
+++ ruby_1_8_7/variable.c	(revision 31904)
@@ -1331,7 +1331,6 @@
     VALUE val;
     st_data_t load = 0;
 
-    st_delete(RCLASS(mod)->iv_tbl, (st_data_t*)&id, 0);
     if (st_lookup(RCLASS(mod)->iv_tbl, autoload, &val)) {
 	struct st_table *tbl = check_autoload_table(val);
 
@@ -1346,18 +1345,55 @@
     return (NODE *)load;
 }
 
+static NODE *
+autoload_node(mod, id)
+    VALUE mod;
+    ID id;
+{
+    st_data_t val, load, n = id;
+    struct st_table *p, *q;
+
+    if ((p = RCLASS(mod)->iv_tbl) == 0) {
+        return 0;
+    }
+    else if (!st_lookup(p, n, &val)) {
+        return 0;
+    }
+    else if (val != Qundef) {
+        return 0;
+    }
+    else if (!st_lookup(p, autoload, &val)) {
+        return 0;
+    }
+    else if ((q = check_autoload_table((VALUE)val)) == 0) {
+        return 0;
+    }
+    else if (!st_lookup(q, n, &load)) {
+        return 0;
+    }
+    else {
+        return (NODE *)load;
+    }
+}
+
 VALUE
 rb_autoload_load(klass, id)
     VALUE klass;
     ID id;
 {
-    VALUE file;
-    NODE *load = autoload_delete(klass, id);
+    NODE *load = 0;
+    VALUE ret = 0;
 
-    if (!load || !(file = load->nd_lit) || rb_provided(RSTRING(file)->ptr)) {
-	return Qfalse;
+    if ((load = autoload_node(klass, id)) == 0) {
+        return 0;
     }
-    return rb_require_safe(file, load->nd_nth);
+    else if ((ret = rb_require_safe(load->nd_lit, load->nd_nth)) == Qfalse) {
+        return 0;
+    }
+    else {
+        (void) autoload_delete(klass, id);
+        return ret;
+    }
 }
 
 static VALUE
@@ -1419,8 +1455,15 @@
     while (tmp) {
 	while (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,&value)) {
 	    if (value == Qundef) {
-		if (!RTEST(rb_autoload_load(tmp, id))) break;
-		continue;
+		rb_autoload_load(tmp, id);
+                st_lookup(RCLASS(tmp)->iv_tbl, id, &value);
+                if (value == Qundef) {
+                    /* the autoload above did not assign a constant */
+                    break;
+                }
+                else {
+                    continue;
+                }
 	    }
 	    if (exclude && tmp == rb_cObject && klass != rb_cObject) {
 		rb_warn("toplevel constant %s referenced by %s::%s",
Index: ruby_1_8_7/version.h
===================================================================
--- ruby_1_8_7/version.h	(revision 31903)
+++ ruby_1_8_7/version.h	(revision 31904)
@@ -2,7 +2,7 @@
 #define RUBY_RELEASE_DATE "2011-06-02"
 #define RUBY_VERSION_CODE 187
 #define RUBY_RELEASE_CODE 20110602
-#define RUBY_PATCHLEVEL 347
+#define RUBY_PATCHLEVEL 348
 
 #define RUBY_VERSION_MAJOR 1
 #define RUBY_VERSION_MINOR 8

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

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