[ruby-cvs:68142] akr:r60961 (trunk): Replace Kernel#pp after PP class is defined.

akr at ruby-lang.org akr at ruby-lang.org
Fri Dec 1 19:48:29 JST 2017


akr	2017-12-01 19:48:29 +0900 (Fri, 01 Dec 2017)

  New Revision: 60961

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=60961

  Log:
    Replace Kernel#pp after PP class is defined.
    
    Avoid a race condition which a context switch
    occur after replacing Kernel#pp but before
    defining PP class.
    
    Following patch, inserting sleep, makes
    this problem reproducible.
    
    ```
    Index: lib/pp.rb
    ===================================================================
    --- lib/pp.rb	(revision 60960)
    +++ lib/pp.rb	(working copy)
    @@ -26,6 +26,7 @@ module Kernel
       end
       undef __pp_backup__ if method_defined?(:__pp_backup__)
       module_function :pp
    +  sleep 1 # thread context switch
     end
     
     ##
    ```
    
    With the above patch, "uninitialized constant Kernel::PP" can
    happen as as follows.
    
    ```
    % ./ruby -w -Ilib -e '
    t1 = Thread.new {
      Thread.current.report_on_exception = true
      pp :foo1
    }
    t2 = Thread.new {
      Thread.current.report_on_exception = true
      sleep 0.5
      pp :foo2
    }
    t1.join rescue nil
    t2.join rescue nil
    '
    #<Thread:0x000055dbf926eaa0 at -e:6 run> terminated with exception:
    Traceback (most recent call last):
    3: from -e:9:in `block in <main>'
    2: from /home/ruby/tst2/ruby/lib/pp.rb:22:in `pp'
    1: from /home/ruby/tst2/ruby/lib/pp.rb:22:in `each'
    /home/ruby/tst2/ruby/lib/pp.rb:23:in `block in pp': uninitialized constant Kernel::PP (NameError)
    :foo1
    ```

  Modified files:
    trunk/lib/pp.rb


More information about the ruby-cvs mailing list