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,24 @@ 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+ } else {
1856+ st_foreach (table2 , asciicompat_encoding_i , (st_data_t )& data );
1857+ }
18431858 }
18441859
18451860 }
1846-
18471861 }
1862+ RB_VM_LOCK_LEAVE_LEV (& lev );
18481863
18491864 return data .ascii_compat_name ; // can be NULL
18501865}
@@ -2989,10 +3004,15 @@ static rb_encoding *
29893004make_encoding (const char * name )
29903005{
29913006 rb_encoding * enc ;
2992- RB_VM_LOCKING () {
2993- enc = rb_enc_find (name );
2994- if (!enc )
2995- enc = make_dummy_encoding (name );
3007+ enc = rb_enc_find (name );
3008+ if (!enc ) {
3009+ RB_VM_LOCKING () {
3010+ if (rb_enc_registered (name )) {
3011+ enc = NULL ;
3012+ } else {
3013+ enc = make_dummy_encoding (name );
3014+ }
3015+ }
29963016 }
29973017 return enc ;
29983018}
@@ -3029,14 +3049,10 @@ econv_s_asciicompat_encoding(VALUE klass, VALUE arg)
30293049 VALUE enc = Qnil ;
30303050
30313051 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- }
3052+ result_name = rb_econv_asciicompat_encoding (arg_name );
3053+ if (result_name ) {
3054+ result_enc = make_encoding (result_name );
3055+ enc = rb_enc_from_encoding (result_enc );
30403056 }
30413057 return enc ;
30423058}
0 commit comments