[前][次][番号順一覧][スレッド一覧]

ruby-changes:48190

From: knu <ko1@a...>
Date: Sun, 22 Oct 2017 00:57:36 +0900 (JST)
Subject: [ruby-changes:48190] knu:r60304 (trunk): Use a mutex to make SortedSet.setup thread-safe

knu	2017-10-22 00:57:32 +0900 (Sun, 22 Oct 2017)

  New Revision: 60304

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=60304

  Log:
    Use a mutex to make SortedSet.setup thread-safe
    
    This should fix [Bug #13735].

  Modified files:
    trunk/lib/set.rb
Index: lib/set.rb
===================================================================
--- lib/set.rb	(revision 60303)
+++ lib/set.rb	(revision 60304)
@@ -634,6 +634,7 @@ end https://github.com/ruby/ruby/blob/trunk/lib/set.rb#L634
 #
 class SortedSet < Set
   @@setup = false
+  @@mutex = Mutex.new
 
   class << self
     def [](*ary)        # :nodoc:
@@ -643,97 +644,98 @@ class SortedSet < Set https://github.com/ruby/ruby/blob/trunk/lib/set.rb#L644
     def setup   # :nodoc:
       @@setup and return
 
-      # a hack to shut up warning
-      alias_method :old_init, :initialize
+      @@mutex.synchronize do
+        # a hack to shut up warning
+        alias_method :old_init, :initialize
+
+        begin
+          require 'rbtree'
+
+          module_eval <<-END, __FILE__, __LINE__+1
+            def initialize(*args)
+              @hash = RBTree.new
+              super
+            end
+
+            def add(o)
+              o.respond_to?(:<=>) or raise ArgumentError, "value must respond to <=>"
+              super
+            end
+            alias << add
+          END
+        rescue LoadError
+          module_eval <<-END, __FILE__, __LINE__+1
+            def initialize(*args)
+              @keys = nil
+              super
+            end
+
+            def clear
+              @keys = nil
+              super
+            end
+
+            def replace(enum)
+              @keys = nil
+              super
+            end
+
+            def add(o)
+              o.respond_to?(:<=>) or raise ArgumentError, "value must respond to <=>"
+              @keys = nil
+              super
+            end
+            alias << add
+
+            def delete(o)
+              @keys = nil
+              @hash.delete(o)
+              self
+            end
+
+            def delete_if
+              block_given? or return enum_for(__method__) { size }
+              n = @hash.size
+              super
+              @keys = nil if @hash.size != n
+              self
+            end
+
+            def keep_if
+              block_given? or return enum_for(__method__) { size }
+              n = @hash.size
+              super
+              @keys = nil if @hash.size != n
+              self
+            end
+
+            def merge(enum)
+              @keys = nil
+              super
+            end
+
+            def each(&block)
+              block or return enum_for(__method__) { size }
+              to_a.each(&block)
+              self
+            end
+
+            def to_a
+              (@keys = @hash.keys).sort! unless @keys
+              @keys
+            end
+
+            def freeze
+              to_a
+              super
+            end
+          END
+        end
+        # a hack to shut up warning
+        remove_method :old_init
 
-      begin
-        require 'rbtree'
-
-        module_eval <<-END, __FILE__, __LINE__+1
-          def initialize(*args)
-            @hash = RBTree.new
-            super
-          end
-
-          def add(o)
-            o.respond_to?(:<=>) or raise ArgumentError, "value must respond to <=>"
-            super
-          end
-          alias << add
-        END
-      rescue LoadError
-        module_eval <<-END, __FILE__, __LINE__+1
-          def initialize(*args)
-            @keys = nil
-            super
-          end
-
-          def clear
-            @keys = nil
-            super
-          end
-
-          def replace(enum)
-            @keys = nil
-            super
-          end
-
-          def add(o)
-            o.respond_to?(:<=>) or raise ArgumentError, "value must respond to <=>"
-            @keys = nil
-            super
-          end
-          alias << add
-
-          def delete(o)
-            @keys = nil
-            @hash.delete(o)
-            self
-          end
-
-          def delete_if
-            block_given? or return enum_for(__method__) { size }
-            n = @hash.size
-            super
-            @keys = nil if @hash.size != n
-            self
-          end
-
-          def keep_if
-            block_given? or return enum_for(__method__) { size }
-            n = @hash.size
-            super
-            @keys = nil if @hash.size != n
-            self
-          end
-
-          def merge(enum)
-            @keys = nil
-            super
-          end
-
-          def each(&block)
-            block or return enum_for(__method__) { size }
-            to_a.each(&block)
-            self
-          end
-
-          def to_a
-            (@keys = @hash.keys).sort! unless @keys
-            @keys
-          end
-
-          def freeze
-            to_a
-            super
-          end
-        END
+        @@setup = true
       end
-
-      # a hack to shut up warning
-      remove_method :old_init
-
-      @@setup = true
     end
   end
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]