From 6ba80f94ed0dbcc537aa7f90d95aff14fea57e79 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 27 Jan 2017 11:58:32 -0800 Subject: [PATCH] Update TCP Windows --- src/core/lib/iomgr/tcp_windows.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/core/lib/iomgr/tcp_windows.c b/src/core/lib/iomgr/tcp_windows.c index 84f791ba07a..26fd746ff6c 100644 --- a/src/core/lib/iomgr/tcp_windows.c +++ b/src/core/lib/iomgr/tcp_windows.c @@ -116,6 +116,7 @@ typedef struct grpc_tcp { to protect ourselves when requesting a shutdown. */ gpr_mu mu; int shutting_down; + grpc_error *shutdown_error; char *peer_string; } grpc_tcp; @@ -125,6 +126,7 @@ static void tcp_free(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) { gpr_mu_destroy(&tcp->mu); gpr_free(tcp->peer_string); grpc_resource_user_unref(exec_ctx, tcp->resource_user); + if (tcp->shutting_down) GRPC_ERROR_UNREF(tcp->shutdown_error); gpr_free(tcp); } @@ -182,7 +184,7 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *tcpp, grpc_error *error) { grpc_slice_buffer_add(tcp->read_slices, sub); } else { grpc_slice_unref_internal(exec_ctx, tcp->read_slice); - error = GRPC_ERROR_CREATE("End of TCP stream"); + error = tcp->shutting_down ? GRPC_ERROR_CREATE_REFERENCING("TCP stream shutting down", &tcp->shutdown_error, 1) : GRPC_ERROR_CREATE("End of TCP stream"); } } } @@ -204,7 +206,7 @@ static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, if (tcp->shutting_down) { grpc_closure_sched(exec_ctx, cb, - GRPC_ERROR_CREATE("TCP socket is shutting down")); + GRPC_ERROR_CREATE_REFERENCING("TCP socket is shutting down", &tcp->shutdown_error, 1)); return; } @@ -292,7 +294,7 @@ static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, if (tcp->shutting_down) { grpc_closure_sched(exec_ctx, cb, - GRPC_ERROR_CREATE("TCP socket is shutting down")); + GRPC_ERROR_CREATE_REFERENCING("TCP socket is shutting down", &tcp->shutdown_error, 1)); return; } @@ -373,12 +375,18 @@ static void win_add_to_pollset_set(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, we're not going to protect against these. However the IO Completion Port callback will happen from another thread, so we need to protect against concurrent access of the data structure in that regard. */ -static void win_shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) { +static void win_shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, grpc_error *why) { grpc_tcp *tcp = (grpc_tcp *)ep; gpr_mu_lock(&tcp->mu); /* At that point, what may happen is that we're already inside the IOCP callback. See the comments in on_read and on_write. */ - tcp->shutting_down = 1; + if (!tcp->shutting_down) { + tcp->shutting_down = 1; + tcp->shutdown_error = why; + } + else { + GRPC_ERROR_UNREF(why); + } grpc_winsocket_shutdown(tcp->socket); gpr_mu_unlock(&tcp->mu); grpc_resource_user_shutdown(exec_ctx, tcp->resource_user);