From 4ce09cf760db8771f9c9b222d6f06df61c058ff7 Mon Sep 17 00:00:00 2001
From: vjpai <vpai@google.com>
Date: Fri, 18 Mar 2016 23:09:15 -0700
Subject: [PATCH] Reorder a release store after the operations it protects.

---
 src/core/iomgr/fd_posix.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/core/iomgr/fd_posix.c b/src/core/iomgr/fd_posix.c
index 4ba7c5df94..3edafa0b07 100644
--- a/src/core/iomgr/fd_posix.c
+++ b/src/core/iomgr/fd_posix.c
@@ -72,6 +72,9 @@ static grpc_fd *fd_freelist = NULL;
 static gpr_mu fd_freelist_mu;
 
 static void freelist_fd(grpc_fd *fd) {
+  // Note that this function must be called after a release store (or
+  // full-barrier operation) on refst so that prior actions on the fd are
+  // ordered before the fd becomes visible to the freelist
   gpr_mu_lock(&fd_freelist_mu);
   fd->freelist_next = fd_freelist;
   fd_freelist = fd;
@@ -92,7 +95,6 @@ static grpc_fd *alloc_fd(int fd) {
     gpr_mu_init(&r->mu);
   }
 
-  gpr_atm_rel_store(&r->refst, 1);
   r->shutdown = 0;
   r->read_closure = CLOSURE_NOT_READY;
   r->write_closure = CLOSURE_NOT_READY;
@@ -104,6 +106,11 @@ static grpc_fd *alloc_fd(int fd) {
   r->on_done_closure = NULL;
   r->closed = 0;
   r->released = 0;
+  // The last operation on r before returning it should be a release-store
+  // so that all the above fields are globally visible before the value of
+  // r could escape to another thread. Our refcount itself needs a release-store
+  // so use this
+  gpr_atm_rel_store(&r->refst, 1);
   return r;
 }
 
-- 
GitLab