From 71bf1be2013c78a3a7a6ae0eb80d01455e1d70b0 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Thu, 9 Jul 2015 14:51:24 -0700
Subject: [PATCH] Fix race in TCP connection

If the TCP client connection alarm triggers close to the connection
deadline (but succeeds), the alarm shuts down the endpoint underneath
the existing transport... which is very bad for its health.
---
 src/core/iomgr/tcp_client_posix.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/core/iomgr/tcp_client_posix.c b/src/core/iomgr/tcp_client_posix.c
index d981aaf028..2c6ff4e9c4 100644
--- a/src/core/iomgr/tcp_client_posix.c
+++ b/src/core/iomgr/tcp_client_posix.c
@@ -114,6 +114,7 @@ static void on_writable(void *acp, int success) {
   void (*cb)(void *arg, grpc_endpoint *tcp) = ac->cb;
   void *cb_arg = ac->cb_arg;
 
+  gpr_mu_lock(&ac->mu);
   if (success) {
     do {
       so_error_size = sizeof(so_error);
@@ -139,6 +140,7 @@ static void on_writable(void *acp, int success) {
            opened too many network connections.  The "easy" fix:
            don't do that! */
         gpr_log(GPR_ERROR, "kernel out of buffers");
+        gpr_mu_unlock(&ac->mu);
         grpc_fd_notify_on_write(ac->fd, &ac->write_closure);
         return;
       } else {
@@ -165,10 +167,11 @@ static void on_writable(void *acp, int success) {
   abort();
 
 finish:
-  gpr_mu_lock(&ac->mu);
-  if (!ep) {
+  if (ep == NULL) {
     grpc_pollset_set_del_fd(ac->interested_parties, ac->fd);
     grpc_fd_orphan(ac->fd, NULL, "tcp_client_orphan");
+  } else {
+    ac->fd = NULL;
   }
   done = (--ac->refs == 0);
   gpr_mu_unlock(&ac->mu);
-- 
GitLab