Skip to content
Snippets Groups Projects
Commit 83901534 authored by Craig Tiller's avatar Craig Tiller
Browse files

Fix TSAN reported race

parent 8819ac75
No related branches found
No related tags found
No related merge requests found
...@@ -87,6 +87,7 @@ typedef struct internal_metadata { ...@@ -87,6 +87,7 @@ typedef struct internal_metadata {
gpr_atm refcnt; gpr_atm refcnt;
/* private only data */ /* private only data */
gpr_mu mu_user_data;
void *user_data; void *user_data;
void (*destroy_user_data)(void *user_data); void (*destroy_user_data)(void *user_data);
...@@ -200,6 +201,7 @@ static void discard_metadata(grpc_mdctx *ctx) { ...@@ -200,6 +201,7 @@ static void discard_metadata(grpc_mdctx *ctx) {
if (cur->user_data) { if (cur->user_data) {
cur->destroy_user_data(cur->user_data); cur->destroy_user_data(cur->user_data);
} }
gpr_mu_destroy(&cur->mu_user_data);
gpr_free(cur); gpr_free(cur);
cur = next; cur = next;
ctx->mdtab_free--; ctx->mdtab_free--;
...@@ -467,6 +469,7 @@ grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdctx *ctx, ...@@ -467,6 +469,7 @@ grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdctx *ctx,
md->user_data = NULL; md->user_data = NULL;
md->destroy_user_data = NULL; md->destroy_user_data = NULL;
md->bucket_next = ctx->mdtab[hash % ctx->mdtab_capacity]; md->bucket_next = ctx->mdtab[hash % ctx->mdtab_capacity];
gpr_mu_init(&md->mu_user_data);
#ifdef GRPC_METADATA_REFCOUNT_DEBUG #ifdef GRPC_METADATA_REFCOUNT_DEBUG
gpr_log(GPR_DEBUG, "ELM NEW:%p:%d: '%s' = '%s'", md, gpr_log(GPR_DEBUG, "ELM NEW:%p:%d: '%s' = '%s'", md,
gpr_atm_no_barrier_load(&md->refcnt), gpr_atm_no_barrier_load(&md->refcnt),
...@@ -581,18 +584,29 @@ size_t grpc_mdctx_get_mdtab_free_test_only(grpc_mdctx *ctx) { ...@@ -581,18 +584,29 @@ size_t grpc_mdctx_get_mdtab_free_test_only(grpc_mdctx *ctx) {
void *grpc_mdelem_get_user_data(grpc_mdelem *md, void *grpc_mdelem_get_user_data(grpc_mdelem *md,
void (*if_destroy_func)(void *)) { void (*if_destroy_func)(void *)) {
internal_metadata *im = (internal_metadata *)md; internal_metadata *im = (internal_metadata *)md;
return im->destroy_user_data == if_destroy_func ? im->user_data : NULL; void *result;
gpr_mu_lock(&im->mu_user_data);
result = im->destroy_user_data == if_destroy_func ? im->user_data : NULL;
gpr_mu_unlock(&im->mu_user_data);
return result;
} }
void grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *), void grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *),
void *user_data) { void *user_data) {
internal_metadata *im = (internal_metadata *)md; internal_metadata *im = (internal_metadata *)md;
GPR_ASSERT((user_data == NULL) == (destroy_func == NULL)); GPR_ASSERT((user_data == NULL) == (destroy_func == NULL));
gpr_mu_lock(&im->mu_user_data);
if (im->destroy_user_data) { if (im->destroy_user_data) {
im->destroy_user_data(im->user_data); /* user data can only be set once */
gpr_mu_unlock(&im->mu_user_data);
if (destroy_func != NULL) {
destroy_func(user_data);
}
return;
} }
im->destroy_user_data = destroy_func; im->destroy_user_data = destroy_func;
im->user_data = user_data; im->user_data = user_data;
gpr_mu_unlock(&im->mu_user_data);
} }
gpr_slice grpc_mdstr_as_base64_encoded_and_huffman_compressed(grpc_mdstr *gs) { gpr_slice grpc_mdstr_as_base64_encoded_and_huffman_compressed(grpc_mdstr *gs) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment