about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2013-04-12 02:05:54 +0000
committerEric Wong <normalperson@yhbt.net>2013-04-12 22:25:13 +0000
commit4c4a6ae523bc7bac4be0fd4dc104b055161ad260 (patch)
tree6c454735d3c8ce6e7fd853865ef20fbdb87d80cc
parent26ba5806ddf9bce97c55f40c741da7d2e29aafbc (diff)
downloadsleepy_penguin-4c4a6ae523bc7bac4be0fd4dc104b055161ad260.tar.gz
Rubinius provides a Rubinius.synchronize helper for locking
objects which do not otherwise have locks.  We need to
synchronize Inotify#take access to prevent the internal array
from being clobbered.

This avoids unnecessary locking overhead on MRI which maintains
a GVL.
-rw-r--r--lib/sleepy_penguin.rb15
1 files changed, 15 insertions, 0 deletions
diff --git a/lib/sleepy_penguin.rb b/lib/sleepy_penguin.rb
index c13eb0c..1888e3b 100644
--- a/lib/sleepy_penguin.rb
+++ b/lib/sleepy_penguin.rb
@@ -6,3 +6,18 @@ module SleepyPenguin
 end
 require 'sleepy_penguin_ext'
 require 'sleepy_penguin/epoll'
+
+# :stopdoc:
+#
+# We need to serialize Inotify#take for Rubinius since that has no GVL
+# to protect the internal array
+if defined?(SleepyPenguin::Inotify) &&
+   defined?(Rubinius) && Rubinius.respond_to?(:synchronize)
+  class SleepyPenguin::Inotify
+    alias __take take
+    undef_method :take
+    def take(*args)
+      Rubinius.synchronize(@inotify_tmp) { __take(*args) }
+    end
+  end
+end