]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/commitdiff
ruby 1.9: monkeypatch MonitorMixin and ConditionVariable
authorfranz <Franz.Netykafka@runbox.com>
Mon, 15 Jun 2009 19:59:56 +0000 (21:59 +0200)
committerGiuseppe Bilotta <giuseppe.bilotta@gmail.com>
Wed, 26 Aug 2009 21:31:37 +0000 (23:31 +0200)
ruby 1.9's ConditionVariable#wait is not implemented for timeout != nil,
this patch adds an implementation for it (see ruby-core:15847)

Also, since MonitorMixin is included into TCPSocket in rbot, and
TCPSocket#send != Object#send in ruby 1.9, i changed that to use
__send__.

bin/rbot
lib/rbot/compat19.rb [new file with mode: 0644]

index dcc8bba43fcbf4eff59c5eae1d2f573735285f39..674f235f5e75d6bda348f314f08e4cdd1bc56e35 100755 (executable)
--- a/bin/rbot
+++ b/bin/rbot
@@ -98,6 +98,11 @@ rescue LoadError => e
   exit 2
 end
 
+# ruby 1.9 specific fixes
+unless RUBY_VERSION < '1.9'
+  require 'rbot/compat19'
+end
+
 if ($opts["version"])
   puts "rbot #{$version}"
   exit 0
diff --git a/lib/rbot/compat19.rb b/lib/rbot/compat19.rb
new file mode 100644 (file)
index 0000000..fbb6847
--- /dev/null
@@ -0,0 +1,70 @@
+#-- vim:sw=2:et
+#++
+#
+# :title: ruby 1.9 compatibility (monkey)patches
+
+require 'timeout'
+require "thread"
+
+class ConditionVariable
+
+  def wait(mutex, timeout=nil)
+    begin
+      # TODO: mutex should not be used
+      @waiters_mutex.synchronize do
+        @waiters.push(Thread.current)
+      end
+      if timeout
+        elapsed = mutex.sleep timeout if timeout > 0.0
+        unless timeout > 0.0 and elapsed < timeout
+          t = @waiters_mutex.synchronize { @waiters.delete Thread.current }
+          signal unless t # if we got notified, pass it along
+          raise TimeoutError, "wait timed out"
+        end
+      else
+        mutex.sleep
+      end
+    end
+    nil
+  end
+
+end
+
+require 'monitor'
+
+module MonitorMixin
+
+  class ConditionVariable
+
+    def wait(timeout = nil)
+      #if timeout
+      #  raise NotImplementedError, "timeout is not implemented yet"
+      #end
+      @monitor.__send__(:mon_check_owner)
+      count = @monitor.__send__(:mon_exit_for_cond)
+      begin
+        @cond.wait(@monitor.instance_variable_get("@mon_mutex"), timeout)
+        return true
+      ensure
+        @monitor.__send__(:mon_enter_for_cond, count)
+      end
+    end
+
+    def signal
+      @monitor.__send__(:mon_check_owner)
+      @cond.signal
+    end
+
+    def broadcast
+      @monitor.__send__(:mon_check_owner)
+      @cond.broadcast
+    end
+
+  end  # ConditionVariable
+
+  def self.extend_object(obj)
+    super(obj)
+    obj.__send__(:mon_initialize)
+  end
+
+end # MonitorMixin