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.
Linux 2.6 always closes the file descriptor, even on EINTR. Retrying the close()
call isn't merely useless, it's actively harmful - the file descriptor may have
been acquired by another thread.
Do not check for minimum kernel and glibc versions, just check that the kernel
headers export the syscall number and invoke the syscall directly. Effectively
bypasses glibc.
Do not check for minimum kernel and glibc versions, just check that the kernel
headers export the syscall number and invoke the syscall directly. Effectively
bypasses glibc.