diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/final.rb | 41 | ||||
-rw-r--r-- | lib/finalize.rb | 121 | ||||
-rw-r--r-- | lib/ftplib.rb | 6 | ||||
-rw-r--r-- | lib/sync.rb | 8 | ||||
-rw-r--r-- | lib/tempfile.rb | 14 |
5 files changed, 117 insertions, 73 deletions
diff --git a/lib/final.rb b/lib/final.rb new file mode 100644 index 0000000000..566d1aae42 --- /dev/null +++ b/lib/final.rb @@ -0,0 +1,41 @@ +# +# $Id$ +# Copyright (C) 1998 Yukihiro Matsumoto. All rights reserved. + +# The ObjectSpace extention: +# +# ObjectSpace.define_finalizer(obj, proc=lambda()) +# +# Defines the finalizer for the specified object. +# +# ObjectSpace.undefine_finalizer(obj) +# +# Removes the finalizers for the object. If multiple finalizers are +# defined for the object, all finalizers will be removed. +# + +module ObjectSpace + Finalizer = {} + def define_finalizer(obj, proc=lambda()) + ObjectSpace.call_finalizer(obj) + if assoc = Finalizer[obj.id] + assoc.push(proc) + else + Finalizer[obj.id] = [proc] + end + end + def undefine_finalizer(obj) + Finalizer.delete(obj.id) + end + module_function :define_finalizer, :remove_finalizer + + Generic_Finalizer = proc {|id| + if Finalizer.key? id + for proc in Finalizer[id] + proc.call(id) + end + Finalizer.delete(id) + end + } + add_finalizer Generic_Finalizer +end diff --git a/lib/finalize.rb b/lib/finalize.rb index d91bb0d333..fcdb1dc448 100644 --- a/lib/finalize.rb +++ b/lib/finalize.rb @@ -1,8 +1,8 @@ # # finalizer.rb - # $Release Version: 0.2$ -# $Revision: 1.1.1.2 $ -# $Date: 1998/01/16 04:14:51 $ +# $Revision: 1.1.1.2.2.1 $ +# $Date: 1998/01/16 12:36:04 $ # by Keiju ISHITSUKA # # -- @@ -13,10 +13,10 @@ # add_dependency(obj, dependant, method = :finalize, *opt) # 依存関係 R_method(obj, dependant) の追加 # -# delete(obj_or_id, dependant, method = :finalize) -# delete_dependency(obj_or_id, dependant, method = :finalize) +# delete(obj, dependant, method = :finalize) +# delete_dependency(obj, dependant, method = :finalize) # 依存関係 R_method(obj, dependant) の削除 -# delete_all_dependency(obj_or_id, dependant) +# delete_all_dependency(obj, dependant) # 依存関係 R_*(obj, dependant) の削除 # delete_by_dependant(dependant, method = :finalize) # 依存関係 R_method(*, dependant) の削除 @@ -25,11 +25,11 @@ # delete_all # 全ての依存関係の削除. # -# finalize(obj_or_id, dependant, method = :finalize) -# finalize_dependency(obj_or_id, dependant, method = :finalize) +# finalize(obj, dependant, method = :finalize) +# finalize_dependency(obj, dependant, method = :finalize) # 依存関連 R_method(obj, dependtant) で結ばれるdependantを # finalizeする. -# finalize_all_dependency(obj_or_id, dependant) +# finalize_all_dependency(obj, dependant) # 依存関連 R_*(obj, dependtant) で結ばれるdependantをfinalizeする. # finalize_by_dependant(dependant, method = :finalize) # 依存関連 R_method(*, dependtant) で結ばれるdependantをfinalizeする. @@ -44,50 +44,46 @@ # module Finalizer - RCS_ID='-$Header: /home/cvsroot/ruby/lib/finalize.rb,v 1.1.1.2 1998/01/16 04:14:51 matz Exp $-' - - # @dependency: {id => [[dependant, method, *opt], ...], ...} + RCS_ID='-$Header: /home/cvsroot/ruby/lib/finalize.rb,v 1.1.1.2.2.1 1998/01/16 12:36:04 matz Exp $-' + + # Dependency: {id => [[dependant, method, opt], ...], ...} + Dependency = {} # 依存関係 R_method(obj, dependant) の追加 def add_dependency(obj, dependant, method = :finalize, *opt) ObjectSpace.call_finalizer(obj) - method = method.intern unless method.kind_of?(Integer) - assoc = [dependant, method].concat(opt) - if dep = @dependency[obj.id] + assoc = [dependant, method, opt] + if dep = Dependency[obj.id] dep.push assoc else - @dependency[obj.id] = [assoc] + Dependency[obj.id] = [assoc] end end alias add add_dependency # 依存関係 R_method(obj, dependant) の削除 - def delete_dependency(id, dependant, method = :finalize) - id = id.id unless id.kind_of?(Integer) - method = method.intern unless method.kind_of?(Integer) - for assoc in @dependency[id] - assoc.delete_if do - |d, m, *o| + def delete_dependency(obj, dependant, method = :finalize) + id = obj.id + for assoc in Dependency[id] + assoc.delete_if do |d,m,*o| d == dependant && m == method end - @dependency.delete(id) if assoc.empty? + Dependency.delete(id) if assoc.empty? end end alias delete delete_dependency # 依存関係 R_*(obj, dependant) の削除 - def delete_all_dependency(id, dependant) - id = id.id unless id.kind_of?(Integer) - method = method.intern unless method.kind_of?(Integer) - for assoc in @dependency[id] - assoc.delete_if do - |d, m, *o| + def delete_all_dependency(obj, dependant) + id = obj.id + for assoc in Dependency[id] + assoc.delete_if do |d,m,*o| d == dependant end - @dependency.delete(id) if assoc.empty? + Dependency.delete(id) if assoc.empty? end end - + # 依存関係 R_method(*, dependant) の削除 def delete_by_dependant(dependant, method = :finalize) method = method.intern unless method.kind_of?(Integer) @@ -95,61 +91,63 @@ module Finalizer delete(id, dependant, method) end end - + # 依存関係 R_*(*, dependant) の削除 def delete_all_by_dependant(dependant) - for id in @dependency.keys + for id in Dependency.keys delete_all_dependency(id, dependant) end end - - # 依存関連 R_method(obj, dependtant) で結ばれるdependantをfinalizeす + + # 依存関連 R_method(id, dependtant) で結ばれるdependantをfinalizeす # る. def finalize_dependency(id, dependant, method = :finalize) - id = id.id unless id.kind_of?(Integer) - method = method.intern unless method.kind_of?(Integer) - for assocs in @dependency[id] - assocs.delete_if do - |d, m, *o| - d.send(m, *o) if ret = d == dependant && m == method - ret + for assocs in Dependency[id] + assocs.delete_if do |d, m, *o| + if d == dependant && m == method + d.send(m, *o) + true + else + false + end end - @dependency.delete(id) if assoc.empty? + Dependency.delete(id) if assoc.empty? end end alias finalize finalize_dependency - # 依存関連 R_*(obj, dependtant) で結ばれるdependantをfinalizeする. + # 依存関連 R_*(id, dependtant) で結ばれるdependantをfinalizeする. def finalize_all_dependency(id, dependant) - id = id.id unless id.kind_of?(Integer) - method = method.intern unless method.kind_of?(Integer) - for assoc in @dependency[id] - assoc.delete_if do - |d, m, *o| - d.send(m, *o) if ret = d == dependant + for assoc in Dependency[id] + assoc.delete_if do |d, m, *o| + if d == dependant + d.send(m, *o) + true + else + false + end end - @dependency.delete(id) if assoc.empty? + Dependency.delete(id) if assoc.empty? end end # 依存関連 R_method(*, dependtant) で結ばれるdependantをfinalizeする. def finalize_by_dependant(dependant, method = :finalize) - method = method.intern unless method.kind_of?(Integer) - for id in @dependency.keys + for id in Dependency.keys finalize(id, dependant, method) end end # 依存関連 R_*(*, dependtant) で結ばれるdependantをfinalizeする. def fainalize_all_by_dependant(dependant) - for id in @dependency.keys + for id in Dependency.keys finalize_all_dependency(id, dependant) end end # Finalizerに登録されている全てのdependantをfinalizeする def finalize_all - for id, assocs in @dependency + for id, assocs in Dependency for dependant, method, *opt in assocs dependant.send(method, id, *opt) end @@ -159,26 +157,24 @@ module Finalizer # finalize_* を安全に呼び出すためのイテレータ def safe - old_status = Thread.critical - Thread.critical = TRUE - ObjectSpace.remove_finalizer(@proc) + old_status, Thread.critical = Thread.critical, true + ObjectSpace.remove_finalizer(Proc) yield - ObjectSpace.add_finalizer(@proc) + ObjectSpace.add_finalizer(Proc) Thread.critical = old_status end # ObjectSpace#add_finalizerへの登録関数 def final_of(id) - if assocs = @dependency.delete(id) + if assocs = Dependency.delete(id) for dependant, method, *opt in assocs dependant.send(method, id, *opt) end end end - @dependency = Hash.new - @proc = proc{|id| final_of(id)} - ObjectSpace.add_finalizer(@proc) + Proc = proc{|id| final_of(id)} + ObjectSpace.add_finalizer(Proc) module_function :add module_function :add_dependency @@ -202,4 +198,3 @@ module Finalizer private_class_method :final_of end - diff --git a/lib/ftplib.rb b/lib/ftplib.rb index a03760daf8..5f949f7099 100644 --- a/lib/ftplib.rb +++ b/lib/ftplib.rb @@ -1,7 +1,7 @@ ### ftplib.rb -*- Mode: ruby; tab-width: 8; -*- -## $Revision: 1.1.1.1 $ -## $Date: 1998/01/16 04:05:49 $ +## $Revision: 1.1.1.1.4.1 $ +## $Date: 1998/01/16 12:36:05 $ ## by maeda shugo <shugo@po.aianet.ne.jp> ### Code: @@ -17,7 +17,7 @@ class FTPProtoError < FTPError; end class FTP - RCS_ID = '$Id: ftplib.rb,v 1.1.1.1 1998/01/16 04:05:49 matz Exp $' + RCS_ID = '$Id: ftplib.rb,v 1.1.1.1.4.1 1998/01/16 12:36:05 matz Exp $ ' FTP_PORT = 21 CRLF = "\r\n" diff --git a/lib/sync.rb b/lib/sync.rb index b5a3fc32b3..a804ade133 100644 --- a/lib/sync.rb +++ b/lib/sync.rb @@ -43,7 +43,7 @@ unless defined? Thread fail "Thread not available for this ruby interpreter" end -require "finalize" +require "final" module Sync_m RCS_ID='-$Header$-' @@ -321,7 +321,11 @@ module Sync_m def For_primitive_object.extend_object(obj) super obj.sync_extended - Finalizer.add(obj, For_primitive_object, :sync_finalize) + # Changed to use `final.rb'. + # Finalizer.add(obj, For_primitive_object, :sync_finalize) + ObjectSpace.define_finalizer(obj) do |id| + For_primitive_object.sync_finalize(id) + end end def initialize diff --git a/lib/tempfile.rb b/lib/tempfile.rb index a6ffaa55fe..93869aebbc 100644 --- a/lib/tempfile.rb +++ b/lib/tempfile.rb @@ -6,11 +6,11 @@ # The class for temporary files. # o creates a temporary file, which name is "basename.pid.n" with mode "w+". # o Tempfile objects can be used like IO object. -# o created temporary files are removed if it is closed or garbage collected, -# or script termination. +# o created temporary files are removed on closing or script termination. # o file mode of the temporary files are 0600. require 'delegate' +require 'final' class Tempfile < SimpleDelegater Max_try = 10 @@ -45,8 +45,7 @@ class Tempfile < SimpleDelegater File.unlink(@tmpdir + '/' + @tmpname + '.lock') end } - ObjectSpace.call_finalizer(self) - ObjectSpace.add_finalizer(@clean_files) + ObjectSpace.define_finalizer(self, @clean_files) @tmpfile = open(@tmpname, 'w+') super(@tmpfile) @@ -57,8 +56,13 @@ class Tempfile < SimpleDelegater end end + def Tempfile.open(*args) + Tempfile.new(*args) + end + def close - super + @tmpfile.close @clean_files.call + ObjectSpace.undefine_finalizer(self) end end |