Apple's `fd_set` stores its bits in an array of 32-bit integers, which
means `FD_ISSET()` may read out of bounds if we allocate storage at
byte granularity. There's also a chance that the `select()` call could
corrupt the heap, although I didn't investigate that.
This issue was discovered by LLVM's AddressSanitizer which caught
`FD_ISSET()` trying to read out of bounds.
PR-URL: https://github.com/libuv/libuv/pull/241
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Fedor Indutny <fedor@indutny.com>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Add a per-event loop flag for blocking SIGPROF signals when polling for
events.
The motivation for this addition is to reduce the number of wakeups and
subsequent clock_gettime() system calls when using a sampling profiler.
On Linux, this switches from epoll_wait() to epoll_pwait() when enabled.
Other platforms bracket the poll syscall with pthread_sigmask() calls.
Refs strongloop/strong-agent#3 and strongloop-internal/scrum-cs#37.
PR-URL: https://github.com/libuv/libuv/pull/15
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
The existing probes, all two of them, cause a great deal of pain for
people trying to build libuv on Linux because of SystemTap's dtrace(1)
utilitity not understanding the -xnolibs flag.
We could hack around that but it's easier to just remove the probes:
they are largely useless and unused while still needing a lot of
supporting infrastructure. This commit removes 200 lines of code
and configuration.
Refs joyent/libuv#1478.
Reopen the file descriptor when it refers to a tty. This lets us put the
tty in non-blocking mode without affecting other processes that share it
with us.
This brings back commit 31f9fbc, which was reverted in 20bb1bf. The OSX
select trick is working now.
Original patch by @bnoordhuis
Introduce `int uv_pipe_pending_count(uv_pipe_t*)` and
`uv_handle_type uv_pipe_pending_type(uv_pipe_t*)`. They should be
used in IPC pipe's read cb to accept incoming handles:
int count = uv_pipe_pending_count(pipe);
int i;
for (i = 0; i < count; i++) {
uv_handle_type type = uv_pipe_pending_type(pipe);
/* ... */
uv_accept(...);
}
Every file descriptor opened using libuv should be automatically marked
as CLOEXEC to prevent it from leaking to a child process. Note that
since we are opening fds in a thread pool, there is a possible race
condition between `uv_spawn()` and the `open()` + `uv__cloexec()`. The
rwlock was added to avoid it.
see https://github.com/joyent/node/issues/6905
Set the close-on-exec flag on file descriptors that we've received with
recvmsg() so we don't leak them when calling fork() afterwards.
On Linux, we use the MSG_CMSG_CLOEXEC flag when supported (2.6.23 and
up.)
On older Linux versions and other platforms, we walk the received file
descriptors and set the close-on-exec flag for each fd manually. That
won't entirely avoid race conditions when other threads call fork() or
clone() but at least we're less likely to leak file descriptors now.
When fd is closed and new one (with the same number) is opened inside
kqueue/epoll/port loop's callback - stale events might invoke callbacks
on wrong watchers.
Check if watcher was changed after invocation and invalidate all events
with the same fd.
fix#826
Otherwise `FSEventStreamCreate()` will coalesce events, even if they're
happening in the interval, bigger than supplied `latency`. In other
words, if this flag is not set events will happen in separate callback
only if there was a delay bigger than `latency` between two consecutive
events.
On some systems, clock_gettime(CLOCK_MONOTONIC) is only serviced from
the vDSO when the __vdso_clock_gettime() wrapper is confident enough
that the vDSO timestamp is highly accurate. When in doubt, it falls
back to making a traditional SYS_clock_gettime system call with all
the overhead that entails.
While a commendable approach, it's overkill for our purposes because we
don't usually need high precision time. That's why this commit switches
to CLOCK_MONOTONIC_COARSE for low-precision timekeeping, provided said
clock has at least a one millisecond resolution.
This change should eliminate the system call on almost all systems,
including virtualized ones, provided the kernel is >= 2.6.32 and glibc
is new enough to find and parse the vDSO.
This commit reverts the following commits:
983fa68 darwin: fix 10.6 build error in fsevents.c
684e212 fsevents: use shared FSEventStream
ea4cb77 fsevents: FSEvents is most likely not thread-safe
9bae606 darwin: create fsevents thread on demand
Several people have reported stability issues on OS X 10.8 and bus
errors on the 10.9 developer preview.
See also joyent/node#6296 and joyent/node#6251.
Ensure that close() system calls don't close stdio file descriptors
because that is almost never the intention.
This is also a partial workaround for a kernel bug that seems to affect
all Linux kernels when stdin is a pipe that gets closed: fd 0 keeps
signalling EPOLLHUP but a subsequent call to epoll_ctl(EPOLL_CTL_DEL)
fails with EBADF. See joyent/node#6271 for details and a test case.
* Move CF run loop code to fsevents.c.
* Create the fsevents thread on demand rather than at startup.
* Remove use of ACCESS_ONCE. All accesses to loop->cf_loop are
protected by full memory barriers so no reordering can take place.
Fixes#872.
Conflicts:
src/unix/darwin.c
* Move CF run loop code to fsevents.c.
* Create the fsevents thread on demand rather than at startup.
* Remove use of ACCESS_ONCE. All accesses to loop->cf_loop are
protected by full memory barriers so no reordering can take place.
Fixes#872.
This commit changes the libuv API to return error codes directly rather
than storing them in a loop-global field.
A code snippet like this one:
if (uv_foo(loop) < 0) {
uv_err_t err = uv_last_error(loop);
fprintf(stderr, "%s\n", uv_strerror(err));
}
Should be rewritten like this:
int err = uv_foo(loop);
if (err < 0)
fprintf(stderr, "%s\n", uv_strerror(err));
The rationale for this change is that it should make creating bindings
for other languages a lot easier: dealing with struct return values is
painful with most FFIs and often downright buggy.
Replace a few internal functions in uv-common.h with macros to avoid
strict aliasing warnings with older versions of gcc.
It's not smart enough to figure out that e.g. a uv_tcp_t is an instance
of uv_handle_t with similar alignment requirements and therefore no
aliasing happens. More recent versions of gcc don't suffer from this.
I'm not normally in the habit of catering to compiler defects but the
aliasing warnings drown out legitimate warnings, hence the change.
`#if FOO` (where FOO is undefined) is a legal construct in C89 and C99
but gcc, clang and sparse complain loudly about it at higher warning
levels.
Squelch those warnings. Makes the code more consistent as well.
Fixes a bug where timers expire prematurely when the following
conditions hold:
a) libuv first spends some time blocked in the platform poll function
b) a callback then calls uv_timer_start()
Cause: uv_timer_start() uses an out-of-date loop->time in its
'when should the timer callback run?' calculations.
Solution: Update loop->time before invoking any callbacks.
Fixes#678.
This commit renames the various uv_hrtime() implementations to uv__hrtime().
Libuv uses the high-res timer internally in performance-critical code paths.
Calling the non-public version avoids going through the PLT when libuv is
compiled as a shared object.
The exported uv_hrtime() now has a single definition in src/unix/core.c that
calls uv__hrtime().
A future optimization is to lift the uv__hrtime() declarations into header
files so they can be inlined at the call sites. Then again, linking with -flto
should accomplish the same thing.
Fix a rather obscure bug where the event loop stalls when an I/O watcher is
stopped while an artificial event, generated with uv__io_feed(), is pending.
kqueue(2) on osx doesn't work (emits EINVAL error) with specific fds
(i.e. /dev/tty, /dev/null, etc). When given such descriptors - start
select(2) watcher thread that will emit io events.
This patch creates a new header - ev-proto.h - which contains all of the
protoypes for libev functions. This allows us to create a shared object of
libuv without exposing libev internal functions.
Relocate the include of TargetConditionals.h and fixe the use of
TARGET_OS_IPHONE. Furthermore, uv__fsevents_init() and uv__fsevents_close are
now empty functions for iOS, since the FSEvents API is not available there.
Fixes the following gcc 4.7+ warning:
../src/unix/internal.h:105:13: warning: always_inline function might not be
inlinable [-Wattributes]
gcc wants the always_inline function to be annotated with the 'inline' keyword
which we can't do because we compile in C89 mode.
Using __inline is not an option because that makes clang generate warnings when
-Wlanguage-extension-token is enabled.
Therefore, remove the always_inline attribute altogether and hope that the
compiler is smart enough to inline the functions.
The OS X version was being checked with the __MAC_OS_X_VERSION_MIN_REQUIRED__
macro, but this value doesn't match the actual SDK version when it is
overridden with the -mmacosx-version-min command line switch.
Variables tagged with __read_mostly are put into a separate ELF section to
improve the cache locality of data that is read often but seldom written to.
Don't make the event loop spin when connect() returns EINPROGRESS.
Test case:
#include "uv.h"
static void connect_cb(uv_connect_t* req, int status) {
// ...
}
int main() {
uv_tcp_t handle;
uv_connect_t req;
struct sockaddr_in addr;
addr = uv_ip4_addr("8.8.8.8", 1234); // unreachable
uv_tcp_init(uv_default_loop(), &handle);
uv_tcp_connect(&req, (uv_stream_t*)&handle, addr, connect_cb);
uv_run(uv_default_loop()); // busy loops until connection times out
return 0;
}
After EINPROGRESS, there are zero active handles and one active request. That
in turn makes uv__poll_timeout() believe that it should merely poll, not block,
in epoll() / kqueue() / port_getn().
Sidestep that by artificially starting the handle on connect() and stopping it
again once the TCP handshake completes / is rejected / times out.
It's a slightly hacky approach because I don't want to change the ABI of the
stable branch. I'll address it properly in the master branch.
* replace libev backed timers with a pure libuv implementation
* gut ev_run() and make it take a timeout instead of flags
Incidentally speeds up the loop_count_timed benchmark by about 100%.
This commit changes how the event loop determines if it needs to stay alive.
Previously, an internal counter was increased whenever a handle got created
and decreased again when the handle was closed.
While conceptually simple, it turned out hard to work with: you often want
to keep the event loop alive only if the handle is actually doing something.
Stopped or inactive handles were a frequent source of hanging event loops.
That's why this commit changes the reference counting scheme to a model where
a handle only references the event loop when it's active. 'Active' means
different things for different handle types, e.g.:
* timers: ticking
* sockets: reading, writing or listening
* processes: always active (for now, subject to change)
* idle, check, prepare: only active when started
This commit also changes how the uv_ref() and uv_unref() functions work: they
now operate on the level of individual handles, not the whole event loop.
The Windows implementation was done by Bert Belder.
Always compile in the kqueue-based fs event watcher and handle it at run-time
if the kernel doesn't actually support it.
Works around build issues when -mmacosx-version-min is not set properly.
Fixesjoyent/node#3075.
Previously, a new inotify fd was created for each watcher, making it quite easy
to run into the system-wide fs.inotify.max_user_instances limit (usually 128).
Fixes#300.