shutdown,unix: reduce code duplication (#3648)
The UV_ECANCELED codepath had an incorrect comment, and the implementation was generally less robust (for example, not checking if `cb` was NULL), so we can merge these codepaths for cleaner code.
This commit is contained in:
parent
2108309302
commit
1a91b51976
@ -66,6 +66,7 @@ static void uv__read(uv_stream_t* stream);
|
|||||||
static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
||||||
static void uv__write_callbacks(uv_stream_t* stream);
|
static void uv__write_callbacks(uv_stream_t* stream);
|
||||||
static size_t uv__write_req_size(uv_write_t* req);
|
static size_t uv__write_req_size(uv_write_t* req);
|
||||||
|
static void uv__drain(uv_stream_t* stream);
|
||||||
|
|
||||||
|
|
||||||
void uv__stream_init(uv_loop_t* loop,
|
void uv__stream_init(uv_loop_t* loop,
|
||||||
@ -453,17 +454,7 @@ void uv__stream_destroy(uv_stream_t* stream) {
|
|||||||
|
|
||||||
uv__stream_flush_write_queue(stream, UV_ECANCELED);
|
uv__stream_flush_write_queue(stream, UV_ECANCELED);
|
||||||
uv__write_callbacks(stream);
|
uv__write_callbacks(stream);
|
||||||
|
uv__drain(stream);
|
||||||
if (stream->shutdown_req) {
|
|
||||||
/* The ECANCELED error code is a lie, the shutdown(2) syscall is a
|
|
||||||
* fait accompli at this point. Maybe we should revisit this in v0.11.
|
|
||||||
* A possible reason for leaving it unchanged is that it informs the
|
|
||||||
* callee that the handle has been destroyed.
|
|
||||||
*/
|
|
||||||
uv__req_unregister(stream->loop, stream->shutdown_req);
|
|
||||||
stream->shutdown_req->cb(stream->shutdown_req, UV_ECANCELED);
|
|
||||||
stream->shutdown_req = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(stream->write_queue_size == 0);
|
assert(stream->write_queue_size == 0);
|
||||||
}
|
}
|
||||||
@ -668,26 +659,31 @@ static void uv__drain(uv_stream_t* stream) {
|
|||||||
uv_shutdown_t* req;
|
uv_shutdown_t* req;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
if (!(stream->flags & UV_HANDLE_SHUTTING))
|
||||||
|
return;
|
||||||
|
|
||||||
assert(QUEUE_EMPTY(&stream->write_queue));
|
assert(QUEUE_EMPTY(&stream->write_queue));
|
||||||
|
req = stream->shutdown_req;
|
||||||
|
assert(req);
|
||||||
|
|
||||||
|
if (!(stream->flags & UV_HANDLE_CLOSING)) {
|
||||||
uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT);
|
uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT);
|
||||||
uv__stream_osx_interrupt_select(stream);
|
uv__stream_osx_interrupt_select(stream);
|
||||||
|
}
|
||||||
|
|
||||||
/* Shutdown? */
|
if ((stream->flags & UV_HANDLE_CLOSING) ||
|
||||||
if ((stream->flags & UV_HANDLE_SHUTTING) &&
|
|
||||||
!(stream->flags & UV_HANDLE_CLOSING) &&
|
|
||||||
!(stream->flags & UV_HANDLE_SHUT)) {
|
!(stream->flags & UV_HANDLE_SHUT)) {
|
||||||
assert(stream->shutdown_req);
|
|
||||||
|
|
||||||
req = stream->shutdown_req;
|
|
||||||
stream->shutdown_req = NULL;
|
stream->shutdown_req = NULL;
|
||||||
stream->flags &= ~UV_HANDLE_SHUTTING;
|
stream->flags &= ~UV_HANDLE_SHUTTING;
|
||||||
uv__req_unregister(stream->loop, req);
|
uv__req_unregister(stream->loop, req);
|
||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
if (shutdown(uv__stream_fd(stream), SHUT_WR))
|
if (stream->flags & UV_HANDLE_CLOSING)
|
||||||
|
/* The user destroyed the stream before we got to do the shutdown. */
|
||||||
|
err = UV_ECANCELED;
|
||||||
|
else if (shutdown(uv__stream_fd(stream), SHUT_WR))
|
||||||
err = UV__ERR(errno);
|
err = UV__ERR(errno);
|
||||||
|
else /* Success. */
|
||||||
if (err == 0)
|
|
||||||
stream->flags |= UV_HANDLE_SHUT;
|
stream->flags |= UV_HANDLE_SHUT;
|
||||||
|
|
||||||
if (req->cb != NULL)
|
if (req->cb != NULL)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user