Make channels and calls properly mark references to their credentials

pull/5929/head
murgatroid99 9 years ago
parent 05afaa838a
commit 8c9edc2a57
  1. 6
      src/ruby/ext/grpc/rb_call.c
  2. 22
      src/ruby/ext/grpc/rb_channel.c

@ -72,6 +72,10 @@ static ID id_cq;
* the flags used to create metadata from a Hash */
static ID id_flags;
/* id_credentials is the name of the hidden ivar that preserves the value
* of the credentials added to the call */
static ID id_credentials;
/* id_input_md is the name of the hidden ivar that preserves the hash used to
* create metadata, so that references to the strings it contains last as long
* as the call the metadata is added to. */
@ -299,6 +303,7 @@ static VALUE grpc_rb_call_set_credentials(VALUE self, VALUE credentials) {
"grpc_call_set_credentials failed with %s (code=%d)",
grpc_call_error_detail_of(err), err);
}
rb_ivar_set(self, id_credentials, credentials);
return Qnil;
}
@ -859,6 +864,7 @@ void Init_grpc_call() {
id_cq = rb_intern("__cq");
id_flags = rb_intern("__flags");
id_input_md = rb_intern("__input_md");
id_credentials = rb_intern("__credentials");
/* Ids used in constructing the batch result. */
sym_send_message = ID2SYM(rb_intern("send_message"));

@ -70,11 +70,10 @@ static VALUE grpc_rb_cChannel = Qnil;
/* Used during the conversion of a hash to channel args during channel setup */
static VALUE grpc_rb_cChannelArgs;
/* grpc_rb_channel wraps a grpc_channel. It provides a peer ruby object,
* 'mark' to minimize copying when a channel is created from ruby. */
/* grpc_rb_channel wraps a grpc_channel. */
typedef struct grpc_rb_channel {
/* Holder of ruby objects involved in constructing the channel */
VALUE mark;
VALUE credentials;
/* The actual channel */
grpc_channel *wrapped;
} grpc_rb_channel;
@ -87,13 +86,8 @@ static void grpc_rb_channel_free(void *p) {
};
ch = (grpc_rb_channel *)p;
/* Deletes the wrapped object if the mark object is Qnil, which indicates
* that no other object is the actual owner. */
if (ch->wrapped != NULL && ch->mark == Qnil) {
if (ch->wrapped != NULL) {
grpc_channel_destroy(ch->wrapped);
rb_warning("channel gc: destroyed the c channel");
} else {
rb_warning("channel gc: did not destroy the c channel");
}
xfree(p);
@ -106,8 +100,8 @@ static void grpc_rb_channel_mark(void *p) {
return;
}
channel = (grpc_rb_channel *)p;
if (channel->mark != Qnil) {
rb_gc_mark(channel->mark);
if (channel->credentials != Qnil) {
rb_gc_mark(channel->credentials);
}
}
@ -125,7 +119,7 @@ static rb_data_type_t grpc_channel_data_type = {
static VALUE grpc_rb_channel_alloc(VALUE cls) {
grpc_rb_channel *wrapper = ALLOC(grpc_rb_channel);
wrapper->wrapped = NULL;
wrapper->mark = Qnil;
wrapper->credentials = Qnil;
return TypedData_Wrap_Struct(cls, &grpc_channel_data_type, wrapper);
}
@ -162,6 +156,7 @@ static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) {
}
ch = grpc_insecure_channel_create(target_chars, &args, NULL);
} else {
wrapper->credentials = credentials;
creds = grpc_rb_get_wrapped_channel_credentials(credentials);
ch = grpc_secure_channel_create(creds, target_chars, &args, NULL);
}
@ -330,7 +325,6 @@ static VALUE grpc_rb_channel_destroy(VALUE self) {
if (ch != NULL) {
grpc_channel_destroy(ch);
wrapper->wrapped = NULL;
wrapper->mark = Qnil;
}
return Qnil;

Loading…
Cancel
Save