about summary refs log tree commit homepage
path: root/lib/dtas/sigevent/fiddle_efd.rb
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2019-12-20 01:39:14 +0000
committerEric Wong <e@80x24.org>2020-01-06 08:15:13 +0000
commit940c0b3cffa7f691620e7890ada15c7519817307 (patch)
tree50674c3892983abdb78fa2a8597865edf6b05c79 /lib/dtas/sigevent/fiddle_efd.rb
parent044d1e1777f37a77084794fadce86b4865a1ccfc (diff)
downloaddtas-940c0b3cffa7f691620e7890ada15c7519817307.tar.gz
sleepy_penguin requires a compiler and development headers to
install, so it could be a PITA to install for users on
distro-provided Ruby.  Allow fiddle since it's part of the Ruby
standard library since 1.9.2 and users won't have to install
anything else.
Diffstat (limited to 'lib/dtas/sigevent/fiddle_efd.rb')
-rw-r--r--lib/dtas/sigevent/fiddle_efd.rb38
1 files changed, 38 insertions, 0 deletions
diff --git a/lib/dtas/sigevent/fiddle_efd.rb b/lib/dtas/sigevent/fiddle_efd.rb
new file mode 100644
index 0000000..e29f6ca
--- /dev/null
+++ b/lib/dtas/sigevent/fiddle_efd.rb
@@ -0,0 +1,38 @@
+# Copyright (C) 2013-2019 all contributors <dtas-all@nongnu.org>
+# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
+# frozen_string_literal: true
+
+# used in various places for safe wakeups from IO.select via signals
+# This requires a modern GNU/Linux system with eventfd(2) support
+require_relative '../nonblock'
+require 'fiddle'
+class DTAS::Sigevent # :nodoc:
+
+  EventFD = Fiddle::Function.new(DTAS.libc['eventfd'],
+    [ Fiddle::TYPE_INT, Fiddle::TYPE_INT ], # initval, flags
+    Fiddle::TYPE_INT) # fd
+
+  attr_reader :to_io
+  ONE = [ 1 ].pack('Q').freeze
+
+  def initialize
+    fd = EventFD.call(0, 02000000|00004000) # EFD_CLOEXEC|EFD_NONBLOCK
+    raise "eventfd failed: #{Fiddle.last_error}" if fd < 0
+    @to_io = DTAS::Nonblock.for_fd(fd)
+    @buf = ''.b
+  end
+
+  def signal
+    @to_io.syswrite(ONE)
+  end
+
+  def readable_iter
+    @to_io.read_nonblock(8, @buf, exception: false)
+    yield self, nil # calls DTAS::Process.reaper
+    :wait_readable
+  end
+
+  def close
+    @to_io.close
+  end
+end