Skip to content

Instantly share code, notes, and snippets.

@nahi
Created May 26, 2011 01:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nahi/992380 to your computer and use it in GitHub Desktop.
Save nahi/992380 to your computer and use it in GitHub Desktop.
CRuby 1.8.7 autoload thread safety patch (against r31735)
Index: variable.c
===================================================================
--- variable.c (revision 31735)
+++ variable.c (working copy)
@@ -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,52 @@
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)) {
+ if ((load = autoload_node(klass, id)) == 0) {
return Qfalse;
}
- return rb_require_safe(file, load->nd_nth);
+ if ((ret = rb_require_safe(load->nd_lit, load->nd_nth)) == Qtrue) {
+ (void) autoload_delete(klass, id);
+ }
+ return ret;
}
static VALUE
@@ -1419,8 +1452,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",
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment