OSDN Git Service

FIRST REPOSITORY
[eos/hostdependOTHERS.git] / ALPHALINUX5 / util / ALPHALINUX5 / lib / ruby / 1.6 / weakref.rb
1 # Weak Reference class that does not bother GCing.
2 #
3 # Usage:
4 #   foo = Object.new
5 #   foo = Object.new
6 #   p foo.to_s                  # original's class
7 #   foo = WeakRef.new(foo)
8 #   p foo.to_s                  # should be same class
9 #   ObjectSpace.garbage_collect
10 #   p foo.to_s                  # should raise exception (recycled)
11
12 require "delegate"
13
14 class WeakRef<Delegator
15
16   class RefError<StandardError
17   end
18
19   ID_MAP =  {}              # obj -> [ref,...]
20   ID_REV_MAP =  {}          # ref -> obj
21   @@final = lambda{|id|
22     __old_status = Thread.critical
23     Thread.critical = true
24     begin
25       rids = ID_MAP[id]
26       if rids
27         for rid in rids
28           ID_REV_MAP[rid] = nil
29         end
30         ID_MAP[id] = nil
31       end
32       rid = ID_REV_MAP[id]
33       if rid
34         ID_REV_MAP[id] = nil
35         ID_MAP[rid].delete(id)
36         ID_MAP[rid] = nil if ID_MAP[rid].empty?
37       end
38     ensure
39       Thread.critical = __old_status
40     end
41   }
42
43   def initialize(orig)
44     super
45     @__id = orig.__id__
46     ObjectSpace.define_finalizer orig, @@final
47     ObjectSpace.define_finalizer self, @@final
48     __old_status = Thread.critical
49     begin
50       Thread.critical = true
51       ID_MAP[@__id] = [] unless ID_MAP[@__id]
52     ensure
53       Thread.critical = __old_status
54     end
55     ID_MAP[@__id].push self.__id__
56     ID_REV_MAP[self.id] = @__id
57   end
58
59   def __getobj__
60     unless ID_MAP[@__id]
61       raise RefError, "Illegal Reference - probably recycled", caller(2)
62     end
63     ObjectSpace._id2ref(@__id)
64   end
65
66   def weakref_alive?
67     if ID_MAP[@__id]
68       true
69     else
70       false
71     end
72   end
73 end
74
75 if __FILE__ == $0
76   require 'thread'
77   foo = Object.new
78   p foo.to_s                    # original's class
79   foo = WeakRef.new(foo)
80   p foo.to_s                    # should be same class
81   ObjectSpace.garbage_collect
82   p foo.to_s                    # should raise exception (recycled)
83 end