From 940c0b3cffa7f691620e7890ada15c7519817307 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 20 Dec 2019 01:39:14 +0000 Subject: provide fiddle-based eventfd implementation 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. --- lib/dtas/sigevent/efd.rb | 2 ++ lib/dtas/sigevent/fiddle_efd.rb | 38 ++++++++++++++++++++++++++++++++++++++ lib/dtas/sigevent/pipe.rb | 2 +- 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 lib/dtas/sigevent/fiddle_efd.rb (limited to 'lib/dtas/sigevent') diff --git a/lib/dtas/sigevent/efd.rb b/lib/dtas/sigevent/efd.rb index 4be2c84..22772ee 100644 --- a/lib/dtas/sigevent/efd.rb +++ b/lib/dtas/sigevent/efd.rb @@ -3,6 +3,8 @@ # used in various places for safe wakeups from IO.select via signals # This requires a modern Linux system and the "sleepy_penguin" RubyGem +require 'sleepy_penguin' + class DTAS::Sigevent < SleepyPenguin::EventFD # :nodoc: def self.new super(0, :CLOEXEC) 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 +# License: GPL-3.0+ +# 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 diff --git a/lib/dtas/sigevent/pipe.rb b/lib/dtas/sigevent/pipe.rb index 921a5b3..0ea9d31 100644 --- a/lib/dtas/sigevent/pipe.rb +++ b/lib/dtas/sigevent/pipe.rb @@ -3,7 +3,7 @@ # frozen_string_literal: true # used in various places for safe wakeups from IO.select via signals -# A fallback for non-Linux systems lacking the "sleepy_penguin" RubyGem +# A fallback for non-Linux systems lacking the "splice" syscall require_relative '../nonblock' class DTAS::Sigevent # :nodoc: attr_reader :to_io -- cgit v1.2.3-24-ge0c7