The echo server shouldn't close the connection when there's an error on
write. Instead simply echo the error message and allow the other side to
close the connection.
Also do a partial revert of 4d905fb where after_shutdown was removed.
Fixes: 4d905fb "test: close stream immediately on error"
Signed-off-by: Trevor Norris <trev.norris@gmail.com>
Signed-off-by: Saúl Ibarra Corretgé <saghul@gmail.com>
`fd_set`s are way too small for `select()` hack when stream's fd is
bigger than 1023. Make `fd_set`s a part of `uv__stream_select_t`
structure.
fix#1461
Returns the platform specific file descriptor for handles that are
backed by one. The datatype is abstracted as uv_os_fd_t, which maps to
int on Unices and HANDLE on Windows.
Users can use this function to set specific socket options, for example,
in a non portable way.
This function is essentially a shotgun, you better be careful with
whatever you do with it, don't blame me if you used it to get the fd of
a stream, close it yourself and expect things to Just Work.
If the connect wouldn't go off (no such tcp remote or any other failure),
the subsequent writes made would not be called. Now we call the writes
in the queue with ECANCELED if the connect fails.
Fix#1432
This fixes a SmartOS specific issue that happens when reading from
a stream that is the reading end of a pipe that has been closed by
the parent process.
In this case, a UV__POLLHUP event would be set on the stream and would
prevent the event loop from closing it. As a result, the event loop
would think there are stil handles open, and leave the process
hanging.
Fixes#1419.
Support all possible types on Unix, and files, directories and links on
Windows. Some systems (hello SunOS!) don't have the d_type field on struct
dirent, so mark them as UV_DIRENT_UNKNOWN.
Introduce:
int uv_fs_readdir_next(uv_fs_t* req, uv_dirent_t* ent);
`uv_fs_readdir()` is not returning a file names list in `req->ptr`
anymore, the proper way to gather them is to call `uv_fs_readdir_next()`
in a callback.
As of right now Linux comes with bindv6only=0 by default but BSDs use
bindv6only=1. It can be changed systemwide with sysctl, but it's not
nice to depend on the environment for running tests, so disable it just
on BSDs.
This implements locking around the blocking call to ReadFile to get
around a Windows kernel bug where a blocking ReadFile operation on a
stream can deadlock the thread. This allows uv_read_stop to immediately
cancel a pending IO operation, and allows uv_pipe_getsockname to
"pause" any pending read (from libuv) while it retrieves the
sockname information.
If unsupported by the OS (pre-Vista), this reverts to the old
(e.g. deadlock-prone) behavior
Closes#1313
The unix and windows process implementations diverge in their behavior
when dealing with subprocesses that are spawned with a relative path.
With unix the *child's* PATH environment variable is read, whereas
with windows the *parent's* environment variable is read.
This commit brings the two implementation in line with respect to
their behavior of reading PATH by having both read the *child's* PATH
environment variable. This involves looking into the user-provided
environment on windows and extracting the PATH variable specifically
so it can be inspected later on.
This is the libuv side of the fix for Node's cluster module on Windows.
https://github.com/joyent/node/issues/7691
Windows and Unix return certain socket errors (i.e. EADDRINUSE) at
different times: bind on Windows, and listen on Unix.
In an effort to hide this difference, libuv on Windows stores such
errors in the bind_error field of uv_tcp_t, to defer raising it at
listen time.
This worked fine except for the case in which a socket is shared in
a Node cluster and a bind error occurs.
A previous attempt to fix this (
d1e6be14603da36fe00e
) was flawed becaused in an attempt to relay the error at the JS level
it caused the master to start accepting connections.
With this new approach, libuv itself is relaying the bind errors,
providing for a uniform behavior of uv_tcp_listen.
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.
It's possible that recv_cb_called is bigger than the number of sockets,
because if all sends succeed the recv callback is called twice: once
with the actual data, and another time with 0.
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.
A correct barriers implementation blocks in uv_barrier_destroy() until
the last thread returns from uv_barrier_wait() so make the test more
rigorous by destroying the barrier straight away instead of first
joining the worker thread.
Signed-off-by: Fedor Indutny <fedor@indutny.com>
Make uv_barrier_wait() return a boolean value indicating whether this
thread was the "serializer".
From `man pthread_barrier_wait`:
Upon successful completion, the pthread_barrier_wait() function
shall return PTHREAD_BARRIER_SERIAL_THREAD for a single (arbitrary)
thread synchronized at the barrier and zero for each of the other
threads.
Exposing that information from libuv is useful because it can make
cleanup significantly easier:
if (uv_barrier_wait(&barrier) > 0)
uv_barrier_destroy(&barrier);
Signed-off-by: Fedor Indutny <fedor@indutny.com>
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 there is an error in the uv_read_cb, close the uv_stream_t
immediately instead of waiting until the uv_write_cb, and only close the
stream in after_write() if it hasn't been closed already.