aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar vjpai <vpai@google.com>2016-03-18 23:09:15 -0700
committerGravatar vjpai <vpai@google.com>2016-03-18 23:09:15 -0700
commit4ce09cf760db8771f9c9b222d6f06df61c058ff7 (patch)
tree8c8b60d6669a5ae10efd3ff3889e057f8f45d385 /src
parentcb1c389a6c98d72e59fe10e07f4c15156abf62a1 (diff)
Reorder a release store after the operations it protects.
Diffstat (limited to 'src')
-rw-r--r--src/core/iomgr/fd_posix.c9
1 files changed, 8 insertions, 1 deletions
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;
}