diff options
author | Masatoshi SEKI <[email protected]> | 2019-05-04 19:28:57 +0900 |
---|---|---|
committer | Masatoshi SEKI <[email protected]> | 2019-05-04 19:28:57 +0900 |
commit | 8980b53a48b1f55e09c5223008225e6bfa765405 (patch) | |
tree | 0f840100eaf38b157b4d3523b952f1c2c3a7ea1e /lib/drb | |
parent | b72623012d74abdb06210153ed48c9e2fa075bbd (diff) |
add DRb::WeakIdConv (Bug #15711)
Diffstat (limited to 'lib/drb')
-rw-r--r-- | lib/drb/weakidconv.rb | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/lib/drb/weakidconv.rb b/lib/drb/weakidconv.rb new file mode 100644 index 0000000000..7f973dc8cc --- /dev/null +++ b/lib/drb/weakidconv.rb @@ -0,0 +1,59 @@ +# 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) |