aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2016-11-14 14:35:02 -0800
committerGravatar Craig Tiller <ctiller@google.com>2016-11-14 14:35:02 -0800
commit68208fe422cee7e28f7a08208c528a08338a9c2b (patch)
tree2008acd78a9359d2266d1e0ea163879ea62c77ee /src/core
parent4eecdde403b852e523a004707c1045b5e6072cdc (diff)
Progress towards mdstr elimination
Diffstat (limited to 'src/core')
-rw-r--r--src/core/lib/compression/algorithm_metadata.h4
-rw-r--r--src/core/lib/compression/compression.c4
-rw-r--r--src/core/lib/slice/slice_string_helpers.h3
-rw-r--r--src/core/lib/surface/call.c122
-rw-r--r--src/core/lib/surface/call_details.c6
-rw-r--r--src/core/lib/surface/call_log_batch.c19
-rw-r--r--src/core/lib/surface/channel.c62
-rw-r--r--src/core/lib/surface/channel.h5
-rw-r--r--src/core/lib/surface/lame_client.c9
-rw-r--r--src/core/lib/surface/server.c93
-rw-r--r--src/core/lib/transport/metadata.h4
11 files changed, 156 insertions, 175 deletions
diff --git a/src/core/lib/compression/algorithm_metadata.h b/src/core/lib/compression/algorithm_metadata.h
index 7412054bfe..bc4963059c 100644
--- a/src/core/lib/compression/algorithm_metadata.h
+++ b/src/core/lib/compression/algorithm_metadata.h
@@ -38,7 +38,7 @@
#include "src/core/lib/transport/metadata.h"
/** Return compression algorithm based metadata value */
-grpc_slice grpc_compression_algorithm_mdstr(
+grpc_slice grpc_compression_algorithm_slice(
grpc_compression_algorithm algorithm);
/** Return compression algorithm based metadata element (grpc-encoding: xxx) */
@@ -47,7 +47,7 @@ grpc_mdelem *grpc_compression_encoding_mdelem(
/** Find compression algorithm based on passed in mdstr - returns
* GRPC_COMPRESS_ALGORITHM_COUNT on failure */
-grpc_compression_algorithm grpc_compression_algorithm_from_mdstr(
+grpc_compression_algorithm grpc_compression_algorithm_from_slice(
grpc_slice str);
#endif /* GRPC_CORE_LIB_COMPRESSION_ALGORITHM_METADATA_H */
diff --git a/src/core/lib/compression/compression.c b/src/core/lib/compression/compression.c
index aa3caf9fef..d73353f392 100644
--- a/src/core/lib/compression/compression.c
+++ b/src/core/lib/compression/compression.c
@@ -81,7 +81,7 @@ int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm,
return 0;
}
-grpc_compression_algorithm grpc_compression_algorithm_from_mdstr(
+grpc_compression_algorithm grpc_compression_algorithm_from_slice(
grpc_slice str) {
if (grpc_slice_cmp(str, GRPC_MDSTR_IDENTITY) == 0) return GRPC_COMPRESS_NONE;
if (grpc_slice_cmp(str, GRPC_MDSTR_DEFLATE) == 0)
@@ -90,7 +90,7 @@ grpc_compression_algorithm grpc_compression_algorithm_from_mdstr(
return GRPC_COMPRESS_ALGORITHMS_COUNT;
}
-grpc_slice grpc_compression_algorithm_mdstr(
+grpc_slice grpc_compression_algorithm_slice(
grpc_compression_algorithm algorithm) {
switch (algorithm) {
case GRPC_COMPRESS_NONE:
diff --git a/src/core/lib/slice/slice_string_helpers.h b/src/core/lib/slice/slice_string_helpers.h
index c6f4e87c7f..4a4deec6e5 100644
--- a/src/core/lib/slice/slice_string_helpers.h
+++ b/src/core/lib/slice/slice_string_helpers.h
@@ -34,6 +34,7 @@
#ifndef GRPC_CORE_LIB_SLICE_SLICE_STRING_HELPERS_H
#define GRPC_CORE_LIB_SLICE_SLICE_STRING_HELPERS_H
+#include <stdbool.h>
#include <stddef.h>
#include <grpc/slice.h>
@@ -53,6 +54,8 @@ char *grpc_dump_slice(grpc_slice slice, uint32_t flags);
* should be a properly initialized instance. */
void grpc_slice_split(grpc_slice str, const char *sep, grpc_slice_buffer *dst);
+bool grpc_parse_slice_to_uint32(grpc_slice str, uint32_t *result);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c
index 525f7b663a..37548697fa 100644
--- a/src/core/lib/surface/call.c
+++ b/src/core/lib/surface/call.c
@@ -196,8 +196,7 @@ struct grpc_call {
union {
struct {
grpc_status_code *status;
- char **status_details;
- size_t *status_details_capacity;
+ grpc_slice *status_details;
} client;
struct {
int *cancelled;
@@ -383,7 +382,7 @@ static void get_final_status(grpc_call *call,
void *set_value_user_data) {
int i;
for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
- if (call->status[i].is_set) {
+ if (call->status[i].is_code_set) {
set_value(call->status[i].code, set_value_user_data);
return;
}
@@ -411,8 +410,8 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
}
gpr_mu_destroy(&c->mu);
for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
- if (c->status[i].details) {
- GRPC_MDSTR_UNREF(exec_ctx, c->status[i].details);
+ if (c->status[i].is_details_set) {
+ grpc_slice_unref_internal(exec_ctx, c->status[i].details);
}
}
for (ii = 0; ii < c->send_extra_metadata_count; ii++) {
@@ -438,18 +437,19 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
static void set_status_code(grpc_call *call, status_source source,
uint32_t status) {
- if (call->status[source].is_set) return;
+ if (call->status[source].is_code_set) return;
- call->status[source].is_set = 1;
+ call->status[source].is_code_set = true;
call->status[source].code = (grpc_status_code)status;
}
static void set_status_details(grpc_exec_ctx *exec_ctx, grpc_call *call,
status_source source, grpc_slice status) {
- if (call->status[source].details != NULL) {
- GRPC_MDSTR_UNREF(exec_ctx, status);
+ if (call->status[source].is_details_set) {
+ grpc_slice_unref_internal(exec_ctx, status);
} else {
call->status[source].details = status;
+ call->status[source].is_details_set = true;
}
}
@@ -459,7 +459,8 @@ static void set_status_from_error(grpc_exec_ctx *exec_ctx, grpc_call *call,
const char *msg;
grpc_error_get_status(error, &status, &msg);
set_status_code(call, source, (uint32_t)status);
- set_status_details(exec_ctx, call, source, grpc_mdstr_from_string(msg));
+ set_status_details(exec_ctx, call, source,
+ grpc_slice_from_copied_string(msg));
}
static void set_incoming_compression_algorithm(
@@ -509,7 +510,7 @@ static void set_encodings_accepted_by_peer(grpc_exec_ctx *exec_ctx,
return;
}
- accept_encoding_slice = mdel->value->slice;
+ accept_encoding_slice = mdel->value;
grpc_slice_buffer_init(&accept_encoding_parts);
grpc_slice_split(accept_encoding_slice, ",", &accept_encoding_parts);
@@ -518,15 +519,13 @@ static void set_encodings_accepted_by_peer(grpc_exec_ctx *exec_ctx,
/* Always support no compression */
GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_COMPRESS_NONE);
for (i = 0; i < accept_encoding_parts.count; i++) {
- const grpc_slice *accept_encoding_entry_slice =
- &accept_encoding_parts.slices[i];
- if (grpc_compression_algorithm_parse(
- (const char *)GRPC_SLICE_START_PTR(*accept_encoding_entry_slice),
- GRPC_SLICE_LENGTH(*accept_encoding_entry_slice), &algorithm)) {
+ grpc_slice accept_encoding_entry_slice = accept_encoding_parts.slices[i];
+ if (grpc_compression_algorithm_parse(accept_encoding_entry_slice,
+ &algorithm)) {
GPR_BITSET(&call->encodings_accepted_by_peer, algorithm);
} else {
char *accept_encoding_entry_str =
- grpc_dump_slice(*accept_encoding_entry_slice, GPR_DUMP_ASCII);
+ grpc_dump_slice(accept_encoding_entry_slice, GPR_DUMP_ASCII);
gpr_log(GPR_ERROR,
"Invalid entry in accept encoding metadata: '%s'. Ignoring.",
accept_encoding_entry_str);
@@ -549,21 +548,12 @@ uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call) {
return encodings_accepted_by_peer;
}
-static void get_final_details(grpc_call *call, char **out_details,
- size_t *out_details_capacity) {
+static void get_final_details(grpc_call *call, grpc_slice *out_details) {
int i;
for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
- if (call->status[i].is_set) {
- if (call->status[i].details) {
- grpc_slice details = call->status[i].details->slice;
- size_t len = GRPC_SLICE_LENGTH(details);
- if (len + 1 > *out_details_capacity) {
- *out_details_capacity =
- GPR_MAX(len + 1, *out_details_capacity * 3 / 2);
- *out_details = gpr_realloc(*out_details, *out_details_capacity);
- }
- memcpy(*out_details, GRPC_SLICE_START_PTR(details), len);
- (*out_details)[len] = 0;
+ if (call->status[i].is_code_set) {
+ if (call->status[i].is_details_set) {
+ *out_details = grpc_slice_ref(call->status[i].details);
} else {
goto no_details;
}
@@ -572,11 +562,7 @@ static void get_final_details(grpc_call *call, char **out_details,
}
no_details:
- if (0 == *out_details_capacity) {
- *out_details_capacity = 8;
- *out_details = gpr_malloc(*out_details_capacity);
- }
- **out_details = 0;
+ *out_details = grpc_empty_slice();
}
static grpc_linked_mdelem *linked_from_md(grpc_metadata *md) {
@@ -605,19 +591,17 @@ static int prepare_application_metadata(
get_md_elem(metadata, additional_metadata, i, count);
grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data;
GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data));
- l->md = grpc_mdelem_from_string_and_buffer(
- exec_ctx, md->key, (const uint8_t *)md->value, md->value_length);
- if (!grpc_header_key_is_legal(grpc_mdstr_as_c_string(l->md->key),
- GRPC_MDSTR_LENGTH(l->md->key))) {
- gpr_log(GPR_ERROR, "attempt to send invalid metadata key: %s",
- grpc_mdstr_as_c_string(l->md->key));
+ l->md = grpc_mdelem_from_slices(exec_ctx, md->key, md->value);
+ if (!grpc_header_key_slice_is_legal(l->md->key)) {
+ char *str = grpc_dump_slice(md->key, GPR_DUMP_ASCII);
+ gpr_log(GPR_ERROR, "attempt to send invalid metadata key: %s", str);
+ gpr_free(str);
break;
- } else if (!grpc_is_binary_header(grpc_mdstr_as_c_string(l->md->key),
- GRPC_MDSTR_LENGTH(l->md->key)) &&
- !grpc_header_nonbin_value_is_legal(
- grpc_mdstr_as_c_string(l->md->value),
- GRPC_MDSTR_LENGTH(l->md->value))) {
- gpr_log(GPR_ERROR, "attempt to send invalid metadata value");
+ } else if (!grpc_slice_is_binary_header(l->md->key) &&
+ !grpc_header_nonbin_value_slice_is_legal(l->md->value)) {
+ char *str = grpc_dump_slice(md->value, GPR_DUMP_HEX | GPR_DUMP_ASCII);
+ gpr_log(GPR_ERROR, "attempt to send invalid metadata value: %s", str);
+ gpr_free(str);
break;
}
}
@@ -902,9 +886,7 @@ static uint32_t decode_status(grpc_mdelem *md) {
if (user_data != NULL) {
status = ((uint32_t)(intptr_t)user_data) - STATUS_OFFSET;
} else {
- if (!gpr_parse_bytes_to_uint32(grpc_mdstr_as_c_string(md->value),
- GRPC_SLICE_LENGTH(md->value->slice),
- &status)) {
+ if (!grpc_parse_slice_to_uint32(md->value, &status)) {
status = GRPC_STATUS_UNKNOWN; /* could not parse status code */
}
grpc_mdelem_set_user_data(md, destroy_status,
@@ -915,13 +897,14 @@ static uint32_t decode_status(grpc_mdelem *md) {
static grpc_compression_algorithm decode_compression(grpc_mdelem *md) {
grpc_compression_algorithm algorithm =
- grpc_compression_algorithm_from_mdstr(md->value);
+ grpc_compression_algorithm_from_slice(md->value);
if (algorithm == GRPC_COMPRESS_ALGORITHMS_COUNT) {
- const char *md_c_str = grpc_mdstr_as_c_string(md->value);
+ char *md_c_str = grpc_dump_slice(md->value, GPR_DUMP_ASCII);
gpr_log(GPR_ERROR,
"Invalid incoming compression algorithm: '%s'. Interpreting "
"incoming data as uncompressed.",
md_c_str);
+ gpr_free(md_c_str);
return GRPC_COMPRESS_NONE;
}
return algorithm;
@@ -929,15 +912,15 @@ static grpc_compression_algorithm decode_compression(grpc_mdelem *md) {
static grpc_mdelem *recv_common_filter(grpc_exec_ctx *exec_ctx, grpc_call *call,
grpc_mdelem *elem) {
- if (elem->key == GRPC_MDSTR_GRPC_STATUS) {
+ if (grpc_slice_cmp(elem->key, GRPC_MDSTR_GRPC_STATUS) == 0) {
GPR_TIMER_BEGIN("status", 0);
set_status_code(call, STATUS_FROM_WIRE, decode_status(elem));
GPR_TIMER_END("status", 0);
return NULL;
- } else if (elem->key == GRPC_MDSTR_GRPC_MESSAGE) {
+ } else if (grpc_slice_cmp(elem->key, GRPC_MDSTR_GRPC_MESSAGE) == 0) {
GPR_TIMER_BEGIN("status-details", 0);
set_status_details(exec_ctx, call, STATUS_FROM_WIRE,
- GRPC_MDSTR_REF(elem->value));
+ grpc_slice_ref_internal(elem->value));
GPR_TIMER_END("status-details", 0);
return NULL;
}
@@ -956,9 +939,8 @@ static grpc_mdelem *publish_app_metadata(grpc_call *call, grpc_mdelem *elem,
gpr_realloc(dest->metadata, sizeof(grpc_metadata) * dest->capacity);
}
mdusr = &dest->metadata[dest->count++];
- mdusr->key = grpc_mdstr_as_c_string(elem->key);
- mdusr->value = grpc_mdstr_as_c_string(elem->value);
- mdusr->value_length = GRPC_SLICE_LENGTH(elem->value->slice);
+ mdusr->key = grpc_slice_ref(elem->key);
+ mdusr->value = grpc_slice_ref(elem->value);
GPR_TIMER_END("publish_app_metadata", 0);
return elem;
}
@@ -973,12 +955,12 @@ static grpc_mdelem *recv_initial_filter(void *args, grpc_mdelem *elem) {
elem = recv_common_filter(a->exec_ctx, a->call, elem);
if (elem == NULL) {
return NULL;
- } else if (elem->key == GRPC_MDSTR_GRPC_ENCODING) {
+ } else if (grpc_slice_cmp(elem->key, GRPC_MDSTR_GRPC_ENCODING) == 0) {
GPR_TIMER_BEGIN("incoming_compression_algorithm", 0);
set_incoming_compression_algorithm(a->call, decode_compression(elem));
GPR_TIMER_END("incoming_compression_algorithm", 0);
return NULL;
- } else if (elem->key == GRPC_MDSTR_GRPC_ACCEPT_ENCODING) {
+ } else if (grpc_slice_cmp(elem->key, GRPC_MDSTR_GRPC_ACCEPT_ENCODING) == 0) {
GPR_TIMER_BEGIN("encodings_accepted_by_peer", 0);
set_encodings_accepted_by_peer(a->exec_ctx, a->call, elem);
GPR_TIMER_END("encodings_accepted_by_peer", 0);
@@ -1328,8 +1310,7 @@ static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp,
if (call->is_client) {
get_final_status(call, set_status_value_directly,
call->final_op.client.status);
- get_final_details(call, call->final_op.client.status_details,
- call->final_op.client.status_details_capacity);
+ get_final_details(call, call->final_op.client.status_details);
} else {
get_final_status(call, set_cancelled_value,
call->final_op.server.cancelled);
@@ -1427,13 +1408,10 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
const grpc_compression_algorithm calgo =
compression_algorithm_for_level_locked(
call, effective_compression_level);
- char *calgo_name = NULL;
- grpc_compression_algorithm_name(calgo, &calgo_name);
// the following will be picked up by the compress filter and used as
// the call's compression algorithm.
- compression_md.key = GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY;
- compression_md.value = calgo_name;
- compression_md.value_length = strlen(calgo_name);
+ compression_md.key = GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST;
+ compression_md.value = grpc_compression_algorithm_slice(calgo);
additional_metadata_count++;
}
@@ -1527,14 +1505,14 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
call->send_extra_metadata[0].md = grpc_channel_get_reffed_status_elem(
exec_ctx, call->channel, op->data.send_status_from_server.status);
if (op->data.send_status_from_server.status_details != NULL) {
- call->send_extra_metadata[1].md = grpc_mdelem_from_metadata_strings(
+ call->send_extra_metadata[1].md = grpc_mdelem_from_slices(
exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
- grpc_mdstr_from_string(
- op->data.send_status_from_server.status_details));
+ grpc_slice_ref_internal(
+ *op->data.send_status_from_server.status_details));
call->send_extra_metadata_count++;
set_status_details(
exec_ctx, call, STATUS_FROM_API_OVERRIDE,
- GRPC_MDSTR_REF(call->send_extra_metadata[1].md->value));
+ grpc_slice_ref_internal(call->send_extra_metadata[1].md->value));
}
if (op->data.send_status_from_server.status != GRPC_STATUS_OK) {
set_status_code(call, STATUS_FROM_API_OVERRIDE,
@@ -1611,8 +1589,6 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
call->final_op.client.status = op->data.recv_status_on_client.status;
call->final_op.client.status_details =
op->data.recv_status_on_client.status_details;
- call->final_op.client.status_details_capacity =
- op->data.recv_status_on_client.status_details_capacity;
bctl->recv_final_op = 1;
stream_op->recv_trailing_metadata =
&call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
diff --git a/src/core/lib/surface/call_details.c b/src/core/lib/surface/call_details.c
index fe73da3f55..5efa3b0141 100644
--- a/src/core/lib/surface/call_details.c
+++ b/src/core/lib/surface/call_details.c
@@ -41,10 +41,12 @@
void grpc_call_details_init(grpc_call_details* cd) {
GRPC_API_TRACE("grpc_call_details_init(cd=%p)", 1, (cd));
memset(cd, 0, sizeof(*cd));
+ cd->method = grpc_empty_slice();
+ cd->host = grpc_empty_slice();
}
void grpc_call_details_destroy(grpc_call_details* cd) {
GRPC_API_TRACE("grpc_call_details_destroy(cd=%p)", 1, (cd));
- gpr_free(cd->method);
- gpr_free(cd->host);
+ grpc_slice_unref(cd->method);
+ grpc_slice_unref(cd->host);
}
diff --git a/src/core/lib/surface/call_log_batch.c b/src/core/lib/surface/call_log_batch.c
index 31c074f15d..8f6438bc3b 100644
--- a/src/core/lib/surface/call_log_batch.c
+++ b/src/core/lib/surface/call_log_batch.c
@@ -35,17 +35,18 @@
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
+#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
static void add_metadata(gpr_strvec *b, const grpc_metadata *md, size_t count) {
size_t i;
for (i = 0; i < count; i++) {
gpr_strvec_add(b, gpr_strdup("\nkey="));
- gpr_strvec_add(b, gpr_strdup(md[i].key));
+ gpr_strvec_add(b, grpc_dump_slice(md[i].key, GPR_DUMP_ASCII));
gpr_strvec_add(b, gpr_strdup(" value="));
- gpr_strvec_add(b, gpr_dump(md[i].value, md[i].value_length,
- GPR_DUMP_HEX | GPR_DUMP_ASCII));
+ gpr_strvec_add(b,
+ grpc_dump_slice(md[i].value, GPR_DUMP_HEX | GPR_DUMP_ASCII));
}
}
@@ -70,10 +71,16 @@ char *grpc_op_string(const grpc_op *op) {
gpr_strvec_add(&b, gpr_strdup("SEND_CLOSE_FROM_CLIENT"));
break;
case GRPC_OP_SEND_STATUS_FROM_SERVER:
- gpr_asprintf(&tmp, "SEND_STATUS_FROM_SERVER status=%d details=%s",
- op->data.send_status_from_server.status,
- op->data.send_status_from_server.status_details);
+ gpr_asprintf(&tmp, "SEND_STATUS_FROM_SERVER status=%d details=",
+ op->data.send_status_from_server.status);
gpr_strvec_add(&b, tmp);
+ if (op->data.send_status_from_server.status_details != NULL) {
+ gpr_strvec_add(&b, grpc_dump_slice(
+ *op->data.send_status_from_server.status_details,
+ GPR_DUMP_ASCII));
+ } else {
+ gpr_strvec_add(&b, gpr_strdup("(null)"));
+ }
add_metadata(&b, op->data.send_status_from_server.trailing_metadata,
op->data.send_status_from_server.trailing_metadata_count);
break;
diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c
index 7e87f05531..986142a692 100644
--- a/src/core/lib/surface/channel.c
+++ b/src/core/lib/surface/channel.c
@@ -123,8 +123,9 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
/* setting this takes precedence over anything else */
GRPC_MDELEM_UNREF(exec_ctx, channel->default_authority);
}
- channel->default_authority = grpc_mdelem_from_strings(
- exec_ctx, ":authority", args->args[i].value.string);
+ channel->default_authority = grpc_mdelem_from_slices(
+ exec_ctx, GRPC_MDSTR_AUTHORITY,
+ grpc_slice_from_copied_string(args->args[i].value.string));
}
} else if (0 ==
strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) {
@@ -138,8 +139,9 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
"%s ignored: default host already set some other way",
GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
} else {
- channel->default_authority = grpc_mdelem_from_strings(
- exec_ctx, ":authority", args->args[i].value.string);
+ channel->default_authority = grpc_mdelem_from_slices(
+ exec_ctx, GRPC_MDSTR_AUTHORITY,
+ grpc_slice_from_copied_string(args->args[i].value.string));
}
}
} else if (0 == strcmp(args->args[i].key,
@@ -224,27 +226,17 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel,
grpc_call *parent_call,
uint32_t propagation_mask,
grpc_completion_queue *cq,
- const char *method, const char *host,
+ grpc_slice method, const grpc_slice *host,
gpr_timespec deadline, void *reserved) {
- GRPC_API_TRACE(
- "grpc_channel_create_call("
- "channel=%p, parent_call=%p, propagation_mask=%x, cq=%p, method=%s, "
- "host=%s, "
- "deadline=gpr_timespec { tv_sec: %" PRId64
- ", tv_nsec: %d, clock_type: %d }, "
- "reserved=%p)",
- 10,
- (channel, parent_call, (unsigned)propagation_mask, cq, method, host,
- deadline.tv_sec, deadline.tv_nsec, (int)deadline.clock_type, reserved));
GPR_ASSERT(!reserved);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_call *call = grpc_channel_create_call_internal(
&exec_ctx, channel, parent_call, propagation_mask, cq, NULL,
- grpc_mdelem_from_metadata_strings(&exec_ctx, GRPC_MDSTR_PATH,
- grpc_mdstr_from_string(method)),
- host ? grpc_mdelem_from_metadata_strings(&exec_ctx, GRPC_MDSTR_AUTHORITY,
- grpc_mdstr_from_string(host))
- : NULL,
+ grpc_mdelem_from_slices(&exec_ctx, GRPC_MDSTR_PATH,
+ grpc_slice_ref(method)),
+ host != NULL ? grpc_mdelem_from_slices(&exec_ctx, GRPC_MDSTR_AUTHORITY,
+ grpc_slice_ref(*host))
+ : NULL,
deadline);
grpc_exec_ctx_finish(&exec_ctx);
return call;
@@ -252,17 +244,16 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel,
grpc_call *grpc_channel_create_pollset_set_call(
grpc_exec_ctx *exec_ctx, grpc_channel *channel, grpc_call *parent_call,
- uint32_t propagation_mask, grpc_pollset_set *pollset_set,
- const char *method, const char *host, gpr_timespec deadline,
- void *reserved) {
+ uint32_t propagation_mask, grpc_pollset_set *pollset_set, grpc_slice method,
+ const grpc_slice *host, gpr_timespec deadline, void *reserved) {
GPR_ASSERT(!reserved);
return grpc_channel_create_call_internal(
exec_ctx, channel, parent_call, propagation_mask, NULL, pollset_set,
- grpc_mdelem_from_metadata_strings(exec_ctx, GRPC_MDSTR_PATH,
- grpc_mdstr_from_string(method)),
- host ? grpc_mdelem_from_metadata_strings(exec_ctx, GRPC_MDSTR_AUTHORITY,
- grpc_mdstr_from_string(host))
- : NULL,
+ grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_PATH,
+ grpc_slice_ref(method)),
+ host != NULL ? grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_AUTHORITY,
+ grpc_slice_ref(*host))
+ : NULL,
deadline);
}
@@ -274,11 +265,14 @@ void *grpc_channel_register_call(grpc_channel *channel, const char *method,
4, (channel, method, host, reserved));
GPR_ASSERT(!reserved);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- rc->path = grpc_mdelem_from_metadata_strings(&exec_ctx, GRPC_MDSTR_PATH,
- grpc_mdstr_from_string(method));
+
+ rc->path = grpc_mdelem_from_slices(
+ &exec_ctx, GRPC_MDSTR_PATH,
+ grpc_slice_intern(grpc_slice_from_copied_string(method)));
rc->authority =
- host ? grpc_mdelem_from_metadata_strings(&exec_ctx, GRPC_MDSTR_AUTHORITY,
- grpc_mdstr_from_string(host))
+ host ? grpc_mdelem_from_slices(
+ &exec_ctx, GRPC_MDSTR_AUTHORITY,
+ grpc_slice_intern(grpc_slice_from_copied_string(host)))
: NULL;
gpr_mu_lock(&channel->registered_call_mu);
rc->next = channel->registered_calls;
@@ -385,6 +379,6 @@ grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_exec_ctx *exec_ctx,
return GRPC_MDELEM_GRPC_STATUS_2;
}
gpr_ltoa(i, tmp);
- return grpc_mdelem_from_metadata_strings(exec_ctx, GRPC_MDSTR_GRPC_STATUS,
- grpc_mdstr_from_string(tmp));
+ return grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_STATUS,
+ grpc_slice_from_copied_string(tmp));
}
diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h
index 2ebadb7a15..cbe48cd6a0 100644
--- a/src/core/lib/surface/channel.h
+++ b/src/core/lib/surface/channel.h
@@ -52,9 +52,8 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
value of \a propagation_mask (see propagation_bits.h for possible values) */
grpc_call *grpc_channel_create_pollset_set_call(
grpc_exec_ctx *exec_ctx, grpc_channel *channel, grpc_call *parent_call,
- uint32_t propagation_mask, grpc_pollset_set *pollset_set,
- const char *method, const char *host, gpr_timespec deadline,
- void *reserved);
+ uint32_t propagation_mask, grpc_pollset_set *pollset_set, grpc_slice method,
+ const grpc_slice *host, gpr_timespec deadline, void *reserved);
/** Get a (borrowed) pointer to this channels underlying channel stack */
grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel);
diff --git a/src/core/lib/surface/lame_client.c b/src/core/lib/surface/lame_client.c
index d606f70c2f..a43969be57 100644
--- a/src/core/lib/surface/lame_client.c
+++ b/src/core/lib/surface/lame_client.c
@@ -44,6 +44,7 @@
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/call.h"
#include "src/core/lib/surface/channel.h"
+#include "src/core/lib/transport/static_metadata.h"
typedef struct {
grpc_linked_mdelem status;
@@ -61,9 +62,11 @@ static void fill_metadata(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
channel_data *chand = elem->channel_data;
char tmp[GPR_LTOA_MIN_BUFSIZE];
gpr_ltoa(chand->error_code, tmp);
- calld->status.md = grpc_mdelem_from_strings(exec_ctx, "grpc-status", tmp);
- calld->details.md =
- grpc_mdelem_from_strings(exec_ctx, "grpc-message", chand->error_message);
+ calld->status.md = grpc_mdelem_from_slices(
+ exec_ctx, GRPC_MDSTR_GRPC_STATUS, grpc_slice_from_copied_string(tmp));
+ calld->details.md = grpc_mdelem_from_slices(
+ exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
+ grpc_slice_from_copied_string(chand->error_message));
calld->status.prev = calld->details.next = NULL;
calld->status.next = &calld->details;
calld->details.prev = &calld->status;
diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c
index 8f0cfbbc17..74411f3aab 100644
--- a/src/core/lib/surface/server.c
+++ b/src/core/lib/surface/server.c
@@ -98,6 +98,7 @@ typedef struct requested_call {
typedef struct channel_registered_method {
registered_method *server_registered_method;
uint32_t flags;
+ bool has_host;
grpc_slice method;
grpc_slice host;
} channel_registered_method;
@@ -144,6 +145,8 @@ struct call_data {
/** the current state of a call - see call_state */
call_state state;
+ bool path_set;
+ bool host_set;
grpc_slice path;
grpc_slice host;
gpr_timespec deadline;
@@ -459,17 +462,6 @@ static void destroy_channel(grpc_exec_ctx *exec_ctx, channel_data *chand,
op);
}
-static void cpstr(char **dest, size_t *capacity, grpc_slice value) {
- grpc_slice slice = value->slice;
- size_t len = GRPC_SLICE_LENGTH(slice);
-
- if (len + 1 > *capacity) {
- *capacity = GPR_MAX(len + 1, *capacity * 2);
- *dest = gpr_realloc(*dest, *capacity);
- }
- memcpy(*dest, grpc_mdstr_as_c_string(value), len + 1);
-}
-
static void done_request_event(grpc_exec_ctx *exec_ctx, void *req,
grpc_cq_completion *c) {
requested_call *rc = req;
@@ -498,12 +490,10 @@ static void publish_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, calld->initial_metadata);
switch (rc->type) {
case BATCH_CALL:
- GPR_ASSERT(calld->host != NULL);
- GPR_ASSERT(calld->path != NULL);
- cpstr(&rc->data.batch.details->host,
- &rc->data.batch.details->host_capacity, calld->host);
- cpstr(&rc->data.batch.details->method,
- &rc->data.batch.details->method_capacity, calld->path);
+ GPR_ASSERT(calld->host_set);
+ GPR_ASSERT(calld->path_set);
+ rc->data.batch.details->host = grpc_slice_ref_internal(calld->host);
+ rc->data.batch.details->method = grpc_slice_ref_internal(calld->path);
rc->data.batch.details->deadline = calld->deadline;
rc->data.batch.details->flags =
(calld->recv_idempotent_request
@@ -623,35 +613,39 @@ static void start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
uint32_t hash;
channel_registered_method *rm;
- if (chand->registered_methods && calld->path && calld->host) {
+ if (chand->registered_methods && calld->path_set && calld->host_set) {
/* TODO(ctiller): unify these two searches */
/* check for an exact match with host */
- hash = GRPC_MDSTR_KV_HASH(calld->host->hash, calld->path->hash);
+ hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(calld->host),
+ grpc_slice_hash(calld->path));
for (i = 0; i <= chand->registered_method_max_probes; i++) {
rm = &chand->registered_methods[(hash + i) %
chand->registered_method_slots];
if (!rm) break;
- if (rm->host != calld->host) continue;
- if (rm->method != calld->path) continue;
+ if (!rm->has_host) continue;
+ if (grpc_slice_cmp(rm->host, calld->host) != 0) continue;
+ if (grpc_slice_cmp(rm->method, calld->path) != 0) continue;
if ((rm->flags & GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) &&
- !calld->recv_idempotent_request)
+ !calld->recv_idempotent_request) {
continue;
+ }
finish_start_new_rpc(exec_ctx, server, elem,
&rm->server_registered_method->request_matcher,
rm->server_registered_method->payload_handling);
return;
}
/* check for a wildcard method definition (no host set) */
- hash = GRPC_MDSTR_KV_HASH(0, calld->path->hash);
+ hash = GRPC_MDSTR_KV_HASH(0, grpc_slice_hash(calld->path));
for (i = 0; i <= chand->registered_method_max_probes; i++) {
rm = &chand->registered_methods[(hash + i) %
chand->registered_method_slots];
if (!rm) break;
- if (rm->host != NULL) continue;
- if (rm->method != calld->path) continue;
+ if (rm->has_host) continue;
+ if (grpc_slice_cmp(rm->method, calld->path) != 0) continue;
if ((rm->flags & GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) &&
- !calld->recv_idempotent_request)
+ !calld->recv_idempotent_request) {
continue;
+ }
finish_start_new_rpc(exec_ctx, server, elem,
&rm->server_registered_method->request_matcher,
rm->server_registered_method->payload_handling);
@@ -743,14 +737,14 @@ static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx,
static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
- if (md->key == GRPC_MDSTR_PATH) {
- if (calld->path == NULL) {
- calld->path = GRPC_MDSTR_REF(md->value);
+ if (grpc_slice_cmp(md->key, GRPC_MDSTR_PATH) == 0) {
+ if (!calld->path_set) {
+ calld->path = grpc_slice_ref(md->value);
}
return NULL;
- } else if (md->key == GRPC_MDSTR_AUTHORITY) {
- if (calld->host == NULL) {
- calld->host = GRPC_MDSTR_REF(md->value);
+ } else if (grpc_slice_cmp(md->key, GRPC_MDSTR_AUTHORITY) == 0) {
+ if (!calld->host_set) {
+ calld->host = grpc_slice_ref(md->value);
}
return NULL;
}
@@ -770,7 +764,7 @@ static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
if (0 != gpr_time_cmp(op_deadline, gpr_inf_future(op_deadline.clock_type))) {
calld->deadline = op_deadline;
}
- if (calld->host && calld->path) {
+ if (calld->host_set && calld->path_set) {
/* do nothing */
} else {
GRPC_ERROR_UNREF(error);
@@ -902,11 +896,11 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
GPR_ASSERT(calld->state != PENDING);
- if (calld->host) {
- GRPC_MDSTR_UNREF(exec_ctx, calld->host);
+ if (calld->host_set) {
+ grpc_slice_unref_internal(exec_ctx, calld->host);
}
- if (calld->path) {
- GRPC_MDSTR_UNREF(exec_ctx, calld->path);
+ if (calld->path_set) {
+ grpc_slice_unref_internal(exec_ctx, calld->path);
}
grpc_metadata_array_destroy(&calld->initial_metadata);
@@ -936,11 +930,9 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
channel_data *chand = elem->channel_data;
if (chand->registered_methods) {
for (i = 0; i < chand->registered_method_slots; i++) {
- if (chand->registered_methods[i].method) {
- GRPC_MDSTR_UNREF(exec_ctx, chand->registered_methods[i].method);
- }
- if (chand->registered_methods[i].host) {
- GRPC_MDSTR_UNREF(exec_ctx, chand->registered_methods[i].host);
+ grpc_slice_unref_internal(exec_ctx, chand->registered_methods[i].method);
+ if (chand->registered_methods[i].has_host) {
+ grpc_slice_unref_internal(exec_ctx, chand->registered_methods[i].host);
}
}
gpr_free(chand->registered_methods);
@@ -1136,8 +1128,6 @@ void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
channel_registered_method *crm;
grpc_channel *channel;
channel_data *chand;
- grpc_slice host;
- grpc_slice method;
uint32_t hash;
size_t slots;
uint32_t probes;
@@ -1176,9 +1166,18 @@ void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
chand->registered_methods = gpr_malloc(alloc);
memset(chand->registered_methods, 0, alloc);
for (rm = s->registered_methods; rm; rm = rm->next) {
- host = rm->host ? grpc_mdstr_from_string(rm->host) : NULL;
- method = grpc_mdstr_from_string(rm->method);
- hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash);
+ grpc_slice host;
+ bool has_host;
+ grpc_slice method;
+ if (rm->host != NULL) {
+ host = grpc_slice_intern(grpc_slice_from_copied_string(rm->host));
+ has_host = true;
+ } else {
+ has_host = false;
+ }
+ method = grpc_slice_intern(grpc_slice_from_copied_string(rm->method));
+ hash = GRPC_MDSTR_KV_HASH(has_host ? grpc_slice_hash(host) : 0,
+ grpc_slice_hash(method));
for (probes = 0; chand->registered_methods[(hash + probes) % slots]
.server_registered_method != NULL;
probes++)
diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h
index ede09d7d76..fcd1c9222f 100644
--- a/src/core/lib/transport/metadata.h
+++ b/src/core/lib/transport/metadata.h
@@ -113,11 +113,9 @@ grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *md);
void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem *md);
#endif
-#define GRPC_MDSTR_LENGTH(s) (GRPC_SLICE_LENGTH(s->slice))
-
/* We add 32 bytes of padding as per RFC-7540 section 6.5.2. */
#define GRPC_MDELEM_LENGTH(e) \
- (GRPC_MDSTR_LENGTH((e)->key) + GRPC_MDSTR_LENGTH((e)->value) + 32)
+ (GRPC_SLICE_LENGTH((e)->key) + GRPC_SLICE_LENGTH((e)->value) + 32)
#define GRPC_MDSTR_KV_HASH(k_hash, v_hash) (GPR_ROTL((k_hash), 2) ^ (v_hash))