about summary refs log tree commit homepage
path: root/lib/rainbows/sync_close.rb
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-12-27 20:25:39 -0800
committerEric Wong <normalperson@yhbt.net>2010-12-28 17:12:28 -0800
commit3495d59763e6159975debf32728dc53fc41c5ea1 (patch)
tree949415250af66075cc9ca98040a85ddc2ad84380 /lib/rainbows/sync_close.rb
parent53afe0b23fc67c5b25541cddbd68f905c649e756 (diff)
downloadrainbows-3495d59763e6159975debf32728dc53fc41c5ea1.tar.gz
Some middlewares require the Rack env to be preserved all
the way through to close, so we'll ensure all request models
preserve it.

We also need to better response body wrappers/proxies always get
fired properly when returning.  IO.copy_stream and "sendfile"
gem users could hit cases where wrappers did not fire properly.
Diffstat (limited to 'lib/rainbows/sync_close.rb')
-rw-r--r--lib/rainbows/sync_close.rb37
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/rainbows/sync_close.rb b/lib/rainbows/sync_close.rb
new file mode 100644
index 0000000..a336262
--- /dev/null
+++ b/lib/rainbows/sync_close.rb
@@ -0,0 +1,37 @@
+# -*- encoding: binary -*-
+# :enddoc:
+require 'thread'
+class Rainbows::SyncClose
+  def initialize(body)
+    @body = body
+    @mutex = Mutex.new
+    @cv = ConditionVariable.new
+    @mutex.synchronize do
+      yield self
+      @cv.wait(@mutex)
+    end
+  end
+
+  def respond_to?(m)
+    @body.respond_to?(m)
+  end
+
+  def to_path
+    @body.to_path
+  end
+
+  def each(&block)
+    @body.each(&block)
+  end
+
+  def to_io
+    @body.to_io
+  end
+
+  # called by the writer thread to wake up the original thread (in #initialize)
+  def close
+    @body.close
+    ensure
+      @mutex.synchronize { @cv.signal }
+  end
+end