19
19
#include "internal/object.h"
20
20
#include "internal/string.h"
21
21
#include "internal/transcode.h"
22
+ #include "internal/encoding.h"
22
23
#include "ruby/encoding.h"
23
24
#include "vm_sync.h"
24
25
@@ -1826,7 +1827,9 @@ rb_econv_asciicompat_encoding(const char *ascii_incompat_name)
1826
1827
st_table * table2 ;
1827
1828
struct asciicompat_encoding_t data = {0 };
1828
1829
1829
- RB_VM_LOCKING () {
1830
+ unsigned int lev ;
1831
+ RB_VM_LOCK_ENTER_LEV (& lev );
1832
+ {
1830
1833
if (st_lookup (transcoder_table , (st_data_t )ascii_incompat_name , & v )) {
1831
1834
table2 = (st_table * )v ;
1832
1835
/*
@@ -1839,12 +1842,25 @@ rb_econv_asciicompat_encoding(const char *ascii_incompat_name)
1839
1842
if (table2 -> num_entries == 1 ) {
1840
1843
data .ascii_incompat_name = ascii_incompat_name ;
1841
1844
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
+ }
1843
1859
}
1844
1860
1845
1861
}
1846
-
1847
1862
}
1863
+ RB_VM_LOCK_LEAVE_LEV (& lev );
1848
1864
1849
1865
return data .ascii_compat_name ; // can be NULL
1850
1866
}
@@ -2989,10 +3005,16 @@ static rb_encoding *
2989
3005
make_encoding (const char * name )
2990
3006
{
2991
3007
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
+ }
2996
3018
}
2997
3019
return enc ;
2998
3020
}
@@ -3029,14 +3051,10 @@ econv_s_asciicompat_encoding(VALUE klass, VALUE arg)
3029
3051
VALUE enc = Qnil ;
3030
3052
3031
3053
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 );
3040
3058
}
3041
3059
return enc ;
3042
3060
}
0 commit comments