Commit Graph

55 Commits

Author SHA1 Message Date
Jason Madden
fd7ce57f2b unix: make loops and watchers usable after fork()
Added the uv_loop_fork() API that must be called in a child process to
continue using an existing loop. Internally this calls a uv__io_fork
function for each supported platform, similar to the way
uv__platform_loop_init works.

After this call, existing and new IO, async and signal watchers will
contiue working as before on all platforms, as will the
threadpool (although any threads it was using are of course gone).

On Linux and BSDs that use kqueue, existing and new fsevent watchers
will also continue to work as expected. On OS X, though, directory
fsevents will not be able to use the optimized CoreFoundation path if
they had already been used in the parent process, instead falling back
to the kqueue path used on other BSDs.

Existing fsevent watchers will not function on AIX or SunOS. This
could be relatively easily fixed by someone with AIX knowledge in the
future, but SunOS will require some additional work to keep track if
the watchers.

A new test file, test/test-fork.c, was added to contain fork-related
tests to verify functionality in the child process.

PR-URL: https://github.com/libuv/libuv/pull/846
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
2017-03-21 12:23:44 +01:00
Ben Noordhuis
5fc8aecd81 unix: simplify async watcher dispatch logic
Remove the unused `nevents` parameter from `uv__async_event()`
and remove the indirection of having a separate `uv__async`
type.  There is only one instance per event loop these days.

This incidentally removes the `assert(n == sizeof(val))` in a
Linux-specific code path that some users seem to hit from time
to time.  The cause is not well-understood and I've never been
able to reproduce it myself.  Presumably libuv gets an EAGAIN
when trying to read from the eventfd but when and why that
happens is unclear.

Since the byte count is unused, removing the assert seems safe.
Worst case, libuv sometimes iterates over the async watcher list
when it doesn't have to.

Fixes: https://github.com/libuv/libuv/issues/1171
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Supersedes: https://github.com/libuv/libuv/pull/1214
2017-03-15 10:03:10 +01:00
Ben Noordhuis
ff0ae10496 unix: preserve loop->data across loop init/done
Libuv leaves loop->data unchanged in uv_loop_init() and uv_loop_done()
on Windows but it clobbered it on UNIX platforms.  This commit fixes
that inconsistency.

PR-URL: https://github.com/libuv/libuv/pull/951
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
2016-07-30 10:49:19 +02:00
Willem Thiart
2a51b61e46 unix, win: make uv_loop_init return on error
Makes uv_loop_init return an error code instead of aborting.

Currently uv_loop_init aborts if there are insufficient resources
available. As a user I want to be able to check the return code from
uv_loop_init and decide how I respond rather than having my process die.

PR-URL: https://github.com/libuv/libuv/pull/405
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
2015-08-20 17:39:21 +02:00
Saúl Ibarra Corretgé
bddd6a8489 core: add ability to customize memory allocator
This patch is composed by the work done in
https://github.com/libuv/libuv/pull/231 and
https://github.com/libuv/libuv/pull/287 plus some changes by yours
truly.

Thanks @beevik and @mattsta for their work on this!

PR-URL: https://github.com/libuv/libuv/pull/368
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-06-02 12:05:20 +02:00
Saúl Ibarra Corretgé
1f711e4d6d Revert "memory: add uv_replace_allocator"
This reverts commit c272f1f1bc.

The concept will come back to libuv, but it needs some more work.
2015-04-29 09:37:02 +02:00
Brett Vickers
c272f1f1bc memory: add uv_replace_allocator
With uv_replace_allocator, it's possible to override the default
memory allocator's malloc and free calls with functions of the user's
choosing. This allows libuv to interoperate with projects requiring a
custom memory allocator.

Internally, all calls to malloc and free have been replaced with
uv__malloc and uv__free, respectively. The uv__malloc and uv__free
functions call malloc and free unless they have been overridden by a
previous call to uv_replace_allocator.

As part of this change, the special aligned memory allocations
performed in src/win/fs-event.c have been replaced with standard
allocations. The 4-byte alignment being requested in this file was
unnecessary, since standard allocators already guarantee at least an
8-byte alignment.

PR-URL: https://github.com/libuv/libuv/pull/231
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
2015-03-05 20:02:16 +01:00
Andrius Bentkus
32747c75ce win,unix: move loop functions which have identical implementations
uv_default_loop, uv_loop_new, uv_loop_close, uv_loop_delete

PR-URL: https://github.com/libuv/libuv/pull/144
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-by: Saúl Ibarra Corretgé <saghul@gmail.com>
2015-01-20 12:22:28 +01:00
Ben Noordhuis
a6f2a4f834 Merge branch 'v0.10' into v1.x
Conflicts:
	AUTHORS
	ChangeLog
	README.md
	config-unix.mk
	include/uv.h
	src/unix/internal.h
	src/unix/kqueue.c
	src/unix/linux-core.c
	src/unix/stream.c
	src/uv-common.c
	src/uv-common.h
	src/version.c
	test/test-osx-select.c
2014-12-05 19:18:36 +01:00
Ben Noordhuis
9da5fd443e unix, windows: add uv_loop_configure() function
The only supported option right now is UV_LOOP_BLOCK_SIGNAL, which only
supports the SIGPROF signal and only on UNIX platforms.  So yes, it is
kind of limited right now.  But everything has to start somewhere.

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>
2014-12-05 17:39:43 +01:00
Saúl Ibarra Corretgé
2d5eaea1cd unix: simplify how process handle queue is managed 2014-09-04 10:06:52 +02:00
John Firebaugh
2cd91f9768 unix, windows: move uv_loop_close out of assert
Closes #1387
2014-08-02 09:41:09 +02:00
Saúl Ibarra Corretgé
2611ef43b1 unix, windows: add assertion in uv_loop_delete 2014-02-27 01:05:54 +01:00
Saúl Ibarra Corretgé
787f5fff92 unix, windows: add uv_loop_init and uv_loop_close
These functions supersede uv_loop_new and uv_loop_delete.
uv_loop_init initialized a user allocated loop and uv_loop_close
removes all associated resources a loop uses after it has finished
execution.

uv_loop_new and uv_loop_delete are now deprecated.
2014-02-21 09:56:13 +01:00
Ben Noordhuis
f17c535b73 unix: use a heap for timers
Replace the red-black tree with a heap.  The most common operation that
libuv performs on timers is looking up the first timer to expire.  With
a red-black tree, that operation is O(log n).  With a heap, it's O(1).
2014-02-19 13:36:14 +01:00
Fedor Indutny
6abe1e4b95 fs: uv__cloexec() opened fd
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
2014-02-01 01:02:37 +04:00
Ben Noordhuis
21c37a7db8 linux: use CLOCK_MONOTONIC_COARSE if available
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.
2013-10-29 21:24:42 +01:00
Ben Noordhuis
359d667893 unix: sanity-check fds before closing
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.
2013-10-01 03:55:54 +02:00
Ben Noordhuis
12933f43c9 unix: move loop functions from core.c to loop.c
Move uv_default_loop(), uv_loop_new() and uv_loop_delete() to loop.c.
2013-08-27 22:48:16 +02:00
Ben Noordhuis
3f2d4d5358 unix: req queue must be empty when destroying loop
Assert that the request queue is empty when destroying the event loop.

Should catch errors where people call uv_loop_delete() when there are
still in-progress work requests (for example.)
2013-08-27 22:48:16 +02:00
Ben Noordhuis
3ee4d3f183 unix, windows: return error codes directly
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.
2013-07-07 09:51:00 +02:00
Ben Noordhuis
0635e29714 unix, windows: remove ngx-queue.h
Avoids an extra #include in public headers and stops the ngx_queue_*
types and macros from leaking into user code.
2013-03-27 00:09:36 +01:00
Saúl Ibarra Corretgé
bb3d1e24da unix, windows: add uv_stop, stop running event loop 2013-02-25 16:21:37 +01:00
Ben Noordhuis
92151658eb unix: abstract away async pipe infrastructure
This commit lays the groundwork for the switch to eventfds on Linux.
2013-02-25 02:36:52 +01:00
Shigeki Ohtsu
fadfeaf6ec unix,windows: fix timer order in case of same timeout
Compare start_id of timer handles when they have the same timeout.
start_id is allocated with loop->timer_counter in uv_timer_start.
2013-02-10 17:46:22 +01:00
Ben Noordhuis
339033afc0 unix: use uv__hrtime() internally
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.
2013-01-06 17:35:34 +01:00
Ben Noordhuis
1282d64868 unix: remove dependency on libev 2012-11-16 17:33:25 +01:00
Ben Noordhuis
b7f38b1e53 Revert "unix: avoid iterating over all async handles"
This reverts commit 209abbab27.

Fixes the following SIGSEGV:

  (gdb) f 1
  #1  0x00007fc084683aec in uv__async_io (loop=0x7fc0848e0b40,
  handle=0x7fc0848e0c78, events=1) at src/unix/async.c:175
  175             ASYNC_CB(h)
  (gdb) list
  170
  171         /* If we need to sweep all handles anyway - skip this loop */
  172         if (!loop->async_sweep_needed) {
  173           for (i = 0; i < end; i += sizeof(h)) {
  174             h = *((uv_async_t**) (buf + i));
  175             ASYNC_CB(h)
  176           }
  177         }
  178
  179         bytes -= end;
  (gdb) print *h
  $1 = {close_cb = 0x184e1b0, data = 0x18d9520, loop = 0x7fc0848e0b40,
  type = 49, handle_queue = {prev = 0x18dae10, next = 0x7860c0}, flags = 32,
  next_closing = 0x1863b40, pending = 0, async_cb = 0x31,
  queue = {prev = 0x18dae50, next = 0x7860c0}}
  (gdb)

It looks like the async handle gets closed or otherwise becomes invalid before
the sweep is executed.

Fixes #603.
2012-10-24 14:58:49 +02:00
Fedor Indutny
209abbab27 unix: avoid iterating over all async handles 2012-10-19 17:22:30 +02:00
Bert Belder
1e32cb01b5 unix: support signal handlers outside the main loop 2012-10-17 01:25:02 +02:00
Ben Noordhuis
74999f8f99 unix: port fs and work api to new thread pool 2012-10-01 22:53:59 +02:00
Ben Noordhuis
f35a4b628a unix: add custom thread pool 2012-10-01 22:53:59 +02:00
Ben Noordhuis
4f8e2a8e8e unix: close async pipe fds on loop delete 2012-09-28 07:44:40 +02:00
Ben Noordhuis
4f5c8da191 unix: reimplement accept() EMFILE trick
Implement a best effort approach to mitigating accept() EMFILE errors.

We have a spare file descriptor stashed away that we close to get below
the EMFILE limit. Next, we accept all pending connections and close them
immediately to signal the clients that we're overloaded - and we are, but
we still keep on trucking.

There is one caveat: it's not reliable in a multi-threaded environment.
The file descriptor limit is per process. Our party trick fails if another
thread opens a file or creates a socket in the time window between us
calling close() and accept().

Fixes #315.
2012-09-10 22:12:30 +02:00
Ben Noordhuis
894b0fc0a7 unix: move platform init out of loop.c
Move platform-specific initialization logic out of loop.c and into the
platform files (freebsd.c, sunos.c, etc).
2012-08-17 14:48:52 +02:00
Ben Noordhuis
75ba681913 unix: remove dependency on ev_child 2012-08-10 02:00:11 +02:00
Ben Noordhuis
ee50db6e36 unix, windows: preliminary signal handler support
* a no-op on Windows for now
* only supports the main loop on UNIX (again, for now)
2012-08-10 02:00:07 +02:00
Bert Belder
a069956996 Remove c-ares integrations 2012-08-07 01:03:52 +02:00
Ben Noordhuis
4fe1916926 linux: fix 'two watchers, one path' segfault
Problem: registering two uv_fs_event_t watchers for the same path, then closing
them, caused a segmentation fault. While active, the watchers didn't work right
either, only one would receive events.

Cause: each watcher has a wd (watch descriptor) that's used as its key in a
binary tree. When you call inotify_watch_add() twice with the same path, the
second call doesn't return a new wd - it returns the existing one. That in turn
resulted in the first handle getting ousted from the binary tree, leaving
dangling pointers.

This commit addresses that by storing the watchers in a queue and storing the
queue in the binary tree instead of storing the watchers directly in the tree.

Fixes joyent/node#3789.
2012-07-28 16:31:47 +02:00
Ben Noordhuis
78bc0d6134 unix: implement async handles in libuv
Replace libev backed async handles with a pure libuv implementation.
2012-06-11 04:19:31 +02:00
Ben Noordhuis
c9396dd57e unix: implement timers in libuv
* 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%.
2012-05-31 03:08:34 +02:00
Ben Noordhuis
171ad8567d unix, windows: add uv_walk()
Lets the libuv user iterate over the open handles. Mostly intended as a
debugging tool or a post-hoc cleanup mechanism.
2012-05-30 02:33:39 +02:00
Ben Noordhuis
58a272e556 unix: rework pending handle/req logic 2012-05-30 00:08:22 +02:00
Bert Belder
e4f23aacec Get rid of UV_LEAN_AND_MEAN 2012-05-28 01:53:22 +02:00
Ben Noordhuis
cff2221fbf unix: split up loop.c
Move prepare/check/idle watcher code to loop-watcher.c so it can be reused for
the linux backend.
2012-05-23 23:47:06 +02:00
Ben Noordhuis
3bc9707054 unix: replace ev_io with uv__io_t
Replace ev_io usage with wrapper constructs.

This is preliminary work for the transition to a libev-less linux backend.
2012-05-23 03:42:32 +02:00
Bert Belder
c06edd4c88 windows, unix: share c-ares glue code 2012-05-22 16:11:22 +02:00
Ben Noordhuis
80b554129b unix: reactive new idle watcher implementation
The new idle watcher was temporarily disabled in 073a48d due to some semantic
incompatibilities with the previous implementation. This commit resolves those
issues and reactivates the new implementation.

One outstanding bug is that idle watchers can run in a different order
(relative to other handle types) than the old implementation, e.g. (timer, idle)
instead of the expected (idle, timer). This will be fixed in an upcoming commit.
2012-05-22 15:13:52 +02:00
Ben Noordhuis
073a48d6bf unix: back out new idle watcher for now
Its semantics don't quite match what node.js expects. This breaks the
stdio_over_pipes and shutdown_close_pipe tests but that can't be helped.
2012-05-18 01:19:56 +02:00
Ben Noordhuis
9efa8b3571 unix, windows: rework reference counting scheme
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.
2012-05-17 07:07:53 +02:00