Copy slices for in-process transports: its no longer safe to just ref

pull/10613/head
Craig Tiller 8 years ago
parent 24c7a18e94
commit 85bf34a4a8
  1. 3
      include/grpc/slice.h
  2. 7
      src/core/lib/slice/slice.c
  3. 4
      test/core/util/passthru_endpoint.c
  4. 7
      test/core/util/trickle_endpoint.c

@ -53,6 +53,9 @@ GPRAPI grpc_slice grpc_slice_ref(grpc_slice s);
where dest!=NULL , then (*dest)(start, len). Requires s initialized. */
GPRAPI void grpc_slice_unref(grpc_slice s);
/* Copy slice - create a new slice that contains the same data as s */
GPRAPI grpc_slice grpc_slice_copy(grpc_slice s);
/* Create a slice pointing at some data. Calls malloc to allocate a refcount
for the object, and arranges that destroy will be called with the pointer
passed in at destruction. */

@ -55,6 +55,13 @@ grpc_slice grpc_empty_slice(void) {
return out;
}
grpc_slice grpc_slice_copy(grpc_slice s) {
grpc_slice out = GRPC_SLICE_MALLOC(GRPC_SLICE_LENGTH(s));
memcpy(GRPC_SLICE_START_PTR(out), GRPC_SLICE_START_PTR(s),
GRPC_SLICE_LENGTH(s));
return out;
}
grpc_slice grpc_slice_ref_internal(grpc_slice slice) {
if (slice.refcount) {
slice.refcount->vtable->ref(slice.refcount);

@ -102,13 +102,13 @@ static void me_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Endpoint already shutdown");
} else if (m->on_read != NULL) {
for (size_t i = 0; i < slices->count; i++) {
grpc_slice_buffer_add(m->on_read_out, grpc_slice_ref(slices->slices[i]));
grpc_slice_buffer_add(m->on_read_out, grpc_slice_copy(slices->slices[i]));
}
grpc_closure_sched(exec_ctx, m->on_read, GRPC_ERROR_NONE);
m->on_read = NULL;
} else {
for (size_t i = 0; i < slices->count; i++) {
grpc_slice_buffer_add(&m->read_buffer, grpc_slice_ref(slices->slices[i]));
grpc_slice_buffer_add(&m->read_buffer, grpc_slice_copy(slices->slices[i]));
}
}
gpr_mu_unlock(&m->parent->mu);

@ -66,14 +66,13 @@ static void te_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
static void te_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
grpc_slice_buffer *slices, grpc_closure *cb) {
trickle_endpoint *te = (trickle_endpoint *)ep;
for (size_t i = 0; i < slices->count; i++) {
grpc_slice_ref_internal(slices->slices[i]);
}
gpr_mu_lock(&te->mu);
if (te->write_buffer.length == 0) {
te->last_write = gpr_now(GPR_CLOCK_MONOTONIC);
}
grpc_slice_buffer_addn(&te->write_buffer, slices->slices, slices->count);
for (size_t i = 0; i < slices->count; i++) {
grpc_slice_buffer_add(&te->write_buffer, grpc_slice_copy(slices->slices[i]));
}
grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_REF(te->error));
gpr_mu_unlock(&te->mu);
}

Loading…
Cancel
Save