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
|
* 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.
|
* 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);
|
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) {
|
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_async_t* async;
|
||||||
uv_timer_t* timer;
|
uv_timer_t* timer;
|
||||||
|
uv_stream_t* stream;
|
||||||
uv_process_t* process;
|
uv_process_t* process;
|
||||||
|
|
||||||
handle->close_cb = close_cb;
|
handle->close_cb = close_cb;
|
||||||
|
|
||||||
switch (handle->type) {
|
switch (handle->type) {
|
||||||
|
case UV_NAMED_PIPE:
|
||||||
|
uv_pipe_cleanup((uv_pipe_t*)handle);
|
||||||
|
/* Fall through. */
|
||||||
|
|
||||||
case UV_TCP:
|
case UV_TCP:
|
||||||
tcp = (uv_tcp_t*) handle;
|
stream = (uv_stream_t*)handle;
|
||||||
uv_read_stop((uv_stream_t*)tcp);
|
|
||||||
ev_io_stop(EV_DEFAULT_ &tcp->write_watcher);
|
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;
|
break;
|
||||||
|
|
||||||
case UV_PREPARE:
|
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);
|
ev_timer_stop(EV_DEFAULT_ &timer->timer_watcher);
|
||||||
break;
|
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:
|
case UV_PROCESS:
|
||||||
process = (uv_process_t*)handle;
|
process = (uv_process_t*)handle;
|
||||||
ev_child_stop(EV_DEFAULT_UC_ &process->child_watcher);
|
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_NAMED_PIPE:
|
||||||
case UV_TCP:
|
case UV_TCP:
|
||||||
{
|
assert(!ev_is_active(&((uv_stream_t*)handle)->read_watcher));
|
||||||
uv_stream_t* stream;
|
assert(!ev_is_active(&((uv_stream_t*)handle)->write_watcher));
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case UV_PROCESS:
|
case UV_PROCESS:
|
||||||
assert(!ev_is_active(&((uv_process_t*)handle)->child_watcher));
|
assert(!ev_is_active(&((uv_process_t*)handle)->child_watcher));
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user