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:
Ben Noordhuis 2011-08-06 01:49:03 +02:00
parent 0c815cfe89
commit 4abd1e0ccc
2 changed files with 23 additions and 28 deletions

View File

@ -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);

View File

@ -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));