|
28 | 28 | #include "id.h"
|
29 | 29 |
|
30 | 30 | #define ENABLE_ECONV_NEWLINE_OPTION 1
|
31 |
| -#define SRC_ENC_TO_DST_ENC_KEY_SIZE 128 |
32 |
| -STATIC_ASSERT(encoding_namelen, SRC_ENC_TO_DST_ENC_KEY_SIZE > (ENCODING_NAMELEN_MAX * 2 + 1)); |
| 31 | +#define SRC_ENC_TO_DST_ENC_KEY_SIZE (ENCODING_NAMELEN_MAX * 2 + 2) |
33 | 32 |
|
34 | 33 | /* VALUE rb_cEncoding = rb_define_class("Encoding", rb_cObject); */
|
35 | 34 | static VALUE rb_eUndefinedConversionError;
|
@@ -1088,26 +1087,30 @@ rb_econv_open0(rb_encoding *senc, const char *sname, rb_encoding *denc, const ch
|
1088 | 1087 | toarg.entries = NULL;
|
1089 | 1088 | toarg.num_additional = 0;
|
1090 | 1089 | char key_buf[SRC_ENC_TO_DST_ENC_KEY_SIZE] = { 0 };
|
1091 |
| - char *key; |
| 1090 | + char *key = NULL; |
1092 | 1091 | gen_src_to_dst_encodings_key(key_buf, sname, dname);
|
1093 | 1092 | VALUE managed_val;
|
1094 |
| - VALUE tbl = RUBY_ATOMIC_VALUE_LOAD(fast_transcoder_path_table); |
1095 |
| - if (rb_managed_st_table_lookup(tbl, (st_data_t)key_buf, &managed_val)) { |
1096 |
| - entries = (transcoder_entry_t **)managed_val; |
1097 |
| - } else { |
1098 |
| - num_trans = transcode_search_path(sname, dname, trans_open_i, (void *)&toarg); |
1099 |
| - entries = toarg.entries; |
1100 |
| - if (num_trans < 0) { |
1101 |
| - xfree(entries); |
1102 |
| - return NULL; |
| 1093 | + while (1) { |
| 1094 | + VALUE tbl = fast_transcoder_path_table; |
| 1095 | + if (rb_managed_st_table_lookup(tbl, (st_data_t)key_buf, &managed_val)) { |
| 1096 | + entries = (transcoder_entry_t **)managed_val; |
| 1097 | + break; |
| 1098 | + } else { |
| 1099 | + if (!entries) { |
| 1100 | + num_trans = transcode_search_path(sname, dname, trans_open_i, (void *)&toarg); |
| 1101 | + entries = toarg.entries; |
| 1102 | + if (num_trans < 0) { |
| 1103 | + xfree(entries); |
| 1104 | + return NULL; |
| 1105 | + } |
| 1106 | + } |
| 1107 | + VALUE new_tbl = rb_managed_st_table_dup(tbl); |
| 1108 | + if (!key) key = strdup(key_buf); |
| 1109 | + rb_managed_st_table_insert(new_tbl, (st_data_t)key, (VALUE)entries); |
| 1110 | + if (RUBY_ATOMIC_VALUE_CAS(fast_transcoder_path_table, tbl, new_tbl) == tbl) { |
| 1111 | + break; |
| 1112 | + } |
1103 | 1113 | }
|
1104 |
| - // No need for CAS loop if it's not most recent `fast_transcoder_table`, some values |
1105 |
| - // can be lost. It will just go through the slow path next time for the lost src/dst encoding |
1106 |
| - // pairs |
1107 |
| - VALUE new_tbl = rb_managed_st_table_dup(tbl); |
1108 |
| - key = strdup(key_buf); |
1109 |
| - rb_managed_st_table_insert(new_tbl, (st_data_t)key, (VALUE)entries); |
1110 |
| - RUBY_ATOMIC_VALUE_SET(fast_transcoder_path_table, new_tbl); |
1111 | 1114 | }
|
1112 | 1115 | }
|
1113 | 1116 |
|
|
0 commit comments