Date | Commit message (Collapse) |
|
RAA is dead
|
|
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.
|
|
Ruby 2.1.0 raises a subclass of Errno::EINPROGRESS, which fails the
exact matching of assert_raises. This does not affect any known
real code.
|
|
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>
|
|
epoll support and thread-safety improvements. The dangerous
Epoll::IO interface is now an option for those who want to share an
epoll descriptor across fork and maintain their own IO object
references to avoid extra overhead. Use the regular (high-level)
Epoll interface unless you're willing to shoot yourself in the face.
There is also preliminary Kqueue support (which should work under
libkqueue on Linux). Similar to our epoll interface (and unlike
most event libraries/frameworks) our kqueue interface also supports
one-shot notifications and _embraces_ multi-threaded use.
Note: unlike epoll, kqueue has close-on-fork behavior, so kqueue
descriptors are not (ever) inheritable across fork.
Added EPOLLWAKEUP constant (Linux 3.5 + glibc 2.17 required) to
allow descriptors to prevent system suspend while active
(this requires the CAP_BLOCK_SUSPEND privilege).
Inotify and Epoll interfaces now use thread-local buffers for
thread-safety and improved concurrency without GVL.
Errno::EINTR is no longer propagated into Ruby-land, for consistency
with existing Ruby IO APIs.
|
|
Oops, the lack of this header prevented gems from being
built + installed properly.
|
|
A subclass may want to set CLOEXEC by default.
|
|
This allows the Ruby-visible constant to always be up-to-date
with the release.
|
|
We support kqueue and Rubinius. Nowadays, we also export
the potentially dangerous low-level APIs for epoll and kqueue.
|
|
We need to ensure Kqueue::IO remains IO-like
|
|
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.
|
|
Wait longer before killing the epoll_wait thread, as we may not
have entered epoll_wait inside that thread before we send
Thread#kill to it. This caused intermittent IOError as the
thread delected the Epoll::IO object was already closed, before
the snapshot (to prevent GC) could be made.
|
|
This allows the heap to reclaim memory sooner (than waiting for
GC), lowering memory usage and perhaps speeding up future
allocations.
|
|
Frequently sending signals can lead to high memory usage and
slowdowns on some Ruby + malloc implementations.
|
|
We want to avoid closing the descriptor while the thread
is running.
|
|
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
|
|
First off, the timeout is not handled properly when timing out,
resulting in an infinite loop.
Secondly, arguments were not passed to the yielded block correctly.
Finally, the return value of kevent was not returned correctly to
the caller.
|
|
The high-level kqueue class is not usable without IO#autoclose
|
|
Due to strange scheduling, the ensure clause could fire while
the thread was still inside wr.syswrite even though the main
thread received the event and exited the method.
|
|
Threads do not seem safe to start inside signal handlers on
Matz Ruby 1.8
|
|
Having a timeout does not make sense if not retrieving events,
so avoid potentially triggering bugs or strange behavior between
different kqueue implementations.
|
|
This test failed on overloaded systems (and may still fail)
Unfortunately timers are hard to test as system latency
must be taken into account.
|
|
This is not _my_ common use case, but some people may
want to fetch multiple events at once.
|
|
It's good to cleanup after ourselves.
|
|
We need to validate the underlying IO object before using
it in a forked child.
|
|
It's generally unsafe to sleep inside a signal handler, and
seems to cause intermittent test failures.
|
|
These skips no longer seem needed. Removed the GC tests since
they were unreliable (even on MRI), anyways.
|
|
assert_nothing_raised hides backtraces on real errors,
so we'll stop doing it, now.
|
|
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)
|
|
This allows us to use something like:
make build EXTCONF_ARGS='--with-kqueue-include=/usr/include/kqueue \
--with-kqueue-libs=-lkqueue'
To build with libkqueue.
|
|
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.
|
|
Ruby 2.0 is out and we're compatible. Also, we've always
supported EPOLLONESHOT, promote it.
|
|
Our usage of rdoc was incorrect in some places and causing
internal methods to become visible.
|
|
This was forgotten for some reason, no longer.
|
|
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.
|
|
Rubinius provides a Rubinius.synchronize helper for locking
objects which do not otherwise have locks. We need to
synchronize Inotify#take access to prevent the internal array
from being clobbered.
This avoids unnecessary locking overhead on MRI which maintains
a GVL.
|
|
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.
|
|
require_paths and date are automatically set in modern RubyGems
versions. Since we only use modern RubyGems versions, the
licenses= accessor is also activated.
Since the FSF may change mailing addresses again in the future,
prefer the web address to point to licenses. This change is
acceptable for GNU projects, so it should be for us, too:
http://sourceware.org/bugzilla/show_bug.cgi?id=13673
|
|
Rubinius drops this directory on us nowadays
|
|
This helps avoid test errors on Rubinius where rb_gc() is a noop.
Otherwise, we might as well infinite loop on thread-creation to
trigger GC.
|
|
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.
|
|
Concurrent modification of Arrays is thread-unsafe and must be
protected by a Mutex. eventpoll objects inside the Linux kernel
are similarly protected by a (kernel) mutex, and do not need
additional locking.
However, we lock around epoll_ctl here anyways since we must
modify our userland arrays after we modify the kernel structure.
We must modify userland arrays after the kernel structure to
prevent epoll_wait callers from seeing an unreferenced object.
|