[前][次][番号順一覧][スレッド一覧][生データ]

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

[前][次][番号順一覧][スレッド一覧][生データ]