Bug #10443 » 0001-thread.c-reinitialize-keeping-mutexes-on-fork.patch
| test/ruby/test_thread.rb | ||
|---|---|---|
|
assert_not_predicate(status, :signaled?, FailDesc[status, bug9751, output])
|
||
|
assert_predicate(status, :success?, bug9751)
|
||
|
end if Process.respond_to?(:fork)
|
||
|
def test_fork_while_lock_held
|
||
|
bug10443 = '[ruby-core:65950] [Bug #10443]'
|
||
|
assert_separately([], <<-EOS)
|
||
|
require 'tempfile'
|
||
|
require 'thread'
|
||
|
tmp = Tempfile.new('bug10443')
|
||
|
mutex = Mutex.new
|
||
|
mutex.lock
|
||
|
th = Thread.new do
|
||
|
mutex.synchronize { sleep }
|
||
|
end
|
||
|
Thread.pass until th.stop?
|
||
|
orig = $stderr.dup
|
||
|
$stderr.reopen(tmp.path, "a")
|
||
|
$VERBOSE = true
|
||
|
pid = Process.fork { exit!(mutex.locked?) }
|
||
|
$VERBOSE = false
|
||
|
$stderr.reopen(orig)
|
||
|
orig.close
|
||
|
th.kill
|
||
|
pid, status = Process.waitpid2(pid)
|
||
|
assert_equal(true, status.success?, status.inspect)
|
||
|
tmp.rewind
|
||
|
assert_match(/\\b1 Mutex resource\\(s\\) leaked on fork$/, tmp.read)
|
||
|
EOS
|
||
|
end if Process.respond_to?(:fork)
|
||
|
end
|
||
| thread.c | ||
|---|---|---|
|
void
|
||
|
rb_thread_atfork(void)
|
||
|
{
|
||
|
rb_thread_t *th = GET_THREAD();
|
||
|
size_t n = 0;
|
||
|
rb_mutex_t *mutex;
|
||
|
rb_thread_atfork_internal(terminate_atfork_i);
|
||
|
GET_THREAD()->join_list = NULL;
|
||
|
th->join_list = NULL;
|
||
|
/* we preserve mutex state across fork, but ensure we do not deadlock */
|
||
|
mutex = th->keeping_mutexes;
|
||
|
while (mutex) {
|
||
|
assert(mutex->th == th);
|
||
|
n++;
|
||
|
/* we cannot safely destroy here, zero instead */
|
||
|
MEMZERO(&mutex->lock, rb_nativethread_lock_t, 1);
|
||
|
MEMZERO(&mutex->cond, rb_nativethread_cond_t, 1);
|
||
|
native_mutex_initialize(&mutex->lock);
|
||
|
native_cond_initialize(&mutex->cond, RB_CONDATTR_CLOCK_MONOTONIC);
|
||
|
mutex = mutex->next_mutex;
|
||
|
}
|
||
|
if (n) {
|
||
|
rb_warn("%"PRIuSIZE" Mutex resource(s) leaked on fork", n);
|
||
|
}
|
||
|
/* We don't want reproduce CVE-2003-0900. */
|
||
|
rb_reset_random_seed();
|
||
|
-
|
||
- « Previous
- 1
- 2
- 3
- Next »