about summary refs log tree commit homepage
path: root/lib/rainbows/fiber
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-11-25 19:01:34 -0800
committerEric Wong <normalperson@yhbt.net>2009-11-25 19:07:01 -0800
commitdd2b2274ef0cd8a121cf7655ade939a1f63bc971 (patch)
tree053dbbd07b6dc3b1339f1ea19ad22afd8add52f3 /lib/rainbows/fiber
parent7f11b212f78a5070bea17bc20af43395b6cc621d (diff)
downloadrainbows-dd2b2274ef0cd8a121cf7655ade939a1f63bc971.tar.gz
This enables the safe use of Rainbows::AppPool with all
concurrency models, not just threaded ones.  AppPool is now
effective with *all* Fiber-based concurrency models including
Revactor (and of course the new Fiber{Pool,Spawn} ones).
Diffstat (limited to 'lib/rainbows/fiber')
-rw-r--r--lib/rainbows/fiber/queue.rb33
1 files changed, 33 insertions, 0 deletions
diff --git a/lib/rainbows/fiber/queue.rb b/lib/rainbows/fiber/queue.rb
new file mode 100644
index 0000000..4c14f19
--- /dev/null
+++ b/lib/rainbows/fiber/queue.rb
@@ -0,0 +1,33 @@
+module Rainbows
+  module Fiber
+
+    # a self-sufficient Queue implmentation for Fiber-based concurrency
+    # models
+    class Queue < Struct.new(:queue, :waiters)
+
+      def initialize(queue = [], waiters = [])
+        # move elements of the Queue into an Array
+        if queue.class.name == "Queue"
+          queue = queue.length.times.map { queue.pop }
+        end
+        super queue, waiters
+      end
+
+      def shift
+        # ah the joys of not having to deal with race conditions
+        if queue.empty?
+          waiters << ::Fiber.current
+          ::Fiber.yield
+        end
+        queue.shift
+      end
+
+      def <<(obj)
+        queue << obj
+        blocked = waiters.shift and blocked.resume
+        queue # not quite 100% compatible but no-one's looking :>
+      end
+
+    end
+  end
+end