aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Zhuochun <zhuochun@hotmail.com>2016-03-13 16:19:56 +0800
committerGravatar Nicolas "Pixel" Noble <pixel@nobis-crew.org>2016-03-30 01:08:29 +0200
commit97daf35addf51951748d2954580fe10dffd3be36 (patch)
treec19e8fe15d4e7c9a4ae875406a41739d52080d05 /src
parentf30bdb817d754dbb92c56eadaed692fc90159651 (diff)
Fix Ruby memory leaks
- `recv_message` is not cleaned up after call - `send_message` is not cleaned up in failure cases - `xmalloc` ruby string is not freed after used
Diffstat (limited to 'src')
-rw-r--r--src/ruby/ext/grpc/rb_byte_buffer.c7
-rw-r--r--src/ruby/ext/grpc/rb_call.c14
2 files changed, 18 insertions, 3 deletions
diff --git a/src/ruby/ext/grpc/rb_byte_buffer.c b/src/ruby/ext/grpc/rb_byte_buffer.c
index db7cac363a..52523b8319 100644
--- a/src/ruby/ext/grpc/rb_byte_buffer.c
+++ b/src/ruby/ext/grpc/rb_byte_buffer.c
@@ -52,12 +52,12 @@ grpc_byte_buffer* grpc_rb_s_to_byte_buffer(char *string, size_t length) {
VALUE grpc_rb_byte_buffer_to_s(grpc_byte_buffer *buffer) {
size_t length = 0;
char *string = NULL;
+ VALUE rb_string;
size_t offset = 0;
grpc_byte_buffer_reader reader;
gpr_slice next;
if (buffer == NULL) {
return Qnil;
-
}
length = grpc_byte_buffer_length(buffer);
string = xmalloc(length + 1);
@@ -65,6 +65,9 @@ VALUE grpc_rb_byte_buffer_to_s(grpc_byte_buffer *buffer) {
while (grpc_byte_buffer_reader_next(&reader, &next) != 0) {
memcpy(string + offset, GPR_SLICE_START_PTR(next), GPR_SLICE_LENGTH(next));
offset += GPR_SLICE_LENGTH(next);
+ gpr_slice_unref(next);
}
- return rb_str_new(string, length);
+ rb_string = rb_str_new(string, length);
+ xfree(string);
+ return rb_string;
}
diff --git a/src/ruby/ext/grpc/rb_call.c b/src/ruby/ext/grpc/rb_call.c
index cd0aa6aaf2..b0829efdc7 100644
--- a/src/ruby/ext/grpc/rb_call.c
+++ b/src/ruby/ext/grpc/rb_call.c
@@ -551,13 +551,26 @@ static void grpc_run_batch_stack_init(run_batch_stack *st,
/* grpc_run_batch_stack_cleanup ensures the run_batch_stack is properly
* cleaned up */
static void grpc_run_batch_stack_cleanup(run_batch_stack *st) {
+ size_t i = 0;
+
grpc_metadata_array_destroy(&st->send_metadata);
grpc_metadata_array_destroy(&st->send_trailing_metadata);
grpc_metadata_array_destroy(&st->recv_metadata);
grpc_metadata_array_destroy(&st->recv_trailing_metadata);
+
if (st->recv_status_details != NULL) {
gpr_free(st->recv_status_details);
}
+
+ if (st->recv_message != NULL) {
+ grpc_byte_buffer_destroy(st->recv_message);
+ }
+
+ for (i = 0; i < st->op_num; i++) {
+ if (st->ops[i].op == GRPC_OP_SEND_MESSAGE) {
+ grpc_byte_buffer_destroy(st->ops[i].data.send_message);
+ }
+ }
}
/* grpc_run_batch_stack_fill_ops fills the run_batch_stack ops array from
@@ -643,7 +656,6 @@ static VALUE grpc_run_batch_stack_build_result(run_batch_stack *st) {
break;
case GRPC_OP_SEND_MESSAGE:
rb_struct_aset(result, sym_send_message, Qtrue);
- grpc_byte_buffer_destroy(st->ops[i].data.send_message);
break;
case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
rb_struct_aset(result, sym_send_close, Qtrue);