From 649deebf7f50d29ed3550ce9dcd241cbeacb7df6 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 24 Sep 2015 23:19:40 -0700 Subject: Recycle partially filled buffers on the next read --- src/core/iomgr/tcp_posix.c | 9 ++++++++- src/core/support/slice_buffer.c | 9 +++++---- 2 files changed, 13 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/core/iomgr/tcp_posix.c b/src/core/iomgr/tcp_posix.c index c98f0125f8..54ebad7dbc 100644 --- a/src/core/iomgr/tcp_posix.c +++ b/src/core/iomgr/tcp_posix.c @@ -78,6 +78,9 @@ typedef struct { size_t slice_size; gpr_refcount refcount; + /* garbage after the last read */ + gpr_slice_buffer last_read_buffer; + gpr_slice_buffer *incoming_buffer; gpr_slice_buffer *outgoing_buffer; /** slice within outgoing_buffer to write next */ @@ -106,6 +109,7 @@ static void tcp_shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) { static void tcp_free(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) { grpc_fd_orphan(exec_ctx, tcp->em_fd, NULL, "tcp_unref_orphan"); + gpr_slice_buffer_destroy(&tcp->last_read_buffer); gpr_free(tcp->peer_string); gpr_free(tcp); } @@ -226,7 +230,8 @@ static void tcp_continue_read(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) { if ((size_t)read_bytes < tcp->incoming_buffer->length) { gpr_slice_buffer_trim_end( tcp->incoming_buffer, - tcp->incoming_buffer->length - (size_t)read_bytes); + tcp->incoming_buffer->length - (size_t)read_bytes, + &tcp->last_read_buffer); } else if (tcp->iov_size < MAX_READ_IOVEC) { ++tcp->iov_size; } @@ -259,6 +264,7 @@ static void tcp_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, tcp->read_cb = cb; tcp->incoming_buffer = incoming_buffer; gpr_slice_buffer_reset_and_unref(incoming_buffer); + gpr_slice_buffer_swap(incoming_buffer, &tcp->last_read_buffer); TCP_REF(tcp, "read"); if (tcp->finished_edge) { tcp->finished_edge = 0; @@ -457,6 +463,7 @@ grpc_endpoint *grpc_tcp_create(grpc_fd *em_fd, size_t slice_size, tcp->read_closure.cb_arg = tcp; tcp->write_closure.cb = tcp_handle_write; tcp->write_closure.cb_arg = tcp; + gpr_slice_buffer_init(&tcp->last_read_buffer); return &tcp->base; } diff --git a/src/core/support/slice_buffer.c b/src/core/support/slice_buffer.c index 8873d459d5..a1aa56fd72 100644 --- a/src/core/support/slice_buffer.c +++ b/src/core/support/slice_buffer.c @@ -208,7 +208,7 @@ void gpr_slice_buffer_move_into(gpr_slice_buffer *src, gpr_slice_buffer *dst) { src->length = 0; } -void gpr_slice_buffer_trim_end(gpr_slice_buffer *sb, size_t n) { +void gpr_slice_buffer_trim_end(gpr_slice_buffer *sb, size_t n, gpr_slice_buffer *garbage) { GPR_ASSERT(n <= sb->length); sb->length -= n; for (;;) { @@ -216,14 +216,15 @@ void gpr_slice_buffer_trim_end(gpr_slice_buffer *sb, size_t n) { gpr_slice slice = sb->slices[idx]; size_t slice_len = GPR_SLICE_LENGTH(slice); if (slice_len > n) { - sb->slices[idx] = gpr_slice_sub_no_ref(slice, 0, slice_len - n); + sb->slices[idx] = gpr_slice_split_head(&slice, slice_len - n); + gpr_slice_buffer_add_indexed(garbage, slice); return; } else if (slice_len == n) { - gpr_slice_unref(slice); + gpr_slice_buffer_add_indexed(garbage, slice); sb->count = idx; return; } else { - gpr_slice_unref(slice); + gpr_slice_buffer_add_indexed(garbage, slice); n -= slice_len; sb->count = idx; } -- cgit v1.2.3 From 0799ff3684d55f002cf3d8d5f5213181e923e631 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 24 Sep 2015 23:39:33 -0700 Subject: Fix a memory corruption bug --- src/core/transport/chttp2/incoming_metadata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/transport/chttp2/incoming_metadata.c b/src/core/transport/chttp2/incoming_metadata.c index d216c42113..10c64f3356 100644 --- a/src/core/transport/chttp2/incoming_metadata.c +++ b/src/core/transport/chttp2/incoming_metadata.c @@ -171,7 +171,7 @@ void grpc_chttp2_incoming_metadata_buffer_postprocess_sopb_and_begin_live_op( size_t copy_bytes = sizeof(*buffer->elems) * new_count; GPR_ASSERT(mdidx < buffer->count); buffer->elems = gpr_malloc(copy_bytes); - memcpy(live_op_buffer->elems + mdidx, buffer->elems, copy_bytes); + memcpy(buffer->elems, live_op_buffer->elems + mdidx, copy_bytes); buffer->count = buffer->capacity = new_count; } else { buffer->elems = NULL; -- cgit v1.2.3