Skip to content
  • nagachika's avatar
    63d9ab33
    merge revision(s) 62934,63210,63215,63309: [Backport #14634] · 63d9ab33
    nagachika authored
    	thread_sync.c: avoid reaching across stacks of dead threads
    
    	rb_ensure is insufficient cleanup for fork and we must
    	reinitialize all waitqueues in the child process.
    
    	Unfortunately this increases the footprint of ConditionVariable,
    	Queue and SizedQueue by 8 bytes on 32-bit (16 bytes on 64-bit).
    
    	[ruby-core:86316] [Bug #14634]
    
    	variable.c: fix thread + fork errors in autoload
    
    	This is fairly non-intrusive bugfix to prevent children
    	from trying to reach into thread stacks of the parent.
    	I will probably reuse this idea and redo r62934, too
    	(same bug).
    
    	* vm_core.h (typedef struct rb_vm_struct): add fork_gen counter
    	* thread.c (rb_thread_atfork_internal): increment fork_gen
    	* variable.c (struct autoload_data_i): store fork_gen
    	* variable.c (check_autoload_data): remove (replaced with get_...)
    	* variable.c (get_autoload_data): check fork_gen when retrieving
    	* variable.c (check_autoload_required): use get_autoload_data
    	* variable.c (rb_autoloading_value): ditto
    	* variable.c (rb_autoload_p): ditto
    	* variable.c (current_autoload_data): ditto
    	* variable.c (autoload_reset): reset fork_gen, adjust indent
    	* variable.c (rb_autoload_load): set fork_gen when setting state
    	* test/ruby/test_autoload.rb (test_autoload_fork): new test
    	  [ruby-core:86410] [Bug #14634]
    
    	thread_sync: redo r62934 to use fork_gen
    
    	Instead of maintaining linked-lists to store all
    	rb_queue/rb_szqueue/rb_condvar structs; store only a fork_gen
    	serial number to simplify management of these items.
    
    	This reduces initialization costs and avoids the up-front cost
    	of resetting all Queue/SizedQueue/ConditionVariable objects at
    	fork while saving 8 bytes per-structure on 64-bit.  There are no
    	savings on 32-bit.
    
    	* thread.c (rb_thread_atfork_internal): remove rb_thread_sync_reset_all call
    	* thread_sync.c (rb_thread_sync_reset_all): remove
    	* thread_sync.c (queue_live): remove
    	* thread_sync.c (queue_free): remove
    	* thread_sync.c (struct rb_queue): s/live/fork_gen/
    	* thread_sync.c (queue_data_type): use default free
    	* thread_sync.c (queue_alloc): remove list_add
    	* thread_sync.c (queue_fork_check): new function
    	* thread_sync.c (queue_ptr): call queue_fork_check
    	* thread_sync.c (szqueue_free): remove
    	* thread_sync.c (szqueue_data_type): use default free
    	* thread_sync.c (szqueue_alloc): remove list_add
    	* thread_sync.c (szqueue_ptr):  check fork_gen via queue_fork_check
    	* thread_sync.c (struct rb_condvar): s/live/fork_gen/
    	* thread_sync.c (condvar_free): remove
    	* thread_sync.c (cv_data_type): use default free
    	* thread_sync.c (condvar_ptr): check fork_gen
    	* thread_sync.c (condvar_alloc): remove list_add
    	  [ruby-core:86316] [Bug #14634]
    
    	thread_sync.c (condvar_ptr): reset fork_gen after forking
    
    	Otherwise the condition variable waiter list will always
    	be empty, which is wrong :x
    
    	[Bug #14725] [Bug #14634]
    
    git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_5@66912 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
    63d9ab33
    merge revision(s) 62934,63210,63215,63309: [Backport #14634]
    nagachika authored
    	thread_sync.c: avoid reaching across stacks of dead threads
    
    	rb_ensure is insufficient cleanup for fork and we must
    	reinitialize all waitqueues in the child process.
    
    	Unfortunately this increases the footprint of ConditionVariable,
    	Queue and SizedQueue by 8 bytes on 32-bit (16 bytes on 64-bit).
    
    	[ruby-core:86316] [Bug #14634]
    
    	variable.c: fix thread + fork errors in autoload
    
    	This is fairly non-intrusive bugfix to prevent children
    	from trying to reach into thread stacks of the parent.
    	I will probably reuse this idea and redo r62934, too
    	(same bug).
    
    	* vm_core.h (typedef struct rb_vm_struct): add fork_gen counter
    	* thread.c (rb_thread_atfork_internal): increment fork_gen
    	* variable.c (struct autoload_data_i): store fork_gen
    	* variable.c (check_autoload_data): remove (replaced with get_...)
    	* variable.c (get_autoload_data): check fork_gen when retrieving
    	* variable.c (check_autoload_required): use get_autoload_data
    	* variable.c (rb_autoloading_value): ditto
    	* variable.c (rb_autoload_p): ditto
    	* variable.c (current_autoload_data): ditto
    	* variable.c (autoload_reset): reset fork_gen, adjust indent
    	* variable.c (rb_autoload_load): set fork_gen when setting state
    	* test/ruby/test_autoload.rb (test_autoload_fork): new test
    	  [ruby-core:86410] [Bug #14634]
    
    	thread_sync: redo r62934 to use fork_gen
    
    	Instead of maintaining linked-lists to store all
    	rb_queue/rb_szqueue/rb_condvar structs; store only a fork_gen
    	serial number to simplify management of these items.
    
    	This reduces initialization costs and avoids the up-front cost
    	of resetting all Queue/SizedQueue/ConditionVariable objects at
    	fork while saving 8 bytes per-structure on 64-bit.  There are no
    	savings on 32-bit.
    
    	* thread.c (rb_thread_atfork_internal): remove rb_thread_sync_reset_all call
    	* thread_sync.c (rb_thread_sync_reset_all): remove
    	* thread_sync.c (queue_live): remove
    	* thread_sync.c (queue_free): remove
    	* thread_sync.c (struct rb_queue): s/live/fork_gen/
    	* thread_sync.c (queue_data_type): use default free
    	* thread_sync.c (queue_alloc): remove list_add
    	* thread_sync.c (queue_fork_check): new function
    	* thread_sync.c (queue_ptr): call queue_fork_check
    	* thread_sync.c (szqueue_free): remove
    	* thread_sync.c (szqueue_data_type): use default free
    	* thread_sync.c (szqueue_alloc): remove list_add
    	* thread_sync.c (szqueue_ptr):  check fork_gen via queue_fork_check
    	* thread_sync.c (struct rb_condvar): s/live/fork_gen/
    	* thread_sync.c (condvar_free): remove
    	* thread_sync.c (cv_data_type): use default free
    	* thread_sync.c (condvar_ptr): check fork_gen
    	* thread_sync.c (condvar_alloc): remove list_add
    	  [ruby-core:86316] [Bug #14634]
    
    	thread_sync.c (condvar_ptr): reset fork_gen after forking
    
    	Otherwise the condition variable waiter list will always
    	be empty, which is wrong :x
    
    	[Bug #14725] [Bug #14634]
    
    git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_5@66912 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Loading