aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/transport
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/transport')
-rw-r--r--src/core/transport/metadata.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c
index acd00986f3..e95b7a21f9 100644
--- a/src/core/transport/metadata.c
+++ b/src/core/transport/metadata.c
@@ -87,6 +87,7 @@ typedef struct internal_metadata {
gpr_atm refcnt;
/* private only data */
+ gpr_mu mu_user_data;
void *user_data;
void (*destroy_user_data)(void *user_data);
@@ -200,6 +201,7 @@ static void discard_metadata(grpc_mdctx *ctx) {
if (cur->user_data) {
cur->destroy_user_data(cur->user_data);
}
+ gpr_mu_destroy(&cur->mu_user_data);
gpr_free(cur);
cur = next;
ctx->mdtab_free--;
@@ -467,6 +469,7 @@ grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdctx *ctx,
md->user_data = NULL;
md->destroy_user_data = NULL;
md->bucket_next = ctx->mdtab[hash % ctx->mdtab_capacity];
+ gpr_mu_init(&md->mu_user_data);
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
gpr_log(GPR_DEBUG, "ELM NEW:%p:%d: '%s' = '%s'", md,
gpr_atm_no_barrier_load(&md->refcnt),
@@ -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 (*if_destroy_func)(void *)) {
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 *user_data) {
internal_metadata *im = (internal_metadata *)md;
GPR_ASSERT((user_data == NULL) == (destroy_func == NULL));
+ gpr_mu_lock(&im->mu_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->user_data = user_data;
+ gpr_mu_unlock(&im->mu_user_data);
}
gpr_slice grpc_mdstr_as_base64_encoded_and_huffman_compressed(grpc_mdstr *gs) {