uv-unix: close file descriptors immediately in uv_close()
Don't defer closing of socket and pipe file descriptors to the next iteration of the event loop. It breaks node.js unit tests that assume the call to `server.close()` immediately frees up the bound to address.
This commit is contained in:
parent
0c815cfe89
commit
4abd1e0ccc
@ -228,6 +228,10 @@ int uv_is_active(uv_handle_t* handle);
|
||||
/*
|
||||
* Request handle to be closed. close_cb will be called asynchronously after
|
||||
* this call. This MUST be called on each handle before memory is released.
|
||||
*
|
||||
* Note that handles that wrap file descriptors are closed immediately but
|
||||
* close_cb will still be deferred to the next iteration of the event loop.
|
||||
* It gives you a chance to free up any resources associated with the handle.
|
||||
*/
|
||||
void uv_close(uv_handle_t* handle, uv_close_cb close_cb);
|
||||
|
||||
|
||||
@ -199,19 +199,31 @@ static uv_err_t uv_err_new(uv_handle_t* handle, int sys_error) {
|
||||
|
||||
|
||||
void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
|
||||
uv_tcp_t* tcp;
|
||||
uv_pipe_t* pipe;
|
||||
uv_async_t* async;
|
||||
uv_timer_t* timer;
|
||||
uv_stream_t* stream;
|
||||
uv_process_t* process;
|
||||
|
||||
handle->close_cb = close_cb;
|
||||
|
||||
switch (handle->type) {
|
||||
case UV_NAMED_PIPE:
|
||||
uv_pipe_cleanup((uv_pipe_t*)handle);
|
||||
/* Fall through. */
|
||||
|
||||
case UV_TCP:
|
||||
tcp = (uv_tcp_t*) handle;
|
||||
uv_read_stop((uv_stream_t*)tcp);
|
||||
ev_io_stop(EV_DEFAULT_ &tcp->write_watcher);
|
||||
stream = (uv_stream_t*)handle;
|
||||
|
||||
uv_read_stop(stream);
|
||||
ev_io_stop(EV_DEFAULT_ &stream->write_watcher);
|
||||
|
||||
uv__close(stream->fd);
|
||||
stream->fd = -1;
|
||||
|
||||
if (stream->accepted_fd >= 0) {
|
||||
uv__close(stream->accepted_fd);
|
||||
stream->accepted_fd = -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case UV_PREPARE:
|
||||
@ -240,13 +252,6 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
|
||||
ev_timer_stop(EV_DEFAULT_ &timer->timer_watcher);
|
||||
break;
|
||||
|
||||
case UV_NAMED_PIPE:
|
||||
pipe = (uv_pipe_t*)handle;
|
||||
uv_pipe_cleanup(pipe);
|
||||
uv_read_stop((uv_stream_t*)handle);
|
||||
ev_io_stop(EV_DEFAULT_ &pipe->write_watcher);
|
||||
break;
|
||||
|
||||
case UV_PROCESS:
|
||||
process = (uv_process_t*)handle;
|
||||
ev_child_stop(EV_DEFAULT_UC_ &process->child_watcher);
|
||||
@ -574,23 +579,9 @@ void uv__finish_close(uv_handle_t* handle) {
|
||||
|
||||
case UV_NAMED_PIPE:
|
||||
case UV_TCP:
|
||||
{
|
||||
uv_stream_t* stream;
|
||||
|
||||
stream = (uv_stream_t*)handle;
|
||||
|
||||
assert(!ev_is_active(&stream->read_watcher));
|
||||
assert(!ev_is_active(&stream->write_watcher));
|
||||
|
||||
uv__close(stream->fd);
|
||||
stream->fd = -1;
|
||||
|
||||
if (stream->accepted_fd >= 0) {
|
||||
uv__close(stream->accepted_fd);
|
||||
stream->accepted_fd = -1;
|
||||
}
|
||||
assert(!ev_is_active(&((uv_stream_t*)handle)->read_watcher));
|
||||
assert(!ev_is_active(&((uv_stream_t*)handle)->write_watcher));
|
||||
break;
|
||||
}
|
||||
|
||||
case UV_PROCESS:
|
||||
assert(!ev_is_active(&((uv_process_t*)handle)->child_watcher));
|
||||
|
||||
Loading…
Reference in New Issue
Block a user