|
|
|
@ -1890,13 +1890,22 @@ static void patch_metadata_ops(stream *s) { |
|
|
|
|
size_t j; |
|
|
|
|
size_t mdidx = 0; |
|
|
|
|
size_t last_mdidx; |
|
|
|
|
int found_metadata = 0; |
|
|
|
|
|
|
|
|
|
/* rework the array of metadata into a linked list, making use
|
|
|
|
|
of the breadcrumbs we left in metadata batches during
|
|
|
|
|
add_metadata_batch */ |
|
|
|
|
for (i = 0; i < nops; i++) { |
|
|
|
|
grpc_stream_op *op = &ops[i]; |
|
|
|
|
if (op->type != GRPC_OP_METADATA) continue; |
|
|
|
|
found_metadata = 1; |
|
|
|
|
/* we left a breadcrumb indicating where the end of this list is,
|
|
|
|
|
and since we add sequentially, we know from the end of the last |
|
|
|
|
segment where this segment begins */ |
|
|
|
|
last_mdidx = (size_t)(gpr_intptr)(op->data.metadata.list.tail); |
|
|
|
|
GPR_ASSERT(last_mdidx > mdidx); |
|
|
|
|
GPR_ASSERT(last_mdidx <= s->incoming_metadata_count); |
|
|
|
|
/* turn the array into a doubly linked list */ |
|
|
|
|
op->data.metadata.list.head = &s->incoming_metadata[mdidx]; |
|
|
|
|
op->data.metadata.list.tail = &s->incoming_metadata[last_mdidx - 1]; |
|
|
|
|
for (j = mdidx + 1; j < last_mdidx; j++) { |
|
|
|
@ -1905,13 +1914,25 @@ static void patch_metadata_ops(stream *s) { |
|
|
|
|
} |
|
|
|
|
s->incoming_metadata[mdidx].prev = NULL; |
|
|
|
|
s->incoming_metadata[last_mdidx-1].next = NULL; |
|
|
|
|
/* track where we're up to */ |
|
|
|
|
mdidx = last_mdidx; |
|
|
|
|
} |
|
|
|
|
GPR_ASSERT(mdidx == s->incoming_metadata_count); |
|
|
|
|
s->old_incoming_metadata = s->incoming_metadata; |
|
|
|
|
s->incoming_metadata = NULL; |
|
|
|
|
s->incoming_metadata_count = 0; |
|
|
|
|
s->incoming_metadata_capacity = 0; |
|
|
|
|
if (found_metadata) { |
|
|
|
|
s->old_incoming_metadata = s->incoming_metadata; |
|
|
|
|
if (mdidx != s->incoming_metadata_count) { |
|
|
|
|
/* we have a partially read metadata batch still in incoming_metadata */ |
|
|
|
|
size_t new_count = s->incoming_metadata_count - mdidx; |
|
|
|
|
size_t copy_bytes = sizeof(*s->incoming_metadata) * new_count; |
|
|
|
|
GPR_ASSERT(mdidx < s->incoming_metadata_count); |
|
|
|
|
s->incoming_metadata = gpr_malloc(copy_bytes); |
|
|
|
|
memcpy(s->old_incoming_metadata + mdidx, s->incoming_metadata, copy_bytes); |
|
|
|
|
s->incoming_metadata_count = s->incoming_metadata_capacity = new_count; |
|
|
|
|
} else { |
|
|
|
|
s->incoming_metadata = NULL; |
|
|
|
|
s->incoming_metadata_count = 0; |
|
|
|
|
s->incoming_metadata_capacity = 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void finish_reads(transport *t) { |
|
|
|
|