about summary refs log tree commit homepage
path: root/lib/yahns/wbuf_common.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/yahns/wbuf_common.rb')
-rw-r--r--lib/yahns/wbuf_common.rb32
1 files changed, 32 insertions, 0 deletions
diff --git a/lib/yahns/wbuf_common.rb b/lib/yahns/wbuf_common.rb
new file mode 100644
index 0000000..e621311
--- /dev/null
+++ b/lib/yahns/wbuf_common.rb
@@ -0,0 +1,32 @@
+# -*- encoding: binary -*-
+# Copyright (C) 2009-2013, Eric Wong <normalperson@yhbt.net> et. al.
+# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
+require 'sendfile'
+module Yahns::WbufCommon # :nodoc:
+  # returns nil on success, :wait_*able when blocked
+  # currently, we rely on each thread having exclusive access to the
+  # client socket, so this is never called concurrently with wbuf_write
+  def wbuf_flush(client)
+    case rv = client.trysendfile(@tmpio, @sf_offset, @sf_count)
+    when Integer
+      return wbuf_close(client) if (@sf_count -= rv) == 0 # all sent!
+
+      @sf_offset += rv # keep going otherwise
+    when :wait_writable, :wait_readable
+      return rv
+    else
+      raise "BUG: #{rv.nil? ? "EOF" : rv.inspect} on tmpio=#{@tmpio.inspect} " \
+            "sf_offset=#@sf_offset sf_count=#@sf_count"
+    end while true
+  end
+
+  def wbuf_close_common(client)
+    @body.close if @body.respond_to?(:close)
+    if @wbuf_persist.respond_to?(:call) # hijack
+      @wbuf_persist.call(client)
+      :delete
+    else
+      @wbuf_persist # true or false or Yahns::StreamFile
+    end
+  end
+end