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__write_callbacks(uv_stream_t* stream);
|
||||
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,
|
||||
@ -453,17 +454,7 @@ void uv__stream_destroy(uv_stream_t* stream) {
|
||||
|
||||
uv__stream_flush_write_queue(stream, UV_ECANCELED);
|
||||
uv__write_callbacks(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;
|
||||
}
|
||||
uv__drain(stream);
|
||||
|
||||
assert(stream->write_queue_size == 0);
|
||||
}
|
||||
@ -668,26 +659,31 @@ static void uv__drain(uv_stream_t* stream) {
|
||||
uv_shutdown_t* req;
|
||||
int err;
|
||||
|
||||
if (!(stream->flags & UV_HANDLE_SHUTTING))
|
||||
return;
|
||||
|
||||
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__stream_osx_interrupt_select(stream);
|
||||
}
|
||||
|
||||
/* Shutdown? */
|
||||
if ((stream->flags & UV_HANDLE_SHUTTING) &&
|
||||
!(stream->flags & UV_HANDLE_CLOSING) &&
|
||||
if ((stream->flags & UV_HANDLE_CLOSING) ||
|
||||
!(stream->flags & UV_HANDLE_SHUT)) {
|
||||
assert(stream->shutdown_req);
|
||||
|
||||
req = stream->shutdown_req;
|
||||
stream->shutdown_req = NULL;
|
||||
stream->flags &= ~UV_HANDLE_SHUTTING;
|
||||
uv__req_unregister(stream->loop, req);
|
||||
|
||||
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);
|
||||
|
||||
if (err == 0)
|
||||
else /* Success. */
|
||||
stream->flags |= UV_HANDLE_SHUT;
|
||||
|
||||
if (req->cb != NULL)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user