ruby-changes:43044
From: seki <ko1@a...>
Date: Sun, 22 May 2016 20:03:50 +0900 (JST)
Subject: [ruby-changes:43044] seki:r55118 (trunk): use finalizer trick instead of thread.
seki 2016-05-22 20:03:43 +0900 (Sun, 22 May 2016) New Revision: 55118 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=55118 Log: use finalizer trick instead of thread. Modified files: trunk/ChangeLog trunk/lib/drb/timeridconv.rb trunk/test/drb/ut_timerholder.rb Index: lib/drb/timeridconv.rb =================================================================== --- lib/drb/timeridconv.rb (revision 55117) +++ lib/drb/timeridconv.rb (revision 55118) @@ -24,7 +24,7 @@ module DRb https://github.com/ruby/ruby/blob/trunk/lib/drb/timeridconv.rb#L24 @gc = {} @renew = {} @keeping = keeping - @expires = Time.now + @keeping + @expires = nil end def add(obj) @@ -32,18 +32,16 @@ module DRb https://github.com/ruby/ruby/blob/trunk/lib/drb/timeridconv.rb#L32 rotate key = obj.__id__ @renew[key] = obj + invoke_keeper return key end end - def fetch(key, dv=@sentinel) + def fetch(key) synchronize do rotate obj = peek(key) - if obj == @sentinel - return dv unless dv == @sentinel - raise InvalidIndexError - end + raise InvalidIndexError if obj == @sentinel @renew[key] = obj # KeepIt return obj end @@ -51,25 +49,28 @@ module DRb https://github.com/ruby/ruby/blob/trunk/lib/drb/timeridconv.rb#L49 private def peek(key) - synchronize do - return @renew.fetch(key) { @gc.fetch(key, @sentinel) } - end + return @renew.fetch(key) { @gc.fetch(key, @sentinel) } end - def rotate - synchronize do - return if @expires > Time.now - @gc = @renew # GCed - @renew = {} - @expires = Time.now + @keeping - end + def invoke_keeper + return if @expires + @expires = Time.now + @keeping + on_gc + end + + def on_gc + return unless Thread.main.alive? + return if @expires.nil? + Thread.new { rotate } if @expires < Time.now + ObjectSpace.define_finalizer(Object.new) {on_gc} end - def keeper - Thread.new do - loop do - rotate - sleep(@keeping) + def rotate + synchronize do + if @expires &.< Time.now + @gc = @renew # GCed + @renew = {} + @expires = @gc.empty? ? nil : Time.now + @keeping end end end Index: ChangeLog =================================================================== --- ChangeLog (revision 55117) +++ ChangeLog (revision 55118) @@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sun May 22 20:01:21 2016 Masatoshi SEKI <m_seki@m...> + + * lib/drb/timeridconv.rb: use finalizer trick instead of thread. + + * test/drb/ut_timerholder.rb: ditto. + Sun May 22 17:25:18 2016 Martin Duerst <duerst@i...> * test/ruby/enc/test_case_options.rb: adjust test class name Index: test/drb/ut_timerholder.rb =================================================================== --- test/drb/ut_timerholder.rb (revision 55117) +++ test/drb/ut_timerholder.rb (revision 55118) @@ -12,7 +12,6 @@ class TimerIdConvTest < Test::Unit::Test https://github.com/ruby/ruby/blob/trunk/test/drb/ut_timerholder.rb#L12 key = idconv.to_id(self) assert_equal(key, self.__id__) sleep(keeping) - assert_equal(idconv.to_id(false), false.__id__) assert_equal(idconv.to_obj(key), self) sleep(keeping) @@ -24,11 +23,48 @@ class TimerIdConvTest < Test::Unit::Test https://github.com/ruby/ruby/blob/trunk/test/drb/ut_timerholder.rb#L23 sleep(keeping) assert_raise do - assert_equal(idconv.to_obj(key)) + assert_equal(idconv.to_obj(key), self) + end + + assert_raise do + assert_equal(idconv.to_obj(false.__id__), false) end + key = idconv.to_id(self) + assert_equal(key, self.__id__) + assert_equal(idconv.to_id(true), true.__id__) + sleep(keeping) + GC.start + sleep(keeping) + GC.start + assert_raise do + assert_equal(idconv.to_obj(key), self) + end + end + + def test_usecase_02 + keeping = 0.1 + idconv = DRb::TimerIdConv.new(keeping) + + key = idconv.to_id(self) + assert_equal(key, self.__id__) + sleep(keeping) + GC.start + sleep(keeping) + GC.start + assert_raise do + assert_equal(idconv.to_obj(key), self) + end + GC.start + + key = idconv.to_id(self) + assert_equal(key, self.__id__) + sleep(keeping) + GC.start + sleep(keeping) + GC.start assert_raise do - assert_equal(idconv.to_obj(false.__id__)) + assert_equal(idconv.to_obj(key), self) end end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/