Skip to content

Commit 8c3d8d5

Browse files
committed
Use CAS in rb_econv_open0
1 parent 48ddbab commit 8c3d8d5

File tree

1 file changed

+22
-19
lines changed

1 file changed

+22
-19
lines changed

transcode.c

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@
2828
#include "id.h"
2929

3030
#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)
3332

3433
/* VALUE rb_cEncoding = rb_define_class("Encoding", rb_cObject); */
3534
static VALUE rb_eUndefinedConversionError;
@@ -1088,26 +1087,30 @@ rb_econv_open0(rb_encoding *senc, const char *sname, rb_encoding *denc, const ch
10881087
toarg.entries = NULL;
10891088
toarg.num_additional = 0;
10901089
char key_buf[SRC_ENC_TO_DST_ENC_KEY_SIZE] = { 0 };
1091-
char *key;
1090+
char *key = NULL;
10921091
gen_src_to_dst_encodings_key(key_buf, sname, dname);
10931092
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+
}
11031113
}
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);
11111114
}
11121115
}
11131116

0 commit comments

Comments
 (0)