Don't insert an entry to loading_tbl if another thread succeed to load.

If rb_thread_shield_wait() returns Qfalse, the file has been successfully
loaded by another thread, so there is no need to insert a new entry into
loading_tbl.  [ruby-core:78464] [Bug #12999]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56985 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
shugo 2016-12-05 11:10:05 +00:00
Родитель 74ba0cfc62
Коммит 11f9b8c05c
2 изменённых файлов: 6 добавлений и 6 удалений

8
load.c
Просмотреть файл

@ -745,9 +745,6 @@ load_lock(const char *ftptr)
} }
switch (rb_thread_shield_wait((VALUE)data)) { switch (rb_thread_shield_wait((VALUE)data)) {
case Qfalse: case Qfalse:
data = (st_data_t)ftptr;
st_insert(loading_tbl, data, (st_data_t)rb_thread_shield_new());
return 0;
case Qnil: case Qnil:
return 0; return 0;
} }
@ -759,7 +756,10 @@ release_thread_shield(st_data_t *key, st_data_t *value, st_data_t done, int exis
{ {
VALUE thread_shield = (VALUE)*value; VALUE thread_shield = (VALUE)*value;
if (!existing) return ST_STOP; if (!existing) return ST_STOP;
if (done ? rb_thread_shield_destroy(thread_shield) : rb_thread_shield_release(thread_shield)) { if (done) {
rb_thread_shield_destroy(thread_shield);
}
else if (rb_thread_shield_release(thread_shield)) {
/* still in-use */ /* still in-use */
return ST_CONTINUE; return ST_CONTINUE;
} }

Просмотреть файл

@ -697,9 +697,9 @@ class TestRequire < Test::Unit::TestCase
bug7530 = '[ruby-core:50645]' bug7530 = '[ruby-core:50645]'
Tempfile.create(%w'bug-7530- .rb') {|script| Tempfile.create(%w'bug-7530- .rb') {|script|
script.close script.close
assert_in_out_err([{"RUBYOPT" => nil}, "-", script.path], <<-INPUT, %w(:ok), [], bug7530, timeout: 20) assert_in_out_err([{"RUBYOPT" => nil}, "-", script.path], <<-INPUT, %w(:ok), [], bug7530, timeout: 40)
PATH = ARGV.shift PATH = ARGV.shift
THREADS = 2 THREADS = 4
ITERATIONS_PER_THREAD = 1000 ITERATIONS_PER_THREAD = 1000
THREADS.times.map { THREADS.times.map {