aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Mark D. Roth <roth@google.com>2016-11-03 07:58:25 -0700
committerGravatar Mark D. Roth <roth@google.com>2016-11-03 07:58:25 -0700
commit896d92568b1b615a19dec26035596de244cbf535 (patch)
treee31678532ba5fdb10bddff66e6ee62deb7008920 /src
parente528993d972396003459a7750db2158cd5a696a7 (diff)
Add grpc_json_tree to handle refcounting for channel arg.
Diffstat (limited to 'src')
-rw-r--r--src/core/ext/client_channel/client_channel.c8
-rw-r--r--src/core/lib/channel/message_size_filter.c5
-rw-r--r--src/core/lib/json/json.c59
-rw-r--r--src/core/lib/json/json.h19
-rw-r--r--src/core/lib/transport/method_config.c23
-rw-r--r--src/core/lib/transport/method_config.h2
6 files changed, 111 insertions, 5 deletions
diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c
index e569af68e9..4a1c0ae1a2 100644
--- a/src/core/ext/client_channel/client_channel.c
+++ b/src/core/ext/client_channel/client_channel.c
@@ -104,7 +104,8 @@ static void *method_config_convert_value(const grpc_json *json) {
if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) {
return NULL;
}
- wait_for_ready = field->type == GRPC_JSON_TRUE;
+ wait_for_ready = field->type == GRPC_JSON_TRUE
+ ? WAIT_FOR_READY_TRUE : WAIT_FOR_READY_FALSE;
} else if (strcmp(field->key, "timeout") == 0) {
if (timeout.tv_sec > 0 || timeout.tv_nsec > 0) return NULL; // Duplicate.
if (field->type != GRPC_JSON_OBJECT) return NULL;
@@ -312,9 +313,10 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg,
grpc_channel_args_find(lb_policy_args.args, GRPC_ARG_SERVICE_CONFIG);
if (channel_arg != NULL) {
GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER);
+ grpc_json_tree* json_tree = channel_arg->value.pointer.p;
method_params_table = grpc_method_config_table_create_from_json(
- (grpc_json *)channel_arg->value.pointer.p,
- method_config_convert_value, &method_parameters_vtable);
+ json_tree->root, method_config_convert_value,
+ &method_parameters_vtable);
}
grpc_channel_args_destroy(chand->resolver_result);
chand->resolver_result = NULL;
diff --git a/src/core/lib/channel/message_size_filter.c b/src/core/lib/channel/message_size_filter.c
index 4723ab8098..86fdf72684 100644
--- a/src/core/lib/channel/message_size_filter.c
+++ b/src/core/lib/channel/message_size_filter.c
@@ -234,9 +234,10 @@ static void init_channel_elem(grpc_exec_ctx* exec_ctx,
grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG);
if (channel_arg != NULL) {
GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER);
+ grpc_json_tree* json_tree = channel_arg->value.pointer.p;
chand->method_limit_table = grpc_method_config_table_create_from_json(
- (grpc_json*)channel_arg->value.pointer.p,
- method_config_convert_value, &message_size_limits_vtable);
+ json_tree->root, method_config_convert_value,
+ &message_size_limits_vtable);
}
}
diff --git a/src/core/lib/json/json.c b/src/core/lib/json/json.c
index 5b583a1f2e..c1a99df6c3 100644
--- a/src/core/lib/json/json.c
+++ b/src/core/lib/json/json.c
@@ -34,6 +34,8 @@
#include <string.h>
#include <grpc/support/alloc.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/sync.h>
#include "src/core/lib/json/json.h"
@@ -62,3 +64,60 @@ void grpc_json_destroy(grpc_json *json) {
gpr_free(json);
}
+
+int grpc_json_cmp(const grpc_json* json1, const grpc_json* json2) {
+ if (json1 == NULL) {
+ if (json2 != NULL) return 1;
+ return 0; // Both NULL.
+ } else {
+ if (json2 == NULL) return -1;
+ }
+ // Compare type.
+ if (json1->type > json2->type) return 1;
+ if (json1->type < json2->type) return -1;
+ // Compare key.
+ if (json1->key == NULL) {
+ if (json2->key != NULL) return -1;
+ } else {
+ if (json2->key == NULL) return 1;
+ int retval = strcmp(json1->key, json2->key);
+ if (retval != 0) return retval;
+ }
+ // Compare value.
+ if (json1->value == NULL) {
+ if (json2->value != NULL) return -1;
+ } else {
+ if (json2->value == NULL) return 1;
+ int retval = strcmp(json1->value, json2->value);
+ if (retval != 0) return retval;
+ }
+ // Recursively compare the next pointer.
+ int retval = grpc_json_cmp(json1->next, json2->next);
+ if (retval != 0) return retval;
+ // Recursively compare the child pointer.
+ retval = grpc_json_cmp(json1->child, json2->child);
+ if (retval != 0) return retval;
+ // Both are the same.
+ return 0;
+}
+
+grpc_json_tree* grpc_json_tree_create(const char* json_string) {
+ grpc_json_tree* tree = gpr_malloc(sizeof(*tree));
+ tree->string = gpr_strdup(json_string);
+ tree->root = grpc_json_parse_string(tree->string);
+ gpr_ref_init(&tree->refs, 1);
+ return tree;
+}
+
+grpc_json_tree* grpc_json_tree_ref(grpc_json_tree* tree) {
+ gpr_ref(&tree->refs);
+ return tree;
+}
+
+void grpc_json_tree_unref(grpc_json_tree* tree) {
+ if (gpr_unref(&tree->refs)) {
+ grpc_json_destroy(tree->root);
+ gpr_free(tree->string);
+ gpr_free(tree);
+ }
+}
diff --git a/src/core/lib/json/json.h b/src/core/lib/json/json.h
index 681df4bb77..e18ace7547 100644
--- a/src/core/lib/json/json.h
+++ b/src/core/lib/json/json.h
@@ -36,6 +36,8 @@
#include <stdlib.h>
+#include <grpc/support/sync.h>
+
#include "src/core/lib/json/json_common.h"
/* A tree-like structure to hold json values. The key and value pointers
@@ -85,4 +87,21 @@ char *grpc_json_dump_to_string(grpc_json *json, int indent);
grpc_json *grpc_json_create(grpc_json_type type);
void grpc_json_destroy(grpc_json *json);
+/* Compares two JSON trees. */
+int grpc_json_cmp(const grpc_json* json1, const grpc_json* json2);
+
+/* A wrapper that contains the string used for underlying allocation and
+ is refcounted. */
+typedef struct {
+ grpc_json* root;
+ char* string;
+ gpr_refcount refs;
+} grpc_json_tree;
+
+/* Creates a copy of \a json_string. */
+grpc_json_tree* grpc_json_tree_create(const char* json_string);
+
+grpc_json_tree* grpc_json_tree_ref(grpc_json_tree* tree);
+void grpc_json_tree_unref(grpc_json_tree* tree);
+
#endif /* GRPC_CORE_LIB_JSON_JSON_H */
diff --git a/src/core/lib/transport/method_config.c b/src/core/lib/transport/method_config.c
index 23cab2b96b..c2bf88a250 100644
--- a/src/core/lib/transport/method_config.c
+++ b/src/core/lib/transport/method_config.c
@@ -460,3 +460,26 @@ grpc_mdstr_hash_table* grpc_method_config_table_create_from_json(
}
return method_config_table;
}
+
+static void* copy_json_tree(void* t) { return grpc_json_tree_ref(t); }
+
+static void destroy_json_tree(void* t) { grpc_json_tree_unref(t); }
+
+static int cmp_json_tree(void* t1, void* t2) {
+ grpc_json_tree* tree1 = t1;
+ grpc_json_tree* tree2 = t2;
+ return grpc_json_cmp(tree1->root, tree2->root);
+}
+
+static grpc_arg_pointer_vtable service_config_arg_vtable = {
+ copy_json_tree, destroy_json_tree, cmp_json_tree};
+
+grpc_arg grpc_service_config_create_channel_arg(
+ grpc_json_tree* service_config) {
+ grpc_arg arg;
+ arg.type = GRPC_ARG_POINTER;
+ arg.key = GRPC_ARG_SERVICE_CONFIG;
+ arg.value.pointer.p = service_config;
+ arg.value.pointer.vtable = &service_config_arg_vtable;
+ return arg;
+}
diff --git a/src/core/lib/transport/method_config.h b/src/core/lib/transport/method_config.h
index eac05f8173..84c6329415 100644
--- a/src/core/lib/transport/method_config.h
+++ b/src/core/lib/transport/method_config.h
@@ -140,4 +140,6 @@ grpc_mdstr_hash_table* grpc_method_config_table_create_from_json(
void* (*create_value)(const grpc_json* method_config_json),
const grpc_mdstr_hash_table_vtable* vtable);
+grpc_arg grpc_service_config_create_channel_arg(grpc_json_tree* service_config);
+
#endif /* GRPC_CORE_LIB_TRANSPORT_METHOD_CONFIG_H */