Currently, rb_str_new_cstr is spec'ed as a function available under both 1.8 CAPI and 1.9 CAPI in spec/ruby/optional/capi/ext/rubyspec.h. This is not true. As a version guard is correctly used in spec/ruby/optional/capi/string_spec.rb, it is only declared under 1.9 CAPI, not under 1.8 CAPI. In 1.8 mode, rb_str_new_cstr specs are only compiled, not run, thanks to the version guard. So, there is no spec failures. However, this commit suppresses the following warning from clang: spec/ruby/optional/capi/ext/string_spec.c:165:12: warning: implicit declaration of function 'rb_str_new_cstr' is invalid in C99 [-Wimplicit-function-declaration] return rb_str_new_cstr(NULL); ^ 1 warning generated. Also, #undefs aren't needed in spec/ruby/optional/capi/ext/mri.h, because rb_str_new_cstr is now correctly declared only in 1.9 CAPI.
In the Autoload parts in the VM we now do the lookup again so it's much easier to do it with the correct current scope and we follow the same lookup mechanisms as a normal constant lookup. For this we modify the Helpers for const_get so it can filter a result so the autoload is filtered and the real class or a class with the same name higher in the hierarchy is returned.
This reverts commit 2106625. This has more consequences that take a lot more effort to fix. If we want to fix this behavior we probably have to review how autoload works and change it more invasively.
This problem could cause multiple signal handling threads. When multiple threads were exec'ing, they would all request starting and stopping the signal thread. Because we weren't locking this properly, it could happen that two signal threads were starting which causes all kinds of other problems such as deadlocking.
When multiple threads would be running sub processes with for example backticks, they could deadlock. The guard makes sure we mark the before_exec handling as gc independent so we don't deadlock.
The Mutex added in 5718738 fixes the race condition but loses the ability to ensure that the signal handler only runs once. Once the mutex unlocks, the handler code can interrupt the code implementing Process.exit! and print 'signaled' again. We first lock the mutex, then check the flag. This ensures there is no race and the correct value of the flag is always seen. The flag itself ensures the handler only runs once.