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

Pre allocate client side strings per channel for method, scheme, path, and

authority.

For method and scheme, move these from channel to http_client_filter.
	Change on 2014/12/19 by klempner <klempner@google.com>
-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=82536909
parent 186cdab8
No related branches found
No related tags found
No related merge requests found
...@@ -34,11 +34,14 @@ ...@@ -34,11 +34,14 @@
#include "src/core/channel/http_client_filter.h" #include "src/core/channel/http_client_filter.h"
#include <grpc/support/log.h> #include <grpc/support/log.h>
typedef struct call_data { typedef struct call_data { int sent_headers; } call_data;
int unused; /* C89 requires at least one struct element */
} call_data;
typedef struct channel_data { grpc_mdelem *te_trailers; } channel_data; typedef struct channel_data {
grpc_mdelem *te_trailers;
grpc_mdelem *method;
grpc_mdelem *scheme;
grpc_mdelem *content_type;
} channel_data;
/* used to silence 'variable not used' warnings */ /* used to silence 'variable not used' warnings */
static void ignore_unused(void *ignored) {} static void ignore_unused(void *ignored) {}
...@@ -58,9 +61,26 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem, ...@@ -58,9 +61,26 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
ignore_unused(calld); ignore_unused(calld);
switch (op->type) { switch (op->type) {
case GRPC_SEND_METADATA:
if (!calld->sent_headers) {
/* Send : prefixed headers, which have to be before any application
* layer headers. */
calld->sent_headers = 1;
grpc_call_element_send_metadata(elem, channeld->method);
grpc_call_element_send_metadata(elem, channeld->scheme);
}
grpc_call_next_op(elem, op);
break;
case GRPC_SEND_START: case GRPC_SEND_START:
/* just prior to starting, add a te: trailers header */ if (!calld->sent_headers) {
/* Send : prefixed headers, if we haven't already */
calld->sent_headers = 1;
grpc_call_element_send_metadata(elem, channeld->method);
grpc_call_element_send_metadata(elem, channeld->scheme);
}
/* Send non : prefixed headers */
grpc_call_element_send_metadata(elem, channeld->te_trailers); grpc_call_element_send_metadata(elem, channeld->te_trailers);
grpc_call_element_send_metadata(elem, channeld->content_type);
grpc_call_next_op(elem, op); grpc_call_next_op(elem, op);
break; break;
default: default:
...@@ -97,7 +117,7 @@ static void init_call_elem(grpc_call_element *elem, ...@@ -97,7 +117,7 @@ static void init_call_elem(grpc_call_element *elem,
ignore_unused(channeld); ignore_unused(channeld);
/* initialize members */ /* initialize members */
calld->unused = 0; calld->sent_headers = 0;
} }
/* Destructor for call_data */ /* Destructor for call_data */
...@@ -125,6 +145,10 @@ static void init_channel_elem(grpc_channel_element *elem, ...@@ -125,6 +145,10 @@ static void init_channel_elem(grpc_channel_element *elem,
/* initialize members */ /* initialize members */
channeld->te_trailers = grpc_mdelem_from_strings(mdctx, "te", "trailers"); channeld->te_trailers = grpc_mdelem_from_strings(mdctx, "te", "trailers");
channeld->method = grpc_mdelem_from_strings(mdctx, ":method", "POST");
channeld->scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "grpc");
channeld->content_type =
grpc_mdelem_from_strings(mdctx, "content-type", "application/grpc");
} }
/* Destructor for channel data */ /* Destructor for channel data */
...@@ -133,6 +157,9 @@ static void destroy_channel_elem(grpc_channel_element *elem) { ...@@ -133,6 +157,9 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
channel_data *channeld = elem->channel_data; channel_data *channeld = elem->channel_data;
grpc_mdelem_unref(channeld->te_trailers); grpc_mdelem_unref(channeld->te_trailers);
grpc_mdelem_unref(channeld->method);
grpc_mdelem_unref(channeld->scheme);
grpc_mdelem_unref(channeld->content_type);
} }
const grpc_channel_filter grpc_http_client_filter = { const grpc_channel_filter grpc_http_client_filter = {
......
...@@ -291,11 +291,28 @@ void grpc_call_execute_op(grpc_call *call, grpc_call_op *op) { ...@@ -291,11 +291,28 @@ void grpc_call_execute_op(grpc_call *call, grpc_call_op *op) {
elem->filter->call_op(elem, NULL, op); elem->filter->call_op(elem, NULL, op);
} }
grpc_call_error grpc_call_add_metadata(grpc_call *call, grpc_metadata *metadata, void grpc_call_add_mdelem(grpc_call *call, grpc_mdelem *mdelem,
gpr_uint32 flags) { gpr_uint32 flags) {
grpc_call_element *elem; grpc_call_element *elem;
grpc_call_op op; grpc_call_op op;
GPR_ASSERT(call->state < CALL_FINISHED);
op.type = GRPC_SEND_METADATA;
op.dir = GRPC_CALL_DOWN;
op.flags = flags;
op.done_cb = do_nothing;
op.user_data = NULL;
op.data.metadata = mdelem;
elem = CALL_ELEM_FROM_CALL(call, 0);
elem->filter->call_op(elem, NULL, &op);
}
grpc_call_error grpc_call_add_metadata(grpc_call *call, grpc_metadata *metadata,
gpr_uint32 flags) {
grpc_mdelem *mdelem;
if (call->is_client) { if (call->is_client) {
if (call->state >= CALL_STARTED) { if (call->state >= CALL_STARTED) {
return GRPC_CALL_ERROR_ALREADY_INVOKED; return GRPC_CALL_ERROR_ALREADY_INVOKED;
...@@ -306,18 +323,10 @@ grpc_call_error grpc_call_add_metadata(grpc_call *call, grpc_metadata *metadata, ...@@ -306,18 +323,10 @@ grpc_call_error grpc_call_add_metadata(grpc_call *call, grpc_metadata *metadata,
} }
} }
op.type = GRPC_SEND_METADATA; mdelem = grpc_mdelem_from_string_and_buffer(
op.dir = GRPC_CALL_DOWN;
op.flags = flags;
op.done_cb = do_nothing;
op.user_data = NULL;
op.data.metadata = grpc_mdelem_from_string_and_buffer(
call->metadata_context, metadata->key, (gpr_uint8 *)metadata->value, call->metadata_context, metadata->key, (gpr_uint8 *)metadata->value,
metadata->value_length); metadata->value_length);
grpc_call_add_mdelem(call, mdelem, flags);
elem = CALL_ELEM_FROM_CALL(call, 0);
elem->filter->call_op(elem, NULL, &op);
return GRPC_CALL_OK; return GRPC_CALL_OK;
} }
......
...@@ -70,4 +70,7 @@ grpc_call *grpc_call_from_top_element(grpc_call_element *surface_element); ...@@ -70,4 +70,7 @@ grpc_call *grpc_call_from_top_element(grpc_call_element *surface_element);
/* Get the metadata buffer. */ /* Get the metadata buffer. */
grpc_metadata_buffer *grpc_call_get_metadata_buffer(grpc_call *call); grpc_metadata_buffer *grpc_call_get_metadata_buffer(grpc_call *call);
void grpc_call_add_mdelem(grpc_call *call, grpc_mdelem *mdelem,
gpr_uint32 flags);
#endif /* __GRPC_INTERNAL_SURFACE_CALL_H__ */ #endif /* __GRPC_INTERNAL_SURFACE_CALL_H__ */
...@@ -47,6 +47,8 @@ struct grpc_channel { ...@@ -47,6 +47,8 @@ struct grpc_channel {
grpc_mdctx *metadata_context; grpc_mdctx *metadata_context;
grpc_mdstr *grpc_status_string; grpc_mdstr *grpc_status_string;
grpc_mdstr *grpc_message_string; grpc_mdstr *grpc_message_string;
grpc_mdstr *path_string;
grpc_mdstr *authority_string;
}; };
#define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack *)((c)+1)) #define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack *)((c)+1))
...@@ -63,6 +65,8 @@ grpc_channel *grpc_channel_create_from_filters( ...@@ -63,6 +65,8 @@ grpc_channel *grpc_channel_create_from_filters(
channel->metadata_context = mdctx; channel->metadata_context = mdctx;
channel->grpc_status_string = grpc_mdstr_from_string(mdctx, "grpc-status"); channel->grpc_status_string = grpc_mdstr_from_string(mdctx, "grpc-status");
channel->grpc_message_string = grpc_mdstr_from_string(mdctx, "grpc-message"); channel->grpc_message_string = grpc_mdstr_from_string(mdctx, "grpc-message");
channel->path_string = grpc_mdstr_from_string(mdctx, ":path");
channel->authority_string = grpc_mdstr_from_string(mdctx, ":authority");
grpc_channel_stack_init(filters, num_filters, args, channel->metadata_context, grpc_channel_stack_init(filters, num_filters, args, channel->metadata_context,
CHANNEL_STACK_FROM_CHANNEL(channel)); CHANNEL_STACK_FROM_CHANNEL(channel));
return channel; return channel;
...@@ -74,7 +78,8 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel, const char *method, ...@@ -74,7 +78,8 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel, const char *method,
const char *host, const char *host,
gpr_timespec absolute_deadline) { gpr_timespec absolute_deadline) {
grpc_call *call; grpc_call *call;
grpc_metadata md; grpc_mdelem *path_mdelem;
grpc_mdelem *authority_mdelem;
if (!channel->is_client) { if (!channel->is_client) {
gpr_log(GPR_ERROR, "Cannot create a call on the server."); gpr_log(GPR_ERROR, "Cannot create a call on the server.");
...@@ -83,18 +88,21 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel, const char *method, ...@@ -83,18 +88,21 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel, const char *method,
call = grpc_call_create(channel, NULL); call = grpc_call_create(channel, NULL);
#define ADDMD(k, v) \ /* Add :path and :authority headers. */
do { \ /* TODO(klempner): Consider optimizing this by stashing mdelems for common
md.key = (k); \ values of method and host. */
md.value = (char *)(v); \ grpc_mdstr_ref(channel->path_string);
md.value_length = strlen((v)); \ path_mdelem = grpc_mdelem_from_metadata_strings(
grpc_call_add_metadata(call, &md, 0); \ channel->metadata_context, channel->path_string,
} while (0) grpc_mdstr_from_string(channel->metadata_context, method));
ADDMD(":method", "POST"); grpc_call_add_mdelem(call, path_mdelem, 0);
ADDMD(":scheme", "grpc");
ADDMD(":path", method); grpc_mdstr_ref(channel->authority_string);
ADDMD(":authority", host); authority_mdelem = grpc_mdelem_from_metadata_strings(
ADDMD("content-type", "application/grpc"); channel->metadata_context, channel->authority_string,
grpc_mdstr_from_string(channel->metadata_context, host));
grpc_call_add_mdelem(call, authority_mdelem, 0);
if (0 != gpr_time_cmp(absolute_deadline, gpr_inf_future)) { if (0 != gpr_time_cmp(absolute_deadline, gpr_inf_future)) {
grpc_call_op op; grpc_call_op op;
op.type = GRPC_SEND_DEADLINE; op.type = GRPC_SEND_DEADLINE;
...@@ -118,6 +126,8 @@ void grpc_channel_internal_unref(grpc_channel *channel) { ...@@ -118,6 +126,8 @@ void grpc_channel_internal_unref(grpc_channel *channel) {
grpc_channel_stack_destroy(CHANNEL_STACK_FROM_CHANNEL(channel)); grpc_channel_stack_destroy(CHANNEL_STACK_FROM_CHANNEL(channel));
grpc_mdstr_unref(channel->grpc_status_string); grpc_mdstr_unref(channel->grpc_status_string);
grpc_mdstr_unref(channel->grpc_message_string); grpc_mdstr_unref(channel->grpc_message_string);
grpc_mdstr_unref(channel->path_string);
grpc_mdstr_unref(channel->authority_string);
grpc_mdctx_orphan(channel->metadata_context); grpc_mdctx_orphan(channel->metadata_context);
gpr_free(channel); gpr_free(channel);
} }
......
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