Fix Thread#native_thread_id being cached across fork (#8418)
The native thread ID can and does change on some operating systems (e.g. Linux) after forking, so it needs to be re-queried. [Bug #19873]
This commit is contained in:
parent
f08cac066e
commit
0117a6d389
Notes:
git
2023-09-15 01:33:51 +00:00
Merged-By: nurse <naruse@airemix.jp>
@ -3,6 +3,7 @@
|
||||
require 'test/unit'
|
||||
require "rbconfig/sizeof"
|
||||
require "timeout"
|
||||
require "fiddle"
|
||||
|
||||
class TestThread < Test::Unit::TestCase
|
||||
class Thread < ::Thread
|
||||
@ -1443,6 +1444,35 @@ q.pop
|
||||
assert_nil th1.native_thread_id
|
||||
end
|
||||
|
||||
def test_thread_native_thread_id_across_fork_on_linux
|
||||
rtld_default = Fiddle.dlopen(nil)
|
||||
omit "this test is only for Linux" unless rtld_default.sym_defined?('gettid')
|
||||
|
||||
gettid = Fiddle::Function.new(rtld_default['gettid'], [], Fiddle::TYPE_INT)
|
||||
|
||||
parent_thread_id = Thread.main.native_thread_id
|
||||
real_parent_thread_id = gettid.call
|
||||
|
||||
assert_equal real_parent_thread_id, parent_thread_id
|
||||
|
||||
child_lines = nil
|
||||
IO.popen('-') do |pipe|
|
||||
if pipe
|
||||
# parent
|
||||
child_lines = pipe.read.lines
|
||||
else
|
||||
# child
|
||||
puts Thread.main.native_thread_id
|
||||
puts gettid.call
|
||||
end
|
||||
end
|
||||
child_thread_id = child_lines[0].chomp.to_i
|
||||
real_child_thread_id = child_lines[1].chomp.to_i
|
||||
|
||||
assert_equal real_child_thread_id, child_thread_id
|
||||
refute_equal parent_thread_id, child_thread_id
|
||||
end
|
||||
|
||||
def test_thread_interrupt_for_killed_thread
|
||||
opts = { timeout: 5, timeout_error: nil }
|
||||
|
||||
|
@ -637,6 +637,18 @@ rb_thread_sched_destroy(struct rb_thread_sched *sched)
|
||||
clear_thread_cache_altstack();
|
||||
}
|
||||
|
||||
#ifdef RB_THREAD_T_HAS_NATIVE_ID
|
||||
static int
|
||||
get_native_thread_id(void)
|
||||
{
|
||||
#ifdef __linux__
|
||||
return (int)syscall(SYS_gettid);
|
||||
#elif defined(__FreeBSD__)
|
||||
return pthread_getthreadid_np();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_WORKING_FORK)
|
||||
static void thread_cache_reset(void);
|
||||
static void
|
||||
@ -646,6 +658,9 @@ thread_sched_atfork(struct rb_thread_sched *sched)
|
||||
thread_cache_reset();
|
||||
rb_thread_sched_init(sched);
|
||||
thread_sched_to_running(sched, GET_THREAD());
|
||||
#ifdef RB_THREAD_T_HAS_NATIVE_ID
|
||||
GET_THREAD()->nt->tid = get_native_thread_id();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -693,18 +708,6 @@ ruby_thread_set_native(rb_thread_t *th)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef RB_THREAD_T_HAS_NATIVE_ID
|
||||
static int
|
||||
get_native_thread_id(void)
|
||||
{
|
||||
#ifdef __linux__
|
||||
return (int)syscall(SYS_gettid);
|
||||
#elif defined(__FreeBSD__)
|
||||
return pthread_getthreadid_np();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
native_thread_init(struct rb_native_thread *nt)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user