Fix race conditions

pull/3794/head
Craig Tiller 9 years ago
parent 8344daa1df
commit b8e82670ce
  1. 14
      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));
if (1 == gpr_atm_no_barrier_load(&md->refcnt)) {
ctx->mdtab_free++;
gpr_atm_no_barrier_store(&md->refcnt, 0);
}
unlock(ctx);
}
}

Loading…
Cancel
Save