Date | Commit message (Collapse) |
|
This makes it easier to avoid file name conflicts while also
improving startup performance by attempting fewer paths.
|
|
Ruby 1.8 is long dead and we already broke 1.9 support by using
keyword args for splice, sendfile, and copy_file_range support.
|
|
Users may wish to use our epoll or kqueue interfaces within
their own app running on a web server or some such.
This prevents users from missing events at an increased
allocation cost.
|
|
Unlikely, but we must not leak memory if pthread_setspecific
somehow fails.
|
|
We need to support FreeBSD, at least.
|
|
This will also allow non-Linux users to use sendfile
if it is not available.
|
|
Keyword args allows for a smaller interface for common use,
while retaining the capability to use offsets for both input and
output. The current (2.4) Ruby C API for keyword args is slow
and creates too many garbage objects. As with our splice
wrapper, use a pure Ruby wrapper around an internal C function.
|
|
This was never in any released version of "sleepy_penguin",
and the same information may be queried via the 'etc'
extension since Ruby 2.2:
require 'etc'
IO.pipe { |r, w| w.pathconf(Etc::PC_PIPE_BUF) }
|
|
This is a part of the "io_splice" RubyGem we will not be
supporting in "sleepy_penguin".
|
|
Since we're breaking away from the old io_splice gem,
we have liberty to change the API when moving to a new
namespace. This might allow us to simplify the common
case args and reduce the amount of C code we maintain.
|
|
I had a recent linux-libc-dev installed with my kernel, so I did
not notice these mistakes until I installed only an updated
kernel without the headers. The old number (285) is the generic
base syscall number.
|
|
It's not our fault, it's the kernels :P
|
|
This should hopefully simplify logic a bit and avoid expensive
access to errno.
|
|
Under Linux 4.5, this allows for efficient copies and
is similar to the splice and sendfile system calls.
|
|
Since these are Linux-specific syscalls, it makes sense to
include it here. This is taken from the "io_splice" RubyGem,
but this may supercede that.
Note: this does not include a vmsplice(2) wrapper
|
|
The long constant name conveys no additional info. Since
epoll_create1 is rarely called, and a cache lookup for cold
code is wasfeful
|
|
We'll prefer using rb_str_new2 instead of rb_str_new(...,strlen)
to save binary size. While we're at it, explain why we cannot
take e->len into account for plain-old rb_str_new.
|
|
Many systems have inotify_init1 nowadays, so use inotify_init1
if it is available to avoid unnecessary syscalls.
|
|
The check for libkqueue may succeed out-of-the-box on Debian systems
where libkqueue-dev is installed. However, libkqueue-dev on Debian
installs sys/event.h in a non-standard include path
(/usr/include/kqueue), so it is not picked up by default and
kqueue support is never compiled.
So only check for (and link to) libkqueue if we are configured
to detect sys/event.h. This should not affect users on *BSD
platforms with native kqueue support.
|
|
Storing heap-allocated memory in __thread is not feasible for a
library since it provides no automatic resource de-allocation.
This oversight caused rare applications which use short-lived
threads for epoll_wait, kevent, or inotify read to leak memory over
time. So we refactor everything to use pthread_* thread-local
storage APIs instead.
While we're at it, we can safely use a common, generic buffer for
inotify, epoll, and kevent to avoid running into PTHREAD_KEYS_MAX
limitations.
These leaks only affected sleepy_penguin v3.2.0 and later, and
only applications which use short-lived threads to call epoll_wait,
kevent and inotify read.
|
|
rb_inspect is unlikely to put a \0 byte in the middle of a string,
but use StringValueCStr anyways just in case to catch potential bugs.
|
|
https://github.com/rubinius/rubinius/issues/2771
|
|
They're long disabled, and there's no way for them to work sanely
inside any VM/language which supports signal handlers. There's
little need, even, as Ruby has a good API for signal handlers and we
have eventfd support.
|
|
This makes our code slightly smaller on Ruby 1.9+
|
|
This is already defined for most (if not all) Rubies when ruby.h
is included.
|
|
RARRAY_PTR incurs extra overhead on the Ruby 2.1.0 and Rubinius
GC implementations, so avoid it. None of these are believed
to be performance-critical enough to benefit from RARRAY_PTR
in older Rubies, either.
|
|
Fallback mechanism was copied from clogger:
http://clogger.rubyforge.org/
This would also make sleepy_penguin compiles on Mac OS X,
which is lacking clock_gettime. All tests passed for me.
[ew: fixed indentation
Note: this project does not and will never officially support
non-Free OSes, but there are likely other systems without
clock_gettime but has kqueue (perhaps via libkqueue).]
Signed-off-by: Eric Wong <normalperson@yhbt.net>
|
|
This allows the Ruby-visible constant to always be up-to-date
with the release.
|
|
The underlying kevent() itself already bypasses the timeout
if nevents==0 (so it is impossible to emulate a sleep function
with kevent()).
|
|
Hopefully this will lead to less confusion among new
users.
|
|
To be consistent with I/O wrappers in Ruby, Ruby-land should
never see EINTR from kevent or epoll_wait. We will just return
zero events if our timeout expired soon after we got signaled.
|
|
Rubinius will not support RSTRUCT* macros, so converting the
structs to arrays is the least intrusive way to go about our
code.
ref: https://github.com/rubinius/rubinius/issues/494
|
|
Having a timeout does not make sense if not retrieving events,
so avoid potentially triggering bugs or strange behavior between
different kqueue implementations.
|
|
This is still a work-in-progress, but allows us to support
using a kqueue descriptor from multiple threads.
(e.g. one thread waiting with kevent, while another thread
modifies the watch list via kevent)
|
|
We will support kqueue on FreeBSD-based systems.
|
|
This prevents overflow and excessive memory usage/OOM error.
Note: the kernel enforces this and returns EINVAL anyways,
we just do it to prevent OOM here.
|
|
When possible, comparisons against zero require one less load
and uses one less register, so this results in smaller code:
$ ~/linux/scripts/bloat-o-meter before.so after.so
add/remove: 0/0 grow/shrink: 0/5 up/down: 0/-57 (-57)
function old new delta
rm_watch 84 83 -1
rb_sp_set_nonblock 80 79 -1
add_watch 127 126 -1
epwait 692 687 -5
s_new 970 921 -49
This style is favored by major C projects, including glibc.
Note: since file and file descriptor flags may eventually use
more bits of an integer, we continue comparing F_GETFD/F_GETFL
return values against -1 to be future proof.
|
|
Ruby 2.0 creates file descriptors with the close-on-exec flag
specified by default. Unless a user specifies flags explicitly,
assume the default is to set the close-on-exec.
This does not change behavior of Ruby 1.9 and earlier.
|
|
We no longer need to use pthread_* functionality.
|
|
rb_thread_blocking_region is deprecated in Ruby 2.0, but
rb_thread_io_blocking region is not (and superior for I/O). So we will
favor rb_thread_io_blocking_region for now.
While we're at it, reimplement green-thread-safe (Ruby 1.8) epoll_wait
in Ruby instead of C. The extra #ifdefs for 1.8.7 were more prone to
bitrot and Ruby code should be easier to follow for Rubyists who care
about 1.8.
|
|
This gives us thread-safety for the internal buffer. While
we're at it, cache-align this buffer to avoid unnecessary
overhead when read() writes to it.
|
|
ENOMEM from syscalls such as inotify_add_watch and epoll_ctl are
from the lack of kernel memory, so even a successful rb_gc() is
unlikely to be able to reap memory taken from those slab caches.
|
|
This probably won't make a huge difference in Ruby, but perhaps
one day the unnecessary dirtying of cache lines will affect
performance (and we'll be ready when that day comes).
While we're at it, remove usage of pthread* functions for
thread-local variables. The __thread construct from GCC (and
also implemented by clang) is much easier-to-use than the
pthread_*specific API.
|
|
Epoll::IO is a dangerous, low-level class which is intended
for users aware of the GC and fork behavior of epoll in the
Linux kernel.
Rewriting the higher-level Epoll in Ruby makes it easier to
maintain, especially since Rubinius has no GVL while running
C extensions.
|
|
I was about to change this to the FIONBIO here myself before
I realized we do not frequently _change_ file flags.
|
|
The file descriptor may be closed while GVL is released,
so we must reload the descriptor before and after calling
rb_io_wait_*able functions.
We reload before calling rb_io_wait_*able because the GVL was
released for the function call (read/write) which triggered
EAGAIN.
We reload after calling rb_io_wait_*able because
rb_io_wait_*able releases the GVL, too.
|
|
We forgot to update this documentation when we released 3.1.0
|
|
pthread_once_t must be static to be effective. This bug only
affects apps which load sleepy_penguin multiple times.
|
|
This was added in Linux 3.5 and glibc 2.17
|
|
This reverts commit 02e5a91b24983d96b342c007661966495ccdb619.
This workaround may have unintended side-effects for apps using
EPOLL_CTL_DEL.
|