From dc8d92ea1d5116de976d556c3c7ca3bff1184e07 Mon Sep 17 00:00:00 2001 From: seki Date: Sun, 22 May 2016 11:03:43 +0000 Subject: use finalizer trick instead of thread. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55118 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/drb/timeridconv.rb | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) (limited to 'lib') diff --git a/lib/drb/timeridconv.rb b/lib/drb/timeridconv.rb index 7e2a6cf998..0f45f4a08e 100644 --- a/lib/drb/timeridconv.rb +++ b/lib/drb/timeridconv.rb @@ -24,7 +24,7 @@ module DRb @gc = {} @renew = {} @keeping = keeping - @expires = Time.now + @keeping + @expires = nil end def add(obj) @@ -32,18 +32,16 @@ module DRb 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 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 -- cgit v1.2.3