20
20
#include "ccan/list/list.h"
21
21
#include "id_table.h"
22
22
#include "debug_counter.h"
23
+ #include "vm_core.h"
23
24
24
25
struct rb_id_table * rb_global_tbl ;
25
26
static ID autoload , classpath , tmp_classpath , classid ;
@@ -1859,6 +1860,7 @@ struct autoload_data_i {
1859
1860
rb_const_flag_t flag ;
1860
1861
VALUE value ;
1861
1862
struct autoload_state * state ; /* points to on-stack struct */
1863
+ rb_serial_t fork_gen ;
1862
1864
};
1863
1865
1864
1866
static void
@@ -1881,8 +1883,18 @@ static const rb_data_type_t autoload_data_i_type = {
1881
1883
0 , 0 , RUBY_TYPED_FREE_IMMEDIATELY
1882
1884
};
1883
1885
1884
- #define check_autoload_data (av ) \
1885
- (struct autoload_data_i *)rb_check_typeddata((av), &autoload_data_i_type)
1886
+ static struct autoload_data_i *
1887
+ get_autoload_data (VALUE av )
1888
+ {
1889
+ struct autoload_data_i * ele = rb_check_typeddata (av , & autoload_data_i_type );
1890
+
1891
+ /* do not reach across stack for ->state after forking: */
1892
+ if (ele && ele -> state && ele -> fork_gen != GET_VM ()-> fork_gen ) {
1893
+ ele -> state = 0 ;
1894
+ ele -> fork_gen = 0 ;
1895
+ }
1896
+ return ele ;
1897
+ }
1886
1898
1887
1899
RUBY_FUNC_EXPORTED void
1888
1900
rb_autoload (VALUE mod , ID id , const char * file )
@@ -1982,7 +1994,7 @@ check_autoload_required(VALUE mod, ID id, const char **loadingpath)
1982
1994
const char * loading ;
1983
1995
int safe ;
1984
1996
1985
- if (!(load = autoload_data (mod , id )) || !(ele = check_autoload_data (load ))) {
1997
+ if (!(load = autoload_data (mod , id )) || !(ele = get_autoload_data (load ))) {
1986
1998
return 0 ;
1987
1999
}
1988
2000
file = ele -> feature ;
@@ -2020,7 +2032,7 @@ rb_autoloading_value(VALUE mod, ID id, VALUE* value, rb_const_flag_t *flag)
2020
2032
VALUE load ;
2021
2033
struct autoload_data_i * ele ;
2022
2034
2023
- if (!(load = autoload_data (mod , id )) || !(ele = check_autoload_data (load ))) {
2035
+ if (!(load = autoload_data (mod , id )) || !(ele = get_autoload_data (load ))) {
2024
2036
return 0 ;
2025
2037
}
2026
2038
if (ele -> state && ele -> state -> thread == rb_thread_current ()) {
@@ -2087,8 +2099,9 @@ autoload_reset(VALUE arg)
2087
2099
int need_wakeups = 0 ;
2088
2100
2089
2101
if (state -> ele -> state == state ) {
2090
- need_wakeups = 1 ;
2091
- state -> ele -> state = 0 ;
2102
+ need_wakeups = 1 ;
2103
+ state -> ele -> state = 0 ;
2104
+ state -> ele -> fork_gen = 0 ;
2092
2105
}
2093
2106
2094
2107
/* At the last, move a value defined in autoload to constant table */
@@ -2170,7 +2183,7 @@ rb_autoload_load(VALUE mod, ID id)
2170
2183
if (src && loading && strcmp (src , loading ) == 0 ) return Qfalse ;
2171
2184
2172
2185
/* set ele->state for a marker of autoloading thread */
2173
- if (!(ele = check_autoload_data (load ))) {
2186
+ if (!(ele = get_autoload_data (load ))) {
2174
2187
return Qfalse ;
2175
2188
}
2176
2189
@@ -2180,6 +2193,7 @@ rb_autoload_load(VALUE mod, ID id)
2180
2193
state .thread = rb_thread_current ();
2181
2194
if (!ele -> state ) {
2182
2195
ele -> state = & state ;
2196
+ ele -> fork_gen = GET_VM ()-> fork_gen ;
2183
2197
2184
2198
/*
2185
2199
* autoload_reset will wake up any threads added to this
@@ -2217,7 +2231,7 @@ rb_autoload_p(VALUE mod, ID id)
2217
2231
}
2218
2232
load = check_autoload_required (mod , id , 0 );
2219
2233
if (!load ) return Qnil ;
2220
- return (ele = check_autoload_data (load )) ? ele -> feature : Qnil ;
2234
+ return (ele = get_autoload_data (load )) ? ele -> feature : Qnil ;
2221
2235
}
2222
2236
2223
2237
void
@@ -2646,7 +2660,7 @@ current_autoload_data(VALUE mod, ID id)
2646
2660
struct autoload_data_i * ele ;
2647
2661
VALUE load = autoload_data (mod , id );
2648
2662
if (!load ) return 0 ;
2649
- ele = check_autoload_data (load );
2663
+ ele = get_autoload_data (load );
2650
2664
if (!ele ) return 0 ;
2651
2665
/* for autoloading thread, keep the defined value to autoloading storage */
2652
2666
if (ele -> state && (ele -> state -> thread == rb_thread_current ())) {
0 commit comments