From b8e82670ce244434e7570fc4b0459628bd6beee1 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Sat, 10 Oct 2015 13:52:47 -0700 Subject: Fix race conditions --- src/core/transport/metadata.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/core') diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c index 1b48b48e09..68f23177eb 100644 --- a/src/core/transport/metadata.c +++ b/src/core/transport/metadata.c @@ -160,12 +160,10 @@ static void ref_md_locked(internal_metadata *md DEBUG_ARGS) { grpc_mdstr_as_c_string((grpc_mdstr *)md->key), grpc_mdstr_as_c_string((grpc_mdstr *)md->value)); #endif - if (0 == gpr_atm_no_barrier_fetch_add(&md->refcnt, 1)) { - /* This ref is dropped if grpc_mdelem_unref reaches 1, - but allows us to safely unref without taking the mdctx lock - until such time */ - gpr_atm_no_barrier_fetch_add(&md->refcnt, 1); + if (0 == gpr_atm_no_barrier_fetch_add(&md->refcnt, 2)) { md->context->mdtab_free--; + } else { + GPR_ASSERT(1 != gpr_atm_no_barrier_fetch_add(&md->refcnt, -1)); } } @@ -537,7 +535,7 @@ grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *gmd DEBUG_ARGS) { this function - meaning that no adjustment to mdtab_free is necessary, simplifying the logic here to be just an atomic increment */ /* use C assert to have this removed in opt builds */ - assert(gpr_atm_no_barrier_load(&md->refcnt) >= 1); + assert(gpr_atm_no_barrier_load(&md->refcnt) >= 2); gpr_atm_no_barrier_fetch_add(&md->refcnt, 1); return gmd; } @@ -555,8 +553,10 @@ void grpc_mdelem_unref(grpc_mdelem *gmd DEBUG_ARGS) { if (2 == gpr_atm_full_fetch_add(&md->refcnt, -1)) { grpc_mdctx *ctx = md->context; lock(ctx); - GPR_ASSERT(1 == gpr_atm_full_fetch_add(&md->refcnt, -1)); - ctx->mdtab_free++; + if (1 == gpr_atm_no_barrier_load(&md->refcnt)) { + ctx->mdtab_free++; + gpr_atm_no_barrier_store(&md->refcnt, 0); + } unlock(ctx); } } -- cgit v1.2.3