Project

General

Profile

« Previous | Next » 

Revision 63d9ab33

Added by nagachika (Tomoyuki Chikanaga) over 5 years ago

merge revision(s) 62934,63210,63215,63309: [Backport #14634]

    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