1919#include "internal/object.h"
2020#include "internal/string.h"
2121#include "internal/transcode.h"
22+ #include "internal/encoding.h"
2223#include "ruby/encoding.h"
2324#include "vm_sync.h"
2425
@@ -1826,7 +1827,9 @@ rb_econv_asciicompat_encoding(const char *ascii_incompat_name)
18261827 st_table * table2 ;
18271828 struct asciicompat_encoding_t data = {0 };
18281829
1829- RB_VM_LOCKING () {
1830+ unsigned int lev ;
1831+ RB_VM_LOCK_ENTER_LEV (& lev );
1832+ {
18301833 if (st_lookup (transcoder_table , (st_data_t )ascii_incompat_name , & v )) {
18311834 table2 = (st_table * )v ;
18321835 /*
@@ -1839,12 +1842,25 @@ rb_econv_asciicompat_encoding(const char *ascii_incompat_name)
18391842 if (table2 -> num_entries == 1 ) {
18401843 data .ascii_incompat_name = ascii_incompat_name ;
18411844 data .ascii_compat_name = NULL ;
1842- st_foreach (table2 , asciicompat_encoding_i , (st_data_t )& data );
1845+ if (rb_multi_ractor_p ()) {
1846+ /*
1847+ * We need to unlock in case `load_transcoder_entry` actually loads the encoding
1848+ * and table2 could be inserted into when we unlock.
1849+ */
1850+ st_table * dup_table2 = st_copy (table2 );
1851+ RB_VM_LOCK_LEAVE_LEV (& lev );
1852+ st_foreach (dup_table2 , asciicompat_encoding_i , (st_data_t )& data );
1853+ st_free_table (dup_table2 );
1854+ RB_VM_LOCK_ENTER_LEV (& lev );
1855+ }
1856+ else {
1857+ st_foreach (table2 , asciicompat_encoding_i , (st_data_t )& data );
1858+ }
18431859 }
18441860
18451861 }
1846-
18471862 }
1863+ RB_VM_LOCK_LEAVE_LEV (& lev );
18481864
18491865 return data .ascii_compat_name ; // can be NULL
18501866}
@@ -2989,10 +3005,16 @@ static rb_encoding *
29893005make_encoding (const char * name )
29903006{
29913007 rb_encoding * enc ;
2992- RB_VM_LOCKING () {
2993- enc = rb_enc_find (name );
2994- if (!enc )
2995- enc = make_dummy_encoding (name );
3008+ enc = rb_enc_find (name );
3009+ if (!enc ) {
3010+ RB_VM_LOCKING () {
3011+ if (rb_enc_registered (name )) {
3012+ enc = NULL ;
3013+ }
3014+ else {
3015+ enc = make_dummy_encoding (name );
3016+ }
3017+ }
29963018 }
29973019 return enc ;
29983020}
@@ -3029,14 +3051,10 @@ econv_s_asciicompat_encoding(VALUE klass, VALUE arg)
30293051 VALUE enc = Qnil ;
30303052
30313053 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- }
3054+ result_name = rb_econv_asciicompat_encoding (arg_name );
3055+ if (result_name ) {
3056+ result_enc = make_encoding (result_name );
3057+ enc = rb_enc_from_encoding (result_enc );
30403058 }
30413059 return enc ;
30423060}
0 commit comments