From c49f5bebebd16cd6052a01fc5471425470f96c20 Mon Sep 17 00:00:00 2001 From: matz Date: Fri, 27 Feb 1998 07:48:11 +0000 Subject: finalize/mutex_m git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/v1_1r@99 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/finalize.rb | 162 ++++++++++++++++++++++++++++---------------------------- lib/mutex_m.rb | 60 ++++++++++++++++----- 2 files changed, 130 insertions(+), 92 deletions(-) diff --git a/lib/finalize.rb b/lib/finalize.rb index e479cac563..acbaf0e66f 100644 --- a/lib/finalize.rb +++ b/lib/finalize.rb @@ -1,8 +1,8 @@ # # finalizer.rb - -# $Release Version: 0.2$ -# $Revision: 1.3 $ -# $Date: 1998/01/09 08:09:49 $ +# $Release Version: 0.3$ +# $Revision: 1.4 $ +# $Date: 1998/02/27 05:34:33 $ # by Keiju ISHITSUKA # # -- @@ -13,10 +13,10 @@ # add_dependency(obj, dependant, method = :finalize, *opt) # 依存関係 R_method(obj, dependant) の追加 # -# delete(obj, dependant, method = :finalize) -# delete_dependency(obj, dependant, method = :finalize) +# delete(obj_or_id, dependant, method = :finalize) +# delete_dependency(obj_or_id, dependant, method = :finalize) # 依存関係 R_method(obj, dependant) の削除 -# delete_all_dependency(obj, dependant) +# delete_all_dependency(obj_or_id, dependant) # 依存関係 R_*(obj, dependant) の削除 # delete_by_dependant(dependant, method = :finalize) # 依存関係 R_method(*, dependant) の削除 @@ -25,11 +25,11 @@ # delete_all # 全ての依存関係の削除. # -# finalize(obj, dependant, method = :finalize) -# finalize_dependency(obj, dependant, method = :finalize) +# finalize(obj_or_id, dependant, method = :finalize) +# finalize_dependency(obj_or_id, dependant, method = :finalize) # 依存関連 R_method(obj, dependtant) で結ばれるdependantを # finalizeする. -# finalize_all_dependency(obj, dependant) +# finalize_all_dependency(obj_or_id, dependant) # 依存関連 R_*(obj, dependtant) で結ばれるdependantをfinalizeする. # finalize_by_dependant(dependant, method = :finalize) # 依存関連 R_method(*, dependtant) で結ばれるdependantをfinalizeする. @@ -44,150 +44,151 @@ # module Finalizer - RCS_ID='-$Header: /home/keiju/var/src/var.lib/ruby/RCS/finalize.rb,v 1.3 1998/01/09 08:09:49 keiju Exp keiju $-' - - # Dependency: {id => [[dependant, method, opt], ...], ...} - Dependency = {} - + RCS_ID='-$Id: finalize.rb,v 1.4 1998/02/27 05:34:33 keiju Exp keiju $-' + + # @dependency: {id => [[dependant, method, *opt], ...], ...} + # 依存関係 R_method(obj, dependant) の追加 def add_dependency(obj, dependant, method = :finalize, *opt) ObjectSpace.call_finalizer(obj) - assoc = [dependant, method, opt] - if dep = Dependency[obj.id] + method = method.intern unless method.kind_of?(Integer) + assoc = [dependant, method].concat(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(obj, dependant, method = :finalize) - id = obj.id - for assoc in Dependency[id] - assoc.delete_if do |d,m,*o| + 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| 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(obj, dependant) - id = obj.id - for assoc in Dependency[id] - assoc.delete_if do |d,m,*o| + 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| 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) - for id in Dependency.keys + for id in @dependency.keys 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(id, dependtant) で結ばれるdependantをfinalizeす + + # 依存関連 R_method(obj, dependtant) で結ばれるdependantをfinalizeす # る. def finalize_dependency(id, dependant, method = :finalize) - 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 + 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, id, *o) if ret = d == dependant && m == method + ret end - Dependency.delete(id) if assoc.empty? + @dependency.delete(id) if assoc.empty? end end alias finalize finalize_dependency - - # 依存関連 R_*(id, dependtant) で結ばれるdependantをfinalizeする. + + # 依存関連 R_*(obj, dependtant) で結ばれるdependantをfinalizeする. def finalize_all_dependency(id, dependant) - for assoc in Dependency[id] - assoc.delete_if do |d, m, *o| - if d == dependant - d.send(m, *o) - true - else - false - end + 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, id, *o) if ret = d == dependant 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) - for id in Dependency.keys + method = method.intern unless method.kind_of?(Integer) + 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 assocs.clear end end - + # finalize_* を安全に呼び出すためのイテレータ def safe - old_status, Thread.critical = Thread.critical, true - ObjectSpace.remove_finalizer(Proc) - begin - yield - ensure - ObjectSpace.add_finalizer(Proc) - Thread.critical = old_status - end + old_status = Thread.critical + Thread.critical = TRUE + ObjectSpace.remove_finalizer(@proc) + yield + ObjectSpace.add_finalizer(@proc) + Thread.critical = old_status end - + # ObjectSpace#add_finalizerへの登録関数 def final_of(id) - if assocs = Dependency.delete(id) - for dependant, method, opt in assocs + if assocs = @dependency.delete(id) + for dependant, method, *opt in assocs dependant.send(method, id, *opt) end end end - - Proc = proc{|id| final_of(id)} - ObjectSpace.add_finalizer(Proc) + + @dependency = Hash.new + @proc = proc{|id| final_of(id)} + ObjectSpace.add_finalizer(@proc) module_function :add module_function :add_dependency - + module_function :delete module_function :delete_dependency module_function :delete_all_dependency module_function :delete_by_dependant module_function :delete_all_by_dependant - + module_function :finalize module_function :finalize_dependency module_function :finalize_all_dependency @@ -196,8 +197,9 @@ module Finalizer module_function :finalize_all module_function :safe - + module_function :final_of private_class_method :final_of - + end + diff --git a/lib/mutex_m.rb b/lib/mutex_m.rb index 693da41675..4b8d64438e 100644 --- a/lib/mutex_m.rb +++ b/lib/mutex_m.rb @@ -1,8 +1,8 @@ # # mutex_m.rb - # $Release Version: 2.0$ -# $Revision: 1.1.1.1 $ -# $Date: 1998/01/16 04:05:49 $ +# $Revision: 1.7 $ +# $Date: 1998/02/27 04:28:57 $ # Original from mutex.rb # by Keiju ISHITSUKA(SHL Japan Inc.) # @@ -18,21 +18,50 @@ require "finalize" module Mutex_m - def Mutex_m.extend_object(obj) + def Mutex_m.extendable_module(obj) if Fixnum === obj or TRUE === obj or FALSE === obj or nil == obj raise TypeError, "Mutex_m can't extend to this class(#{obj.type})" else begin - eval "class << obj - @mu_locked - end" - obj.extend(For_primitive_object) + obj.instance_eval "@mu_locked" + For_general_object rescue TypeError - obj.extend(For_general_object) + For_primitive_object end end end + def Mutex_m.includable_module(cl) + begin + dummy = cl.new + Mutex_m.extendable_module(dummy) + rescue NameError + # newが定義されていない時は, DATAとみなす. + For_primitive_object + end + end + + def Mutex_m.extend_class(cl) + return super if cl.instance_of?(Module) + + # モジュールの時は何もしない. クラスの場合, 適切なモジュールの決定 + # とaliasを行う. + real = includable_module(cl) + cl.module_eval %q{ + include real + + alias locked? mu_locked? + alias lock mu_lock + alias unlock mu_unlock + alias try_lock mu_try_lock + alias synchronize mu_synchronize + } + end + + def Mutex_m.extend_object(obj) + obj.extend(Mutex_m.extendable_module(obj)) + end + def mu_extended unless (defined? locked? and defined? lock and @@ -40,7 +69,7 @@ module Mutex_m defined? try_lock and defined? synchronize) eval "class << self - alias locked mu_locked? + alias locked? mu_locked? alias lock mu_lock alias unlock mu_unlock alias try_lock mu_try_lock @@ -49,6 +78,7 @@ module Mutex_m end end + # locking def mu_synchronize begin mu_lock @@ -58,6 +88,7 @@ module Mutex_m end end + # internal class module For_general_object include Mutex_m @@ -118,10 +149,16 @@ module Mutex_m def For_primitive_object.extend_object(obj) super + obj.mu_extended Finalizer.add(obj, For_primitive_object, :mu_finalize) end + def mu_extended + super + initialize + end + def For_primitive_object.mu_finalize(id) Thread.critical = TRUE if wait = Mu_Locked.delete(id) @@ -146,7 +183,7 @@ module Mutex_m ret = FALSE else Mu_Locked[self.id] = [] - Finalizer.set(self, For_primitive_object, :mu_delete_Locked) + Finalizer.add(self, For_primitive_object, :mu_finalize) ret = TRUE end Thread.critical = FALSE @@ -159,7 +196,7 @@ module Mutex_m Thread.stop end Mu_Locked[self.id] = [] - Finalizer.add(self, For_primitive_object, :mu_delete_Locked) + Finalizer.add(self, For_primitive_object, :mu_finalize) Thread.critical = FALSE self end @@ -180,4 +217,3 @@ module Mutex_m end end - -- cgit v1.2.3