about summary refs log tree commit homepage
path: root/lib/dtas/buffer/splice.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dtas/buffer/splice.rb')
-rw-r--r--lib/dtas/buffer/splice.rb17
1 files changed, 11 insertions, 6 deletions
diff --git a/lib/dtas/buffer/splice.rb b/lib/dtas/buffer/splice.rb
index 281ecfd..b9957ce 100644
--- a/lib/dtas/buffer/splice.rb
+++ b/lib/dtas/buffer/splice.rb
@@ -1,10 +1,12 @@
-# Copyright (C) 2013-2019 all contributors <dtas-all@nongnu.org>
+# Copyright (C) 2013-2020 all contributors <dtas-all@nongnu.org>
 # License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
 # frozen_string_literal: true
 require 'io/nonblock'
 require 'sleepy_penguin'
 require_relative '../../dtas'
 require_relative '../pipe'
+SleepyPenguin.respond_to?(:splice) or
+  raise LoadError, 'sleepy_penguin 3.5+ required for splice', []
 
 # Used by -player on Linux systems with the "sleepy_penguin" RubyGem installed
 module DTAS::Buffer::Splice # :nodoc:
@@ -12,7 +14,6 @@ module DTAS::Buffer::Splice # :nodoc:
   MAX_AT_ONCE_1 = 65536
   F_MOVE = SleepyPenguin::F_MOVE
   F_NONBLOCK = SleepyPenguin::F_NONBLOCK
-  TRY = { exception: false }.freeze
 
   def buffer_size
     @to_io.pipe_size
@@ -32,12 +33,14 @@ module DTAS::Buffer::Splice # :nodoc:
   def broadcast_one(targets, limit = nil)
     # single output is always non-blocking
     limit ||= MAX_AT_ONCE_1
-    s = SleepyPenguin.splice(@to_io, targets[0], limit, F_MOVE|F_NONBLOCK, TRY)
+    s = SleepyPenguin.splice(@to_io, targets[0], limit, F_MOVE|F_NONBLOCK,
+                             exception: false)
     if Symbol === s
       targets # our one and only target blocked on write
     else
       @bytes_xfer += s
-      :wait_readable # we want to read more from @to_io soon
+      # s < limit means targets[0] is full
+      s < limit ? targets : :wait_readable
     end
   rescue Errno::EPIPE, IOError => e
     __dst_error(targets[0], e)
@@ -71,7 +74,8 @@ module DTAS::Buffer::Splice # :nodoc:
     targets.delete_if do |dst|
       begin
         t = (dst.nonblock? || most_teed == 0) ?
-            SleepyPenguin.tee(@to_io, dst, chunk_size, F_NONBLOCK, TRY) :
+            SleepyPenguin.tee(@to_io, dst, chunk_size, F_NONBLOCK,
+                              exception: false) :
             __tee_in_full(@to_io, dst, chunk_size)
         if Integer === t
           if t > most_teed
@@ -119,7 +123,8 @@ module DTAS::Buffer::Splice # :nodoc:
     begin
       targets << last
       if last.nonblock? || most_teed == 0
-        s = SleepyPenguin.splice(@to_io, last, bytes, F_MOVE|F_NONBLOCK, TRY)
+        s = SleepyPenguin.splice(@to_io, last, bytes, F_MOVE|F_NONBLOCK,
+                                 exception: false)
         if Symbol === s
           blocked << last