summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/hacking.md4
-rw-r--r--variable.c64
2 files changed, 32 insertions, 36 deletions
diff --git a/doc/hacking.md b/doc/hacking.md
index 1268f36fb1..fcaead8965 100644
--- a/doc/hacking.md
+++ b/doc/hacking.md
@@ -42,6 +42,10 @@ If you are frequently building Ruby, this will reduce the time it takes to `make
../configure --disable-install-doc
```
+### Unexplainable Build Errors
+
+If you are having unexplainable build errors, after saving all your work, try running `git clean -xfd` in the source root to remove all git ignored local files. If you are working from a source directory that's been updated several times, you may have temporary build artefacts from previous releases which can cause build failures.
+
## Running Ruby
### Run Local Test Script
diff --git a/variable.c b/variable.c
index 78eecad2c2..c3414d61c4 100644
--- a/variable.c
+++ b/variable.c
@@ -2549,8 +2549,6 @@ struct autoload_load_arguments {
ID name;
int flag;
- VALUE result;
-
VALUE mutex;
// The specific constant which triggered the autoload code to fire:
@@ -2616,40 +2614,23 @@ autoload_load_needed(VALUE _arguments)
}
static VALUE
-autoload_feature_require(VALUE _arguments)
-{
- struct autoload_load_arguments *arguments = (struct autoload_load_arguments*)_arguments;
-
- struct autoload_const *autoload_const = arguments->autoload_const;
-
- // We save this for later use in autoload_apply_constants:
- arguments->autoload_data = rb_check_typeddata(autoload_const->autoload_data_value, &autoload_data_type);
-
- arguments->result = rb_funcall(rb_vm_top_self(), rb_intern("require"), 1, arguments->autoload_data->feature);
-
- return arguments->result;
-}
-
-static VALUE
autoload_apply_constants(VALUE _arguments)
{
RUBY_ASSERT_CRITICAL_SECTION_ENTER();
struct autoload_load_arguments *arguments = (struct autoload_load_arguments*)_arguments;
- if (arguments->result == Qtrue) {
- struct autoload_const *autoload_const;
- struct autoload_const *next;
+ struct autoload_const *autoload_const;
+ struct autoload_const *next;
- // We use safe iteration here because `autoload_const_set` will eventually invoke
- // `autoload_delete` which will remove the constant from the linked list. In theory, once
- // the `autoload_data->constants` linked list is empty, we can remove it.
+ // We use safe iteration here because `autoload_const_set` will eventually invoke
+ // `autoload_delete` which will remove the constant from the linked list. In theory, once
+ // the `autoload_data->constants` linked list is empty, we can remove it.
- // Iterate over all constants and assign them:
- ccan_list_for_each_safe(&arguments->autoload_data->constants, autoload_const, next, cnode) {
- if (autoload_const->value != Qundef) {
- autoload_const_set(autoload_const);
- }
+ // Iterate over all constants and assign them:
+ ccan_list_for_each_safe(&arguments->autoload_data->constants, autoload_const, next, cnode) {
+ if (autoload_const->value != Qundef) {
+ autoload_const_set(autoload_const);
}
}
@@ -2659,9 +2640,22 @@ autoload_apply_constants(VALUE _arguments)
}
static VALUE
-autoload_feature_require_ensure(VALUE _arguments)
+autoload_feature_require(VALUE _arguments)
{
- return rb_mutex_synchronize(autoload_mutex, autoload_apply_constants, _arguments);
+ struct autoload_load_arguments *arguments = (struct autoload_load_arguments*)_arguments;
+
+ struct autoload_const *autoload_const = arguments->autoload_const;
+
+ // We save this for later use in autoload_apply_constants:
+ arguments->autoload_data = rb_check_typeddata(autoload_const->autoload_data_value, &autoload_data_type);
+
+ VALUE result = rb_funcall(rb_vm_top_self(), rb_intern("require"), 1, arguments->autoload_data->feature);
+
+ if (RTEST(result)) {
+ return rb_mutex_synchronize(autoload_mutex, autoload_apply_constants, _arguments);
+ }
+
+ return result;
}
static VALUE
@@ -2669,15 +2663,13 @@ autoload_try_load(VALUE _arguments)
{
struct autoload_load_arguments *arguments = (struct autoload_load_arguments*)_arguments;
- // Try to require the autoload feature:
- rb_ensure(autoload_feature_require, _arguments, autoload_feature_require_ensure, _arguments);
+ VALUE result = autoload_feature_require(_arguments);
// After we loaded the feature, if the constant is not defined, we remove it completely:
rb_const_entry_t *ce = rb_const_lookup(arguments->module, arguments->name);
if (!ce || ce->value == Qundef) {
- // Absolutely ensure that any other threads will bail out, returning false:
- arguments->result = Qfalse;
+ result = Qfalse;
rb_const_remove(arguments->module, arguments->name);
}
@@ -2686,7 +2678,7 @@ autoload_try_load(VALUE _arguments)
ce->flag |= arguments->flag;
}
- return arguments->result;
+ return result;
}
VALUE
@@ -2705,7 +2697,7 @@ rb_autoload_load(VALUE module, ID name)
}
// This state is stored on thes stack and is used during the autoload process.
- struct autoload_load_arguments arguments = {.module = module, .name = name, .mutex = Qnil, .result = Qnil};
+ struct autoload_load_arguments arguments = {.module = module, .name = name, .mutex = Qnil};
// Figure out whether we can autoload the named constant:
VALUE autoload_const_value = rb_mutex_synchronize(autoload_mutex, autoload_load_needed, (VALUE)&arguments);