yarv-diff:264
From: ko1 atdot.net
Date: 15 Feb 2006 13:12:35 -0000
Subject: [yarv-diff:264] r427 - in trunk: . lib test
Author: aamine
Date: 2006-02-15 22:12:34 +0900 (Wed, 15 Feb 2006)
New Revision: 427
Added:
trunk/test/inlinetest.rb
Modified:
trunk/ChangeLog
trunk/lib/singleton.rb
trunk/lib/thread.rb
trunk/lib/timeout.rb
trunk/lib/weakref.rb
Log:
* lib/weakref.rb: do not use Thread.critical=.
* lib/singleton.rb: ditto.
* lib/timeout.rb: ditto.
* lib/thread.rb: ditto.
* test/inlinetest.rb: forgot to commit.
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2006-02-15 12:34:47 UTC (rev 426)
+++ trunk/ChangeLog 2006-02-15 13:12:34 UTC (rev 427)
@@ -4,6 +4,19 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2006-02-15(Wed) 22:12:25 +0900 Minero Aoki <aamine loveruby.net>
+
+ * lib/weakref.rb: do not use Thread.critical=.
+
+ * lib/singleton.rb: ditto.
+
+ * lib/timeout.rb: ditto.
+
+ * lib/thread.rb: ditto.
+
+ * test/inlinetest.rb: forgot to commit.
+
+
2006-02-15(Wed) 21:34:17 +0900 Minero Aoki <aamine loveruby.net>
* test/test_pp.rb: imported from Ruby CVS trunk HEAD.
Modified: trunk/lib/singleton.rb
===================================================================
--- trunk/lib/singleton.rb 2006-02-15 12:34:47 UTC (rev 426)
+++ trunk/lib/singleton.rb 2006-02-15 13:12:34 UTC (rev 427)
@@ -60,8 +60,6 @@
# and _dump(depth) hooks allows the (partially) resurrections of
# a previous state of ``the instance''.
-
-
module Singleton
# disable build-in copying methods
def clone
@@ -72,65 +70,19 @@
end
private
+
# default marshalling strategy
- def _dump(depth=-1)
+ def _dump(depth = -1)
''
end
-end
-
-class << Singleton
- # Method body of first instance call.
- FirstInstanceCall = proc do
- # @__instance__ takes on one of the following values
- # * nil - before and after a failed creation
- # * false - during creation
- # * sub_class instance - after a successful creation
- # the form makes up for the lack of returns in progs
- Thread.critical = true
- if @__instance__.nil?
- @__instance__ = false
- Thread.critical = false
- begin
- @__instance__ = new
- ensure
- if @__instance__
- class <<self
- remove_method :instance
- def instance; @__instance__ end
- end
- else
- @__instance__ = nil # failed instance creation
- end
- end
- elsif _instantiate?()
- Thread.critical = false
- else
- @__instance__ = false
- Thread.critical = false
- begin
- @__instance__ = new
- ensure
- if @__instance__
- class <<self
- remove_method :instance
- def instance; @__instance__ end
- end
- else
- @__instance__ = nil
- end
- end
- end
- @__instance__
- end
-
module SingletonClassMethods
# properly clone the Singleton pattern - did you know
# that duping doesn't copy class methods?
def clone
Singleton.__init__(super)
end
-
+
private
# ensure that the Singleton pattern is properly inherited
@@ -142,46 +94,47 @@
def _load(str)
instance
end
+ end
+
+ class << Singleton
+ def __init__(klass)
+ klass.instance_eval {
+ @__instance__ = nil
+ @__mutex__ = Mutex.new
+ }
+ def klass.instance
+ return @__instance__ if @__instance__
+ @__mutex__.synchronize {
+ return @__instance__ if @__instance__
+ @__instance__ = new()
+ }
+ @__instance__
+ end
+ klass
+ end
- # waiting-loop hook
- def _instantiate?()
- while false.equal?(@__instance__)
- Thread.critical = false
- sleep(0.08) # timeout
- Thread.critical = true
+ private
+
+ # extending an object with Singleton is a bad idea
+ undef_method :extend_object
+
+ def append_features(mod)
+ # help out people counting on transitive mixins
+ unless mod.instance_of?(Class)
+ raise TypeError, "Inclusion of the OO-Singleton module in module #{mod}"
end
- @__instance__
+ super
end
- end
-
- def __init__(klass)
- klass.instance_eval { @__instance__ = nil }
- class << klass
- define_method(:instance,FirstInstanceCall)
+
+ def included(klass)
+ super
+ klass.private_class_method :new, :allocate
+ klass.extend SingletonClassMethods
+ Singleton.__init__(klass)
end
- klass
end
- private
- # extending an object with Singleton is a bad idea
- undef_method :extend_object
-
- def append_features(mod)
- # help out people counting on transitive mixins
- unless mod.instance_of?(Class)
- raise TypeError, "Inclusion of the OO-Singleton module in module #{mod}"
- end
- super
- end
-
- def included(klass)
- super
- klass.private_class_method :new, :allocate
- klass.extend SingletonClassMethods
- Singleton.__init__(klass)
- end
end
-
if __FILE__ == $0
@@ -223,9 +176,9 @@
def _instantiate?
@enter.push Thread.current[:i]
while false.equal?(@__instance__)
- Thread.critical = false
+ @__mutex__.unlock
sleep 0.08
- Thread.critical = true
+ @__mutex__.lock
end
@leave.push Thread.current[:i]
@__instance__
Modified: trunk/lib/thread.rb
===================================================================
--- trunk/lib/thread.rb 2006-02-15 12:34:47 UTC (rev 426)
+++ trunk/lib/thread.rb 2006-02-15 13:12:34 UTC (rev 427)
@@ -13,7 +13,7 @@
end
unless defined? ThreadError
- class ThreadError<StandardError
+ class ThreadError < StandardError
end
end
@@ -240,7 +240,7 @@
#
# See Queue for an example of how a SizedQueue works.
#
-class SizedQueue<Queue
+class SizedQueue < Queue
#
# Creates a fixed-length queue with a maximum size of +max+.
#
@@ -263,14 +263,16 @@
# Sets the maximum size of the queue.
#
def max=(max)
- Thread.critical = true
- if max <= @max
- @max = max
- Thread.critical = false
- else
- diff = max - @max
- @max = max
- Thread.critical = false
+ diff = nil
+ @mutex.synchronize {
+ if max <= @max
+ @max = max
+ else
+ diff = max - @max
+ @max = max
+ end
+ }
+ if diff
diff.times do
begin
t = @queue_wait.shift
@@ -288,13 +290,15 @@
# until space becomes available.
#
def push(obj)
- Thread.critical = true
- while @que.length >= @max
+ while true
+ @mutex.lock
+ break if @que.length >= @max
@queue_wait.push Thread.current
- Thread.stop
- Thread.critical = true
+ @mutex.unlock_and_sleep
end
super
+ ensure
+ @mutex.unlock
end
#
@@ -312,20 +316,20 @@
#
def pop(*args)
retval = super
- Thread.critical = true
- if @que.length < @max
- begin
- t = @queue_wait.shift
- t.wakeup if t
- rescue ThreadError
- retry
- ensure
- Thread.critical = false
+ t = nil
+ @mutex.synchronize {
+ if @que.length < @max
+ begin
+ t = @queue_wait.shift
+ t.wakeup if t
+ rescue ThreadError
+ retry
+ end
end
- begin
- t.run if t
- rescue ThreadError
- end
+ }
+ begin
+ t.run if t
+ rescue ThreadError
end
retval
end
Modified: trunk/lib/timeout.rb
===================================================================
--- trunk/lib/timeout.rb 2006-02-15 12:34:47 UTC (rev 426)
+++ trunk/lib/timeout.rb 2006-02-15 13:12:34 UTC (rev 427)
@@ -24,7 +24,7 @@
module Timeout
# Raised by Timeout#timeout when the block times out.
- class Error<Interrupt
+ class Error < Interrupt
end
# Executes the method's block. If the block execution terminates before +sec+
@@ -36,7 +36,6 @@
# so you can call it directly as Timeout.timeout().
def timeout(sec, exception=Error)
return yield if sec == nil or sec.zero?
- # raise ThreadError, "timeout within critical session" if Thread.critical
begin
x = Thread.current
y = Thread.start {
@@ -59,7 +58,7 @@
#
# Defined for backwards compatibility with earlier versions of timeout.rb, see
# Timeout#timeout.
-def timeout(n, e=Timeout::Error, &block)
+def timeout(n, e = Timeout::Error, &block)
Timeout::timeout(n, e, &block)
end
Modified: trunk/lib/weakref.rb
===================================================================
--- trunk/lib/weakref.rb 2006-02-15 12:34:47 UTC (rev 426)
+++ trunk/lib/weakref.rb 2006-02-15 13:12:34 UTC (rev 427)
@@ -11,18 +11,17 @@
require "delegate"
-class WeakRef<Delegator
+class WeakRef < Delegator
- class RefError<StandardError
+ class RefError < StandardError
end
@@id_map = {} # obj -> [ref,...]
@@id_rev_map = {} # ref -> obj
+ @@mutex = Mutex.new
@@final = lambda {|id|
printf "final: %p\n", id
- __old_status = Thread.critical
- Thread.critical = true
- begin
+ mutex.synchronize {
rids = @@id_map[id]
if rids
for rid in rids
@@ -36,9 +35,7 @@
id_map[rid].delete(id)
id_map.delete(rid) if id_map[rid].empty?
end
- ensure
- Thread.critical = __old_status
- end
+ }
}
def initialize(orig)
@@ -46,13 +43,9 @@
printf "orig: %p\n", @__id
ObjectSpace.define_finalizer orig, @@final
ObjectSpace.define_finalizer self, @@final
- __old_status = Thread.critical
- begin
- Thread.critical = true
+ mutex.synchronize {
@@id_map[@__id] = [] unless @@id_map[@__id]
- ensure
- Thread.critical = __old_status
- end
+ }
id_map[ __id].push self.object_id
id_rev_map[self.object_id] = @__id
super
Added: trunk/test/inlinetest.rb
===================================================================
--- trunk/test/inlinetest.rb 2006-02-15 12:34:47 UTC (rev 426)
+++ trunk/test/inlinetest.rb 2006-02-15 13:12:34 UTC (rev 427)
@@ -0,0 +1,55 @@
+module InlineTest
+ def eval_part(libname, sep, part)
+ path = libpath(libname)
+ program = File.open(path) { |f| f.read }
+ mainpart, endpart = program.split(sep)
+ if endpart.nil?
+ raise RuntimeError.new("No #{part} part in the library '#{filename}'")
+ end
+ eval(endpart, TOPLEVEL_BINDING, path, mainpart.count("\n")+1)
+ end
+ module_function :eval_part
+
+ def loadtest(libname)
+ require(libname)
+ in_critical do
+ in_progname(libpath(libname)) do
+ eval_part(libname, /^(?=if\s+(?:\$0\s*==\s*__FILE__|__FILE__\s*==\s*\$0)(?:[\#\s]|$))/, '$0 == __FILE__')
+ end
+ end
+ end
+ module_function :loadtest
+
+ def loadtest__END__part(libname)
+ require(libname)
+ eval_part(libname, /^__END__$/, '__END__')
+ end
+ module_function :loadtest__END__part
+
+ @mutex = Mutex.new
+
+ def self.in_critical(&block)
+ @mutex.synchronize(&block)
+ end
+
+ def self.in_progname(progname)
+ progname_backup = $0.dup
+ $0.replace(progname)
+ begin
+ yield
+ ensure
+ $0.replace(progname_backup)
+ end
+ end
+
+ def self.libpath(libname)
+ libpath = nil
+ $:.find do |path|
+ File.file?(testname = File.join(path, libname)) && libpath = testname
+ end
+ if libpath.nil?
+ raise RuntimeError.new("'#{libname}' not found")
+ end
+ libpath
+ end
+end
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml