aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ruby/ext
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2016-12-27 08:59:00 -0800
committerGravatar Craig Tiller <ctiller@google.com>2016-12-27 08:59:00 -0800
commitef6938477b5019fea4f0ed7da06cc1f974f29438 (patch)
tree7501942df052fa4d983a3f2f4b0adaf99be317c8 /src/ruby/ext
parent9a66ba5fe9b0714f2b48c6d3848d9716cdf85b91 (diff)
parent702f93d3645055bd77181935c18f41a9de272c1e (diff)
Merge branch 'slice_with_exec_ctx' into metadata_filter
Diffstat (limited to 'src/ruby/ext')
-rw-r--r--src/ruby/ext/grpc/rb_byte_buffer.c1
-rw-r--r--src/ruby/ext/grpc/rb_server.c28
2 files changed, 18 insertions, 11 deletions
diff --git a/src/ruby/ext/grpc/rb_byte_buffer.c b/src/ruby/ext/grpc/rb_byte_buffer.c
index 0f15f70a28..65fa2f2cf6 100644
--- a/src/ruby/ext/grpc/rb_byte_buffer.c
+++ b/src/ruby/ext/grpc/rb_byte_buffer.c
@@ -65,6 +65,7 @@ VALUE grpc_rb_byte_buffer_to_s(grpc_byte_buffer *buffer) {
GRPC_SLICE_LENGTH(next));
grpc_slice_unref(next);
}
+ grpc_byte_buffer_reader_destroy(&reader);
return rb_string;
}
diff --git a/src/ruby/ext/grpc/rb_server.c b/src/ruby/ext/grpc/rb_server.c
index 7caafe7b8d..7b2f5774aa 100644
--- a/src/ruby/ext/grpc/rb_server.c
+++ b/src/ruby/ext/grpc/rb_server.c
@@ -37,6 +37,7 @@
#include "rb_server.h"
#include <grpc/grpc.h>
+#include <grpc/support/atm.h>
#include <grpc/grpc_security.h>
#include <grpc/support/log.h>
#include "rb_call.h"
@@ -60,22 +61,26 @@ typedef struct grpc_rb_server {
/* The actual server */
grpc_server *wrapped;
grpc_completion_queue *queue;
+ gpr_atm shutdown_started;
} grpc_rb_server;
static void destroy_server(grpc_rb_server *server, gpr_timespec deadline) {
grpc_event ev;
- if (server->wrapped != NULL) {
- grpc_server_shutdown_and_notify(server->wrapped, server->queue, NULL);
- ev = rb_completion_queue_pluck(server->queue, NULL, deadline, NULL);
- if (ev.type == GRPC_QUEUE_TIMEOUT) {
- grpc_server_cancel_all_calls(server->wrapped);
- rb_completion_queue_pluck(server->queue, NULL,
- gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+ // This can be started by app or implicitly by GC. Avoid a race between these.
+ if (gpr_atm_full_fetch_add(&server->shutdown_started, (gpr_atm)1) == 0) {
+ if (server->wrapped != NULL) {
+ grpc_server_shutdown_and_notify(server->wrapped, server->queue, NULL);
+ ev = rb_completion_queue_pluck(server->queue, NULL, deadline, NULL);
+ if (ev.type == GRPC_QUEUE_TIMEOUT) {
+ grpc_server_cancel_all_calls(server->wrapped);
+ rb_completion_queue_pluck(server->queue, NULL,
+ gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+ }
+ grpc_server_destroy(server->wrapped);
+ grpc_rb_completion_queue_destroy(server->queue);
+ server->wrapped = NULL;
+ server->queue = NULL;
}
- grpc_server_destroy(server->wrapped);
- grpc_rb_completion_queue_destroy(server->queue);
- server->wrapped = NULL;
- server->queue = NULL;
}
}
@@ -116,6 +121,7 @@ static const rb_data_type_t grpc_rb_server_data_type = {
static VALUE grpc_rb_server_alloc(VALUE cls) {
grpc_rb_server *wrapper = ALLOC(grpc_rb_server);
wrapper->wrapped = NULL;
+ wrapper->shutdown_started = (gpr_atm)0;
return TypedData_Wrap_Struct(cls, &grpc_rb_server_data_type, wrapper);
}