Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

CRuby 1.8.7 autoload thread safety patch (against r31735)

View gist:992380
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
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
Something went wrong with that request. Please try again.