[前][次][番号順一覧][スレッド一覧]

ruby-changes:55656

From: Masatoshi <ko1@a...>
Date: Sat, 4 May 2019 19:29:15 +0900 (JST)
Subject: [ruby-changes:55656] Masatoshi SEKI: 8980b53a48 (trunk): add DRb::WeakIdConv (Bug #15711)

https://git.ruby-lang.org/ruby.git/commit/?id=8980b53a48

From 8980b53a48b1f55e09c5223008225e6bfa765405 Mon Sep 17 00:00:00 2001
From: Masatoshi SEKI <m_seki@m...>
Date: Sat, 4 May 2019 19:28:57 +0900
Subject: add DRb::WeakIdConv (Bug #15711)


diff --git a/lib/drb/weakidconv.rb b/lib/drb/weakidconv.rb
new file mode 100644
index 0000000..7f973dc
--- /dev/null
+++ b/lib/drb/weakidconv.rb
@@ -0,0 +1,59 @@ https://github.com/ruby/ruby/blob/trunk/lib/drb/weakidconv.rb#L1
+# frozen_string_literal: false
+require_relative 'drb'
+require 'monitor'
+
+module DRb
+
+  # To use WeakIdConv:
+  #
+  #  DRb.start_service(nil, nil, {:idconv => DRb::WeakIdConv.new})
+
+  class WeakIdConv < DRbIdConv
+    class WeakSet
+      include MonitorMixin
+      def initialize
+        super()
+        @immutable = {}
+        @map = ObjectSpace::WeakMap.new
+      end
+
+      def add(obj)
+        synchronize do
+          begin
+            @map[obj] = self 
+          rescue ArgumentError
+            @immutable[obj.__id__] = obj
+          end
+          return obj.__id__
+        end
+      end
+
+      def fetch(ref)
+        synchronize do
+          @immutable.fetch(ref) { 
+            @map.each { |key, _|
+              return key if key.__id__ == ref
+            }
+            raise RangeError.new("invalid reference")
+          }
+        end
+      end
+    end
+
+    def initialize()
+      super()
+      @weak_set = WeakSet.new
+    end
+
+    def to_obj(ref) # :nodoc:
+      return super if ref.nil?
+      @weak_set.fetch(ref)
+    end
+
+    def to_id(obj) # :nodoc:
+      return @weak_set.add(obj)
+    end
+  end
+end
+
+# DRb.install_id_conv(WeakIdConv.new)
diff --git a/test/drb/test_drbobject.rb b/test/drb/test_drbobject.rb
index 3c7b0c1..6b88087 100644
--- a/test/drb/test_drbobject.rb
+++ b/test/drb/test_drbobject.rb
@@ -1,6 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/test/drb/test_drbobject.rb#L1
 require 'test/unit'
 require 'drb'
 require 'drb/timeridconv'
+require 'drb/weakidconv'
 
 module DRbObjectTest
   class Foo
@@ -45,3 +46,19 @@ class TestDRbObjectTimerIdConv < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/drb/test_drbobject.rb#L46
     DRb.start_service(nil, nil, {:idconv => DRb::TimerIdConv.new})
   end
 end
+
+class TestDRbObjectWeakIdConv < Test::Unit::TestCase
+  include DRbObjectTest
+
+  def setup
+    DRb.start_service(nil, nil, {:idconv => DRb::WeakIdConv.new})
+  end
+
+  def test_RangeError
+    proxy = DRbObject.new("string".dup)
+    GC.start
+    assert_raise(RangeError) {
+      DRb.to_obj(proxy.__drbref)
+    }
+  end
+end
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]