|
|
|
@ -49,29 +49,28 @@ typedef struct grpc_rb_server { |
|
|
|
|
/* The actual server */ |
|
|
|
|
grpc_server* wrapped; |
|
|
|
|
grpc_completion_queue* queue; |
|
|
|
|
int shutdown_and_notify_done; |
|
|
|
|
int destroy_done; |
|
|
|
|
} grpc_rb_server; |
|
|
|
|
|
|
|
|
|
static void grpc_rb_server_maybe_shutdown_and_notify(grpc_rb_server* server, |
|
|
|
|
gpr_timespec deadline) { |
|
|
|
|
static void grpc_rb_server_shutdown_and_notify_internal(grpc_rb_server* server, |
|
|
|
|
gpr_timespec deadline) { |
|
|
|
|
grpc_event ev; |
|
|
|
|
void* tag = &ev; |
|
|
|
|
if (!server->shutdown_and_notify_done) { |
|
|
|
|
server->shutdown_and_notify_done = 1; |
|
|
|
|
if (server->wrapped != NULL) { |
|
|
|
|
grpc_server_shutdown_and_notify(server->wrapped, server->queue, tag); |
|
|
|
|
ev = rb_completion_queue_pluck(server->queue, tag, deadline, NULL); |
|
|
|
|
if (ev.type == GRPC_QUEUE_TIMEOUT) { |
|
|
|
|
grpc_server_cancel_all_calls(server->wrapped); |
|
|
|
|
ev = rb_completion_queue_pluck( |
|
|
|
|
server->queue, tag, gpr_inf_future(GPR_CLOCK_REALTIME), NULL); |
|
|
|
|
} |
|
|
|
|
if (ev.type != GRPC_OP_COMPLETE) { |
|
|
|
|
gpr_log(GPR_INFO, |
|
|
|
|
"GRPC_RUBY: bad grpc_server_shutdown_and_notify result:%d", |
|
|
|
|
ev.type); |
|
|
|
|
} |
|
|
|
|
if (server->wrapped != NULL) { |
|
|
|
|
grpc_server_shutdown_and_notify(server->wrapped, server->queue, tag); |
|
|
|
|
// Following pluck calls will release the GIL and block but cannot
|
|
|
|
|
// be interrupted. They should terminate quickly enough though b/c
|
|
|
|
|
// we will cancel all server calls after the deadline.
|
|
|
|
|
ev = rb_completion_queue_pluck(server->queue, tag, deadline, NULL, NULL); |
|
|
|
|
if (ev.type == GRPC_QUEUE_TIMEOUT) { |
|
|
|
|
grpc_server_cancel_all_calls(server->wrapped); |
|
|
|
|
ev = rb_completion_queue_pluck( |
|
|
|
|
server->queue, tag, gpr_inf_future(GPR_CLOCK_REALTIME), NULL, NULL); |
|
|
|
|
} |
|
|
|
|
if (ev.type != GRPC_OP_COMPLETE) { |
|
|
|
|
gpr_log(GPR_INFO, |
|
|
|
|
"GRPC_RUBY: bad grpc_server_shutdown_and_notify result:%d", |
|
|
|
|
ev.type); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -100,7 +99,7 @@ static void grpc_rb_server_free_internal(void* p) { |
|
|
|
|
deadline = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), |
|
|
|
|
gpr_time_from_seconds(2, GPR_TIMESPAN)); |
|
|
|
|
|
|
|
|
|
grpc_rb_server_maybe_shutdown_and_notify(svr, deadline); |
|
|
|
|
grpc_rb_server_shutdown_and_notify_internal(svr, deadline); |
|
|
|
|
grpc_rb_server_maybe_destroy(svr); |
|
|
|
|
|
|
|
|
|
xfree(p); |
|
|
|
@ -132,7 +131,6 @@ static VALUE grpc_rb_server_alloc(VALUE cls) { |
|
|
|
|
grpc_rb_server* wrapper = ALLOC(grpc_rb_server); |
|
|
|
|
wrapper->wrapped = NULL; |
|
|
|
|
wrapper->destroy_done = 0; |
|
|
|
|
wrapper->shutdown_and_notify_done = 0; |
|
|
|
|
return TypedData_Wrap_Struct(cls, &grpc_rb_server_data_type, wrapper); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -192,6 +190,24 @@ struct server_request_call_args { |
|
|
|
|
request_call_stack st; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static void shutdown_server_unblock_func(void* arg) { |
|
|
|
|
grpc_rb_server* server = (grpc_rb_server*)arg; |
|
|
|
|
gpr_log(GPR_INFO, "GRPC_RUBY: shutdown_server_unblock_func"); |
|
|
|
|
GPR_ASSERT(server->wrapped != NULL); |
|
|
|
|
grpc_event event; |
|
|
|
|
void* tag = &event; |
|
|
|
|
grpc_server_shutdown_and_notify(server->wrapped, server->queue, tag); |
|
|
|
|
grpc_server_cancel_all_calls(server->wrapped); |
|
|
|
|
// Following call is blocking, but should finish quickly since we've
|
|
|
|
|
// cancelled all calls.
|
|
|
|
|
event = grpc_completion_queue_pluck(server->queue, tag, |
|
|
|
|
gpr_inf_future(GPR_CLOCK_REALTIME), NULL); |
|
|
|
|
gpr_log(GPR_INFO, |
|
|
|
|
"GRPC_RUBY: shutdown_server_unblock_func pluck event.type: %d " |
|
|
|
|
"event.success: %d", |
|
|
|
|
event.type, event.success); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static VALUE grpc_rb_server_request_call_try(VALUE value_args) { |
|
|
|
|
grpc_rb_fork_unsafe_begin(); |
|
|
|
|
struct server_request_call_args* args = |
|
|
|
@ -215,7 +231,8 @@ static VALUE grpc_rb_server_request_call_try(VALUE value_args) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
grpc_event ev = rb_completion_queue_pluck( |
|
|
|
|
args->server->queue, tag, gpr_inf_future(GPR_CLOCK_REALTIME), NULL); |
|
|
|
|
args->server->queue, tag, gpr_inf_future(GPR_CLOCK_REALTIME), |
|
|
|
|
shutdown_server_unblock_func, args->server); |
|
|
|
|
if (!ev.success) { |
|
|
|
|
rb_raise(grpc_rb_eCallError, "request_call completion failed"); |
|
|
|
|
} |
|
|
|
@ -288,7 +305,7 @@ static VALUE grpc_rb_server_shutdown_and_notify(VALUE self, VALUE timeout) { |
|
|
|
|
deadline = grpc_rb_time_timeval(timeout, /* absolute time*/ 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
grpc_rb_server_maybe_shutdown_and_notify(s, deadline); |
|
|
|
|
grpc_rb_server_shutdown_and_notify_internal(s, deadline); |
|
|
|
|
|
|
|
|
|
return Qnil; |
|
|
|
|
} |
|
|
|
|