On Solaris and derivatives such as SmartOS, the length of socket options
for multicast and ttl options is not always sizeof(char).
This fixes the udp_options and udp_options6 tests.
PR-URL: https://github.com/libuv/libuv/pull/243
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
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>
The contract specifies that the file descriptor should already be in
non-blocking mode before passing it to libuv.
However, node users don't really have an opportunity to do so, never
mind the fact that the call to uv_pipe_open() or uv_tcp_open() is an
implementation detail that most users won't be aware of.
Let's be nice and set the non-blocking flag explicitly. It's a cheap
operation anyway.
Fixes: https://github.com/libuv/libuv/issues/124
PR: https://github.com/libuv/libuv/pull/134
Reviewed-by: Saúl Ibarra Corretgé <saghul@gmail.com>
As pointed out by clang-analyzer.
PR-URL: https://github.com/libuv/libuv/pull/13
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
After 41891222bc landed it's possible that uv__udp_sendmsg is called
even if there are no pending write nor write completed requests:
1. User calls uv_udp_send and the request is sent immediately. The
request is the added to the completed queue and we 'feed' the uv__io
handle so that we process the completed request in the next
iteration.
2. User calls uv_udp_send again but the request is not completed
immediately, so it's queued in the write_queue.
3. The uv__io handle gets a UV__POLLOUT event and uv__udp_sendmsg is
run, which completes the send request and puts it in the
write_completed_queue. Afterwards, uv__udp_run_completed is executed
and the write_completed queue is drained.
4. At this point, the uv__io handle was made pending in step 3, in
uv__udp_sendmsg, but we no longer have requests to write or to complete,
so we skip processing.
This functionality is present in stream and uv_udp_t has a queue
as well so it makes sense for udp to have a send_write_size.
Since udp sends entire messages atomically, the send_queue_count field
lets the user determine how many messages are there left to send.
Only these functions will trigger an implicit binding of a UDP handle:
- uv_udp_send
- uv_udp_recv_start
- uv_udp_set_membership
All other functions will return UV_EBADF in case the socket was not
bound.
Note: currently the socket is created and bound at the same time. This
may change in the future.
If the handle was opened using `uv_udp_open` ift's possible that the
kernel doesn't fill in the msg_name field, so return NULL as the address
in that case.
fixes#1252
Add UV_UDP_REUSEADDR flag instead, which can be passed to uv_udp_bind.
If the udp handle is unbound when uv_udp_set_memberhsip or
uv_udp_set_multicast_interface is called, the handle will be bound with
UV_UDP_REUSEADDR set.
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.
Passing or returning structs as values makes life hard for people that
work with libuv through a foreign function interface. Switch to a
pointer-based approach.
Fixes#684.
Passing or returning structs as values makes life hard for people that
work with libuv through a foreign function interface. Switch to a
pointer-based approach.
Fixes#684.
Passing or returning structs as values makes life hard for people that
work with libuv through a foreign function interface. Switch to a
pointer-based approach.
Fixes#684.
Passing or returning structs as values makes life hard for people that
work with libuv through a foreign function interface. Switch to a
pointer-based approach.
Fixes#684.
On the BSDs, SO_REUSEPORT is pretty much SO_REUSEADDR with some special
casing for IP multicast. When two processes (that don't do multicast)
bind to the same address, only the last one receives traffic. It allows
one to "steal" the bound address from another process. (Both processes
have to enable SO_REUSEPORT though, so it only works in a cooperative
setting.)
On Linux however, it enables port sharing, not stealing - both processes
receive a share of the traffic. This is a desirable trait but pre-3.9
kernels don't support the socket option and a libuv program therefore
behaves differently with older kernels or on another platform.
The difference in behavior (sharing vs. stealing) is, in my opinion,
big enough and confusing enough that it merits a rollback. People
that want this kind of functionality can prepare the socket manually
and hand it off to uv_udp_open().
This commit effectively reverts commit 17452cd.
Linux as of 3.9 has a SO_REUSEPORT option that is similar but not
identical to its BSD counterpart.
On the BSDs, it turns on SO_REUSEADDR _and_ makes it possible to share
the address and port across processes.
On Linux, it "merely" enables fair load distribution - port sharing
still requires that you set SO_REUSEADDR.
Fair distribution is a desirable trait but not an essential one.
We don't know in advance whether the kernel actually supports
SO_REUSEPORT so don't treat EINVAL or ENOPROTOOPT as errors.
As an aside, on the BSDs we now omit the setsockopt(SO_REUSEADDR)
system call because it's implied by SO_REUSEPORT.
Fixes#870.
Make it possible for the libuv user to handle out of memory conditions
gracefully. When alloc_cb() returns a buffer with len==0, call the read
or recv callback with nread=UV_ENOBUFS. It's up to the user to stop or
close the handle.
Fixes#752.
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.
Remove the errno preserving code. Libuv only implemented it in a
haphazard way and there seems to be a general consensus that no one
really cares anyway. Therefore, remove it.
`#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.
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.
Harmonize with stream.c and tcp.c: when a handle is closed that has pending
writes queued up, run the callbacks with loop->err.code set to UV_ECANCELED,
not UV_EINTR.
Some memory was leaked when the uv_udp_t handle was closed when there were
in-flight send requests with a heap allocated buffer list.
That doesn't happen much in practice. In the common case (writing < 5 buffers),
the buffer list is stored inside the uv_udp_send_t structure, not allocated on
the heap.