From 7f8a628f6ae1c67020c9137ea53d2f9f20b00a50 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 23 Nov 2016 10:36:08 -0800 Subject: [PATCH] fix race between app and GC on ruby server shutdown --- src/ruby/ext/grpc/rb_server.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ruby/ext/grpc/rb_server.c b/src/ruby/ext/grpc/rb_server.c index bf26841fd22..6783fd3f88a 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 +#include #include #include #include "rb_call.h" @@ -59,11 +60,13 @@ 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) { + // 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) { 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) { @@ -115,6 +118,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); }