@@ -1826,7 +1826,9 @@ rb_econv_asciicompat_encoding(const char *ascii_incompat_name)
18261826 st_table * table2 ;
18271827 struct asciicompat_encoding_t data = {0 };
18281828
1829- RB_VM_LOCKING () {
1829+ unsigned int lev ;
1830+ RB_VM_LOCK_ENTER_LEV (& lev );
1831+ {
18301832 if (st_lookup (transcoder_table , (st_data_t )ascii_incompat_name , & v )) {
18311833 table2 = (st_table * )v ;
18321834 /*
@@ -1839,12 +1841,24 @@ rb_econv_asciicompat_encoding(const char *ascii_incompat_name)
18391841 if (table2 -> num_entries == 1 ) {
18401842 data .ascii_incompat_name = ascii_incompat_name ;
18411843 data .ascii_compat_name = NULL ;
1842- st_foreach (table2 , asciicompat_encoding_i , (st_data_t )& data );
1844+ if (rb_multi_ractor_p ()) {
1845+ /*
1846+ * We need to unlock in case `load_transcoder_entry` actually loads the encoding
1847+ * and table2 could be inserted into when we unlock.
1848+ */
1849+ st_table * dup_table2 = st_copy (table2 );
1850+ RB_VM_LOCK_LEAVE_LEV (& lev );
1851+ st_foreach (dup_table2 , asciicompat_encoding_i , (st_data_t )& data );
1852+ st_free_table (dup_table2 );
1853+ RB_VM_LOCK_ENTER_LEV (& lev );
1854+ } else {
1855+ st_foreach (table2 , asciicompat_encoding_i , (st_data_t )& data );
1856+ }
18431857 }
18441858
18451859 }
1846-
18471860 }
1861+ RB_VM_LOCK_LEAVE_LEV (& lev );
18481862
18491863 return data .ascii_compat_name ; // can be NULL
18501864}
@@ -2989,10 +3003,15 @@ static rb_encoding *
29893003make_encoding (const char * name )
29903004{
29913005 rb_encoding * enc ;
2992- RB_VM_LOCKING () {
2993- enc = rb_enc_find (name );
2994- if (!enc )
2995- enc = make_dummy_encoding (name );
3006+ enc = rb_enc_find (name );
3007+ if (!enc ) {
3008+ RB_VM_LOCKING () {
3009+ if (rb_enc_registered (name )) {
3010+ enc = NULL ;
3011+ } else {
3012+ enc = make_dummy_encoding (name );
3013+ }
3014+ }
29963015 }
29973016 return enc ;
29983017}
@@ -3029,14 +3048,10 @@ econv_s_asciicompat_encoding(VALUE klass, VALUE arg)
30293048 VALUE enc = Qnil ;
30303049
30313050 enc_arg (& arg , & arg_name , & arg_enc );
3032-
3033- RB_VM_LOCKING () {
3034- result_name = rb_econv_asciicompat_encoding (arg_name );
3035-
3036- if (result_name ) {
3037- result_enc = make_encoding (result_name );
3038- enc = rb_enc_from_encoding (result_enc );
3039- }
3051+ result_name = rb_econv_asciicompat_encoding (arg_name );
3052+ if (result_name ) {
3053+ result_enc = make_encoding (result_name );
3054+ enc = rb_enc_from_encoding (result_enc );
30403055 }
30413056 return enc ;
30423057}
0 commit comments