Merge pull request #1295 from yugui/fix/typed-struct

Use TypedData_XXX instead of Data_XXX
pull/1310/head
Tim Emiola 10 years ago
commit 3d3a65da84
  1. 50
      src/ruby/ext/grpc/rb_call.c
  2. 22
      src/ruby/ext/grpc/rb_channel.c
  3. 15
      src/ruby/ext/grpc/rb_channel_args.c
  4. 22
      src/ruby/ext/grpc/rb_completion_queue.c
  5. 47
      src/ruby/ext/grpc/rb_credentials.c
  6. 35
      src/ruby/ext/grpc/rb_grpc.c
  7. 8
      src/ruby/ext/grpc/rb_grpc.h
  8. 33
      src/ruby/ext/grpc/rb_server.c
  9. 24
      src/ruby/ext/grpc/rb_server_credentials.c

@ -117,6 +117,37 @@ static void grpc_rb_call_destroy(void *p) {
} }
} }
static size_t md_ary_datasize(const void *p) {
const grpc_metadata_array* const ary = (grpc_metadata_array*)p;
size_t i, datasize = sizeof(grpc_metadata_array);
for (i = 0; i < ary->count; ++i) {
const grpc_metadata* const md = &ary->metadata[i];
datasize += strlen(md->key);
datasize += md->value_length;
}
datasize += ary->capacity * sizeof(grpc_metadata);
return datasize;
}
static const rb_data_type_t grpc_rb_md_ary_data_type = {
"grpc_metadata_array",
{GRPC_RB_GC_NOT_MARKED, GRPC_RB_GC_DONT_FREE, md_ary_datasize},
NULL, NULL,
0
};
/* Describes grpc_call struct for RTypedData */
static const rb_data_type_t grpc_call_data_type = {
"grpc_call",
{GRPC_RB_GC_NOT_MARKED, grpc_rb_call_destroy, GRPC_RB_MEMSIZE_UNAVAILABLE},
NULL, NULL,
/* it is unsafe to specify RUBY_TYPED_FREE_IMMEDIATELY because grpc_rb_call_destroy
* touches a hash object.
* TODO(yugui) Directly use st_table and call the free function earlier?
*/
0
};
/* Error code details is a hash containing text strings describing errors */ /* Error code details is a hash containing text strings describing errors */
VALUE rb_error_code_details; VALUE rb_error_code_details;
@ -135,7 +166,7 @@ const char *grpc_call_error_detail_of(grpc_call_error err) {
static VALUE grpc_rb_call_cancel(VALUE self) { static VALUE grpc_rb_call_cancel(VALUE self) {
grpc_call *call = NULL; grpc_call *call = NULL;
grpc_call_error err; grpc_call_error err;
Data_Get_Struct(self, grpc_call, call); TypedData_Get_Struct(self, grpc_call, &grpc_call_data_type, call);
err = grpc_call_cancel(call); err = grpc_call_cancel(call);
if (err != GRPC_CALL_OK) { if (err != GRPC_CALL_OK) {
rb_raise(grpc_rb_eCallError, "cancel failed: %s (code=%d)", rb_raise(grpc_rb_eCallError, "cancel failed: %s (code=%d)",
@ -205,7 +236,8 @@ static int grpc_rb_md_ary_fill_hash_cb(VALUE key, VALUE val, VALUE md_ary_obj) {
int i; int i;
/* Construct a metadata object from key and value and add it */ /* Construct a metadata object from key and value and add it */
Data_Get_Struct(md_ary_obj, grpc_metadata_array, md_ary); TypedData_Get_Struct(md_ary_obj, grpc_metadata_array,
&grpc_rb_md_ary_data_type, md_ary);
if (TYPE(val) == T_ARRAY) { if (TYPE(val) == T_ARRAY) {
/* If the value is an array, add capacity for each value in the array */ /* If the value is an array, add capacity for each value in the array */
@ -243,7 +275,8 @@ static int grpc_rb_md_ary_capacity_hash_cb(VALUE key, VALUE val,
grpc_metadata_array *md_ary = NULL; grpc_metadata_array *md_ary = NULL;
/* Construct a metadata object from key and value and add it */ /* Construct a metadata object from key and value and add it */
Data_Get_Struct(md_ary_obj, grpc_metadata_array, md_ary); TypedData_Get_Struct(md_ary_obj, grpc_metadata_array,
&grpc_rb_md_ary_data_type, md_ary);
if (TYPE(val) == T_ARRAY) { if (TYPE(val) == T_ARRAY) {
/* If the value is an array, add capacity for each value in the array */ /* If the value is an array, add capacity for each value in the array */
@ -270,8 +303,8 @@ static void grpc_rb_md_ary_convert(VALUE md_ary_hash, grpc_metadata_array *md_ar
/* Initialize the array, compute it's capacity, then fill it. */ /* Initialize the array, compute it's capacity, then fill it. */
grpc_metadata_array_init(md_ary); grpc_metadata_array_init(md_ary);
md_ary_obj = md_ary_obj = TypedData_Wrap_Struct(grpc_rb_cMdAry, &grpc_rb_md_ary_data_type,
Data_Wrap_Struct(grpc_rb_cMdAry, GC_NOT_MARKED, GC_DONT_FREE, md_ary); md_ary);
rb_hash_foreach(md_ary_hash, grpc_rb_md_ary_capacity_hash_cb, md_ary_obj); rb_hash_foreach(md_ary_hash, grpc_rb_md_ary_capacity_hash_cb, md_ary_obj);
md_ary->metadata = gpr_malloc(md_ary->capacity * sizeof(grpc_metadata)); md_ary->metadata = gpr_malloc(md_ary->capacity * sizeof(grpc_metadata));
rb_hash_foreach(md_ary_hash, grpc_rb_md_ary_fill_hash_cb, md_ary_obj); rb_hash_foreach(md_ary_hash, grpc_rb_md_ary_fill_hash_cb, md_ary_obj);
@ -556,7 +589,7 @@ static VALUE grpc_rb_call_run_batch(VALUE self, VALUE cqueue, VALUE tag,
grpc_event *ev = NULL; grpc_event *ev = NULL;
grpc_call_error err; grpc_call_error err;
VALUE result = Qnil; VALUE result = Qnil;
Data_Get_Struct(self, grpc_call, call); TypedData_Get_Struct(self, grpc_call, &grpc_call_data_type, call);
/* Validate the ops args, adding them to a ruby array */ /* Validate the ops args, adding them to a ruby array */
if (TYPE(ops_hash) != T_HASH) { if (TYPE(ops_hash) != T_HASH) {
@ -736,7 +769,7 @@ void Init_grpc_call() {
/* Gets the call from the ruby object */ /* Gets the call from the ruby object */
grpc_call *grpc_rb_get_wrapped_call(VALUE v) { grpc_call *grpc_rb_get_wrapped_call(VALUE v) {
grpc_call *c = NULL; grpc_call *c = NULL;
Data_Get_Struct(v, grpc_call, c); TypedData_Get_Struct(v, grpc_call, &grpc_call_data_type, c);
return c; return c;
} }
@ -753,6 +786,5 @@ VALUE grpc_rb_wrap_call(grpc_call *c) {
rb_hash_aset(hash_all_calls, OFFT2NUM((VALUE)c), rb_hash_aset(hash_all_calls, OFFT2NUM((VALUE)c),
UINT2NUM(NUM2UINT(obj) + 1)); UINT2NUM(NUM2UINT(obj) + 1));
} }
return Data_Wrap_Struct(grpc_rb_cCall, GC_NOT_MARKED, return TypedData_Wrap_Struct(grpc_rb_cCall, &grpc_call_data_type, c);
grpc_rb_call_destroy, c);
} }

@ -105,13 +105,19 @@ static void grpc_rb_channel_mark(void *p) {
} }
} }
static rb_data_type_t grpc_channel_data_type = {
"grpc_channel",
{grpc_rb_channel_mark, grpc_rb_channel_free, GRPC_RB_MEMSIZE_UNAVAILABLE},
NULL, NULL,
RUBY_TYPED_FREE_IMMEDIATELY
};
/* Allocates grpc_rb_channel instances. */ /* Allocates grpc_rb_channel instances. */
static VALUE grpc_rb_channel_alloc(VALUE cls) { static VALUE grpc_rb_channel_alloc(VALUE cls) {
grpc_rb_channel *wrapper = ALLOC(grpc_rb_channel); grpc_rb_channel *wrapper = ALLOC(grpc_rb_channel);
wrapper->wrapped = NULL; wrapper->wrapped = NULL;
wrapper->mark = Qnil; wrapper->mark = Qnil;
return Data_Wrap_Struct(cls, grpc_rb_channel_mark, grpc_rb_channel_free, return TypedData_Wrap_Struct(cls, &grpc_channel_data_type, wrapper);
wrapper);
} }
/* /*
@ -135,7 +141,7 @@ static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) {
/* "21" == 2 mandatory args, 1 (credentials) is optional */ /* "21" == 2 mandatory args, 1 (credentials) is optional */
rb_scan_args(argc, argv, "21", &target, &channel_args, &credentials); rb_scan_args(argc, argv, "21", &target, &channel_args, &credentials);
Data_Get_Struct(self, grpc_rb_channel, wrapper); TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
target_chars = StringValueCStr(target); target_chars = StringValueCStr(target);
grpc_rb_hash_convert_to_channel_args(channel_args, &args); grpc_rb_hash_convert_to_channel_args(channel_args, &args);
if (credentials == Qnil) { if (credentials == Qnil) {
@ -176,8 +182,8 @@ static VALUE grpc_rb_channel_init_copy(VALUE copy, VALUE orig) {
return Qnil; return Qnil;
} }
Data_Get_Struct(orig, grpc_rb_channel, orig_ch); TypedData_Get_Struct(orig, grpc_rb_channel, &grpc_channel_data_type, orig_ch);
Data_Get_Struct(copy, grpc_rb_channel, copy_ch); TypedData_Get_Struct(copy, grpc_rb_channel, &grpc_channel_data_type, copy_ch);
/* use ruby's MEMCPY to make a byte-for-byte copy of the channel wrapper /* use ruby's MEMCPY to make a byte-for-byte copy of the channel wrapper
* object. */ * object. */
@ -198,7 +204,7 @@ static VALUE grpc_rb_channel_create_call(VALUE self, VALUE cqueue, VALUE method,
char *host_chars = StringValueCStr(host); char *host_chars = StringValueCStr(host);
cq = grpc_rb_get_wrapped_completion_queue(cqueue); cq = grpc_rb_get_wrapped_completion_queue(cqueue);
Data_Get_Struct(self, grpc_rb_channel, wrapper); TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
ch = wrapper->wrapped; ch = wrapper->wrapped;
if (ch == NULL) { if (ch == NULL) {
rb_raise(rb_eRuntimeError, "closed!"); rb_raise(rb_eRuntimeError, "closed!");
@ -231,7 +237,7 @@ static VALUE grpc_rb_channel_destroy(VALUE self) {
grpc_rb_channel *wrapper = NULL; grpc_rb_channel *wrapper = NULL;
grpc_channel *ch = NULL; grpc_channel *ch = NULL;
Data_Get_Struct(self, grpc_rb_channel, wrapper); TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
ch = wrapper->wrapped; ch = wrapper->wrapped;
if (ch != NULL) { if (ch != NULL) {
grpc_channel_destroy(ch); grpc_channel_destroy(ch);
@ -277,6 +283,6 @@ void Init_grpc_channel() {
/* Gets the wrapped channel from the ruby wrapper */ /* Gets the wrapped channel from the ruby wrapper */
grpc_channel *grpc_rb_get_wrapped_channel(VALUE v) { grpc_channel *grpc_rb_get_wrapped_channel(VALUE v) {
grpc_rb_channel *wrapper = NULL; grpc_rb_channel *wrapper = NULL;
Data_Get_Struct(v, grpc_rb_channel, wrapper); TypedData_Get_Struct(v, grpc_rb_channel, &grpc_channel_data_type, wrapper);
return wrapper->wrapped; return wrapper->wrapped;
} }

@ -38,6 +38,13 @@
#include "rb_grpc.h" #include "rb_grpc.h"
static rb_data_type_t grpc_rb_channel_args_data_type = {
"grpc_channel_args",
{GRPC_RB_GC_NOT_MARKED, GRPC_RB_GC_DONT_FREE, GRPC_RB_MEMSIZE_UNAVAILABLE},
NULL, NULL,
RUBY_TYPED_FREE_IMMEDIATELY
};
/* A callback the processes the hash key values in channel_args hash */ /* A callback the processes the hash key values in channel_args hash */
static int grpc_rb_channel_create_in_process_add_args_hash_cb(VALUE key, static int grpc_rb_channel_create_in_process_add_args_hash_cb(VALUE key,
VALUE val, VALUE val,
@ -60,7 +67,8 @@ static int grpc_rb_channel_create_in_process_add_args_hash_cb(VALUE key,
return ST_STOP; return ST_STOP;
} }
Data_Get_Struct(args_obj, grpc_channel_args, args); TypedData_Get_Struct(args_obj, grpc_channel_args,
&grpc_rb_channel_args_data_type, args);
if (args->num_args <= 0) { if (args->num_args <= 0) {
rb_raise(rb_eRuntimeError, "hash_cb bug: num_args is %lu for key:%s", rb_raise(rb_eRuntimeError, "hash_cb bug: num_args is %lu for key:%s",
args->num_args, StringValueCStr(key)); args->num_args, StringValueCStr(key));
@ -126,8 +134,9 @@ static VALUE grpc_rb_hash_convert_to_channel_args0(VALUE as_value) {
MEMZERO(params->dst->args, grpc_arg, num_args); MEMZERO(params->dst->args, grpc_arg, num_args);
rb_hash_foreach(params->src_hash, rb_hash_foreach(params->src_hash,
grpc_rb_channel_create_in_process_add_args_hash_cb, grpc_rb_channel_create_in_process_add_args_hash_cb,
Data_Wrap_Struct(grpc_rb_cChannelArgs, GC_NOT_MARKED, TypedData_Wrap_Struct(grpc_rb_cChannelArgs,
GC_DONT_FREE, params->dst)); &grpc_rb_channel_args_data_type,
params->dst));
/* reset num_args as grpc_rb_channel_create_in_process_add_args_hash_cb /* reset num_args as grpc_rb_channel_create_in_process_add_args_hash_cb
* decrements it during has processing */ * decrements it during has processing */
params->dst->num_args = num_args; params->dst->num_args = num_args;

@ -116,21 +116,31 @@ static void grpc_rb_completion_queue_destroy(void *p) {
grpc_completion_queue_destroy(cq); grpc_completion_queue_destroy(cq);
} }
static rb_data_type_t grpc_rb_completion_queue_data_type = {
"grpc_completion_queue",
{GRPC_RB_GC_NOT_MARKED, grpc_rb_completion_queue_destroy,
GRPC_RB_MEMSIZE_UNAVAILABLE},
NULL, NULL,
/* cannot immediately free because grpc_rb_completion_queue_shutdown_drain
* calls rb_thread_call_without_gvl. */
0
};
/* Allocates a completion queue. */ /* Allocates a completion queue. */
static VALUE grpc_rb_completion_queue_alloc(VALUE cls) { static VALUE grpc_rb_completion_queue_alloc(VALUE cls) {
grpc_completion_queue *cq = grpc_completion_queue_create(); grpc_completion_queue *cq = grpc_completion_queue_create();
if (cq == NULL) { if (cq == NULL) {
rb_raise(rb_eArgError, "could not create a completion queue: not sure why"); rb_raise(rb_eArgError, "could not create a completion queue: not sure why");
} }
return Data_Wrap_Struct(cls, GC_NOT_MARKED, grpc_rb_completion_queue_destroy, return TypedData_Wrap_Struct(cls, &grpc_rb_completion_queue_data_type, cq);
cq);
} }
/* Blocks until the next event is available, and returns the event. */ /* Blocks until the next event is available, and returns the event. */
static VALUE grpc_rb_completion_queue_next(VALUE self, VALUE timeout) { static VALUE grpc_rb_completion_queue_next(VALUE self, VALUE timeout) {
next_call_stack next_call; next_call_stack next_call;
MEMZERO(&next_call, next_call_stack, 1); MEMZERO(&next_call, next_call_stack, 1);
Data_Get_Struct(self, grpc_completion_queue, next_call.cq); TypedData_Get_Struct(self, grpc_completion_queue,
&grpc_rb_completion_queue_data_type, next_call.cq);
next_call.timeout = grpc_rb_time_timeval(timeout, /* absolute time*/ 0); next_call.timeout = grpc_rb_time_timeval(timeout, /* absolute time*/ 0);
next_call.event = NULL; next_call.event = NULL;
rb_thread_call_without_gvl(grpc_rb_completion_queue_next_no_gil, rb_thread_call_without_gvl(grpc_rb_completion_queue_next_no_gil,
@ -158,7 +168,8 @@ grpc_event* grpc_rb_completion_queue_pluck_event(VALUE self, VALUE tag,
VALUE timeout) { VALUE timeout) {
next_call_stack next_call; next_call_stack next_call;
MEMZERO(&next_call, next_call_stack, 1); MEMZERO(&next_call, next_call_stack, 1);
Data_Get_Struct(self, grpc_completion_queue, next_call.cq); TypedData_Get_Struct(self, grpc_completion_queue,
&grpc_rb_completion_queue_data_type, next_call.cq);
next_call.timeout = grpc_rb_time_timeval(timeout, /* absolute time*/ 0); next_call.timeout = grpc_rb_time_timeval(timeout, /* absolute time*/ 0);
next_call.tag = ROBJECT(tag); next_call.tag = ROBJECT(tag);
next_call.event = NULL; next_call.event = NULL;
@ -192,6 +203,7 @@ void Init_grpc_completion_queue() {
/* Gets the wrapped completion queue from the ruby wrapper */ /* Gets the wrapped completion queue from the ruby wrapper */
grpc_completion_queue *grpc_rb_get_wrapped_completion_queue(VALUE v) { grpc_completion_queue *grpc_rb_get_wrapped_completion_queue(VALUE v) {
grpc_completion_queue *cq = NULL; grpc_completion_queue *cq = NULL;
Data_Get_Struct(v, grpc_completion_queue, cq); TypedData_Get_Struct(v, grpc_completion_queue,
&grpc_rb_completion_queue_data_type, cq);
return cq; return cq;
} }

@ -86,14 +86,21 @@ static void grpc_rb_credentials_mark(void *p) {
} }
} }
static rb_data_type_t grpc_rb_credentials_data_type = {
"grpc_credentials",
{grpc_rb_credentials_mark, grpc_rb_credentials_free,
GRPC_RB_MEMSIZE_UNAVAILABLE},
NULL,
NULL,
RUBY_TYPED_FREE_IMMEDIATELY};
/* Allocates Credential instances. /* Allocates Credential instances.
Provides safe initial defaults for the instance fields. */ Provides safe initial defaults for the instance fields. */
static VALUE grpc_rb_credentials_alloc(VALUE cls) { static VALUE grpc_rb_credentials_alloc(VALUE cls) {
grpc_rb_credentials *wrapper = ALLOC(grpc_rb_credentials); grpc_rb_credentials *wrapper = ALLOC(grpc_rb_credentials);
wrapper->wrapped = NULL; wrapper->wrapped = NULL;
wrapper->mark = Qnil; wrapper->mark = Qnil;
return Data_Wrap_Struct(cls, grpc_rb_credentials_mark, return TypedData_Wrap_Struct(cls, &grpc_rb_credentials_data_type, wrapper);
grpc_rb_credentials_free, wrapper);
} }
/* Clones Credentials instances. /* Clones Credentials instances.
@ -113,8 +120,10 @@ static VALUE grpc_rb_credentials_init_copy(VALUE copy, VALUE orig) {
rb_raise(rb_eTypeError, "not a %s", rb_obj_classname(grpc_rb_cCredentials)); rb_raise(rb_eTypeError, "not a %s", rb_obj_classname(grpc_rb_cCredentials));
} }
Data_Get_Struct(orig, grpc_rb_credentials, orig_cred); TypedData_Get_Struct(orig, grpc_rb_credentials,
Data_Get_Struct(copy, grpc_rb_credentials, copy_cred); &grpc_rb_credentials_data_type, orig_cred);
TypedData_Get_Struct(copy, grpc_rb_credentials,
&grpc_rb_credentials_data_type, copy_cred);
/* use ruby's MEMCPY to make a byte-for-byte copy of the credentials /* use ruby's MEMCPY to make a byte-for-byte copy of the credentials
* wrapper object. */ * wrapper object. */
@ -136,8 +145,7 @@ static VALUE grpc_rb_default_credentials_create(VALUE cls) {
} }
wrapper->mark = Qnil; wrapper->mark = Qnil;
return Data_Wrap_Struct(cls, grpc_rb_credentials_mark, return TypedData_Wrap_Struct(cls, &grpc_rb_credentials_data_type, wrapper);
grpc_rb_credentials_free, wrapper);
} }
/* /*
@ -154,8 +162,7 @@ static VALUE grpc_rb_compute_engine_credentials_create(VALUE cls) {
} }
wrapper->mark = Qnil; wrapper->mark = Qnil;
return Data_Wrap_Struct(cls, grpc_rb_credentials_mark, return TypedData_Wrap_Struct(cls, &grpc_rb_credentials_data_type, wrapper);
grpc_rb_credentials_free, wrapper);
} }
/* /*
@ -169,8 +176,10 @@ static VALUE grpc_rb_composite_credentials_create(VALUE self, VALUE other) {
grpc_rb_credentials *other_wrapper = NULL; grpc_rb_credentials *other_wrapper = NULL;
grpc_rb_credentials *wrapper = NULL; grpc_rb_credentials *wrapper = NULL;
Data_Get_Struct(self, grpc_rb_credentials, self_wrapper); TypedData_Get_Struct(self, grpc_rb_credentials,
Data_Get_Struct(other, grpc_rb_credentials, other_wrapper); &grpc_rb_credentials_data_type, self_wrapper);
TypedData_Get_Struct(other, grpc_rb_credentials,
&grpc_rb_credentials_data_type, other_wrapper);
wrapper = ALLOC(grpc_rb_credentials); wrapper = ALLOC(grpc_rb_credentials);
wrapper->wrapped = grpc_composite_credentials_create(self_wrapper->wrapped, wrapper->wrapped = grpc_composite_credentials_create(self_wrapper->wrapped,
other_wrapper->wrapped); other_wrapper->wrapped);
@ -181,8 +190,8 @@ static VALUE grpc_rb_composite_credentials_create(VALUE self, VALUE other) {
} }
wrapper->mark = Qnil; wrapper->mark = Qnil;
return Data_Wrap_Struct(grpc_rb_cCredentials, grpc_rb_credentials_mark, return TypedData_Wrap_Struct(grpc_rb_cCredentials,
grpc_rb_credentials_free, wrapper); &grpc_rb_credentials_data_type, wrapper);
} }
/* The attribute used on the mark object to hold the pem_root_certs. */ /* The attribute used on the mark object to hold the pem_root_certs. */
@ -217,7 +226,8 @@ static VALUE grpc_rb_credentials_init(int argc, VALUE *argv, VALUE self) {
rb_scan_args(argc, argv, "12", &pem_root_certs, &pem_private_key, rb_scan_args(argc, argv, "12", &pem_root_certs, &pem_private_key,
&pem_cert_chain); &pem_cert_chain);
Data_Get_Struct(self, grpc_rb_credentials, wrapper); TypedData_Get_Struct(self, grpc_rb_credentials,
&grpc_rb_credentials_data_type, wrapper);
if (pem_root_certs == Qnil) { if (pem_root_certs == Qnil) {
rb_raise(rb_eRuntimeError, rb_raise(rb_eRuntimeError,
"could not create a credential: nil pem_root_certs"); "could not create a credential: nil pem_root_certs");
@ -228,8 +238,8 @@ static VALUE grpc_rb_credentials_init(int argc, VALUE *argv, VALUE self) {
} else { } else {
key_cert_pair.private_key = RSTRING_PTR(pem_private_key); key_cert_pair.private_key = RSTRING_PTR(pem_private_key);
key_cert_pair.cert_chain = RSTRING_PTR(pem_cert_chain); key_cert_pair.cert_chain = RSTRING_PTR(pem_cert_chain);
creds = grpc_ssl_credentials_create( creds = grpc_ssl_credentials_create(RSTRING_PTR(pem_root_certs),
RSTRING_PTR(pem_root_certs), &key_cert_pair); &key_cert_pair);
} }
if (creds == NULL) { if (creds == NULL) {
rb_raise(rb_eRuntimeError, "could not create a credentials, not sure why"); rb_raise(rb_eRuntimeError, "could not create a credentials, not sure why");
@ -253,8 +263,8 @@ void Init_grpc_credentials() {
rb_define_alloc_func(grpc_rb_cCredentials, grpc_rb_credentials_alloc); rb_define_alloc_func(grpc_rb_cCredentials, grpc_rb_credentials_alloc);
/* Provides a ruby constructor and support for dup/clone. */ /* Provides a ruby constructor and support for dup/clone. */
rb_define_method(grpc_rb_cCredentials, "initialize", rb_define_method(grpc_rb_cCredentials, "initialize", grpc_rb_credentials_init,
grpc_rb_credentials_init, -1); -1);
rb_define_method(grpc_rb_cCredentials, "initialize_copy", rb_define_method(grpc_rb_cCredentials, "initialize_copy",
grpc_rb_credentials_init_copy, 1); grpc_rb_credentials_init_copy, 1);
@ -277,6 +287,7 @@ void Init_grpc_credentials() {
/* Gets the wrapped grpc_credentials from the ruby wrapper */ /* Gets the wrapped grpc_credentials from the ruby wrapper */
grpc_credentials *grpc_rb_get_wrapped_credentials(VALUE v) { grpc_credentials *grpc_rb_get_wrapped_credentials(VALUE v) {
grpc_rb_credentials *wrapper = NULL; grpc_rb_credentials *wrapper = NULL;
Data_Get_Struct(v, grpc_rb_credentials, wrapper); TypedData_Get_Struct(v, grpc_rb_credentials, &grpc_rb_credentials_data_type,
wrapper);
return wrapper->wrapped; return wrapper->wrapped;
} }

@ -46,12 +46,15 @@
#include "rb_credentials.h" #include "rb_credentials.h"
#include "rb_server_credentials.h" #include "rb_server_credentials.h"
/* Define common vars and funcs declared in rb.h */
const RUBY_DATA_FUNC GC_NOT_MARKED = NULL;
const RUBY_DATA_FUNC GC_DONT_FREE = NULL;
static VALUE grpc_rb_cTimeVal = Qnil; static VALUE grpc_rb_cTimeVal = Qnil;
static rb_data_type_t grpc_rb_timespec_data_type = {
"gpr_timespec",
{GRPC_RB_GC_NOT_MARKED, GRPC_RB_GC_DONT_FREE, GRPC_RB_MEMSIZE_UNAVAILABLE},
NULL,
NULL,
RUBY_TYPED_FREE_IMMEDIATELY};
/* Alloc func that blocks allocation of a given object by raising an /* Alloc func that blocks allocation of a given object by raising an
* exception. */ * exception. */
VALUE grpc_rb_cannot_alloc(VALUE cls) { VALUE grpc_rb_cannot_alloc(VALUE cls) {
@ -97,7 +100,8 @@ gpr_timespec grpc_rb_time_timeval(VALUE time, int interval) {
switch (TYPE(time)) { switch (TYPE(time)) {
case T_DATA: case T_DATA:
if (CLASS_OF(time) == grpc_rb_cTimeVal) { if (CLASS_OF(time) == grpc_rb_cTimeVal) {
Data_Get_Struct(time, gpr_timespec, time_const); TypedData_Get_Struct(time, gpr_timespec, &grpc_rb_timespec_data_type,
time_const);
t = *time_const; t = *time_const;
} else if (CLASS_OF(time) == rb_cTime) { } else if (CLASS_OF(time) == rb_cTime) {
t.tv_sec = NUM2INT(rb_funcall(time, id_tv_sec, 0)); t.tv_sec = NUM2INT(rb_funcall(time, id_tv_sec, 0));
@ -201,7 +205,8 @@ static ID id_to_s;
/* Converts a wrapped time constant to a standard time. */ /* Converts a wrapped time constant to a standard time. */
static VALUE grpc_rb_time_val_to_time(VALUE self) { static VALUE grpc_rb_time_val_to_time(VALUE self) {
gpr_timespec *time_const = NULL; gpr_timespec *time_const = NULL;
Data_Get_Struct(self, gpr_timespec, time_const); TypedData_Get_Struct(self, gpr_timespec, &grpc_rb_timespec_data_type,
time_const);
return rb_funcall(rb_cTime, id_at, 2, INT2NUM(time_const->tv_sec), return rb_funcall(rb_cTime, id_at, 2, INT2NUM(time_const->tv_sec),
INT2NUM(time_const->tv_nsec)); INT2NUM(time_const->tv_nsec));
} }
@ -222,17 +227,17 @@ static void Init_grpc_time_consts() {
rb_define_module_under(grpc_rb_mGrpcCore, "TimeConsts"); rb_define_module_under(grpc_rb_mGrpcCore, "TimeConsts");
grpc_rb_cTimeVal = grpc_rb_cTimeVal =
rb_define_class_under(grpc_rb_mGrpcCore, "TimeSpec", rb_cObject); rb_define_class_under(grpc_rb_mGrpcCore, "TimeSpec", rb_cObject);
rb_define_const(grpc_rb_mTimeConsts, "ZERO", rb_define_const(
Data_Wrap_Struct(grpc_rb_cTimeVal, grpc_rb_mTimeConsts, "ZERO",
GC_NOT_MARKED, GC_DONT_FREE, TypedData_Wrap_Struct(grpc_rb_cTimeVal, &grpc_rb_timespec_data_type,
(void *)&gpr_time_0)); (void *)&gpr_time_0));
rb_define_const(grpc_rb_mTimeConsts, "INFINITE_FUTURE", rb_define_const(
Data_Wrap_Struct(grpc_rb_cTimeVal, grpc_rb_mTimeConsts, "INFINITE_FUTURE",
GC_NOT_MARKED, GC_DONT_FREE, TypedData_Wrap_Struct(grpc_rb_cTimeVal, &grpc_rb_timespec_data_type,
(void *)&gpr_inf_future)); (void *)&gpr_inf_future));
rb_define_const(grpc_rb_mTimeConsts, "INFINITE_PAST", rb_define_const(
Data_Wrap_Struct(grpc_rb_cTimeVal, grpc_rb_mTimeConsts, "INFINITE_PAST",
GC_NOT_MARKED, GC_DONT_FREE, TypedData_Wrap_Struct(grpc_rb_cTimeVal, &grpc_rb_timespec_data_type,
(void *)&gpr_inf_past)); (void *)&gpr_inf_past));
rb_define_method(grpc_rb_cTimeVal, "to_time", grpc_rb_time_val_to_time, 0); rb_define_method(grpc_rb_cTimeVal, "to_time", grpc_rb_time_val_to_time, 0);
rb_define_method(grpc_rb_cTimeVal, "inspect", grpc_rb_time_val_inspect, 0); rb_define_method(grpc_rb_cTimeVal, "inspect", grpc_rb_time_val_inspect, 0);

@ -58,12 +58,16 @@ extern VALUE sym_metadata;
/* GC_NOT_MARKED is used in calls to Data_Wrap_Struct to indicate that the /* GC_NOT_MARKED is used in calls to Data_Wrap_Struct to indicate that the
wrapped struct does not need to participate in ruby gc. */ wrapped struct does not need to participate in ruby gc. */
extern const RUBY_DATA_FUNC GC_NOT_MARKED; #define GRPC_RB_GC_NOT_MARKED (RUBY_DATA_FUNC)(NULL)
/* GC_DONT_FREED is used in calls to Data_Wrap_Struct to indicate that the /* GC_DONT_FREED is used in calls to Data_Wrap_Struct to indicate that the
wrapped struct should not be freed the wrapped ruby object is released by wrapped struct should not be freed the wrapped ruby object is released by
the garbage collector. */ the garbage collector. */
extern const RUBY_DATA_FUNC GC_DONT_FREE; #define GRPC_RB_GC_DONT_FREE (RUBY_DATA_FUNC)(NULL)
/* GRPC_RB_MEMSIZE_UNAVAILABLE is used in rb_data_type_t to indicate that the
* number of bytes used by the wrapped struct is not available. */
#define GRPC_RB_MEMSIZE_UNAVAILABLE (size_t (*)(const void*))(NULL)
/* A ruby object alloc func that fails by raising an exception. */ /* A ruby object alloc func that fails by raising an exception. */
VALUE grpc_rb_cannot_alloc(VALUE cls); VALUE grpc_rb_cannot_alloc(VALUE cls);

@ -88,13 +88,23 @@ static void grpc_rb_server_mark(void *p) {
} }
} }
static const rb_data_type_t grpc_rb_server_data_type = {
"grpc_server",
{grpc_rb_server_mark, grpc_rb_server_free, GRPC_RB_MEMSIZE_UNAVAILABLE},
NULL,
NULL,
/* It is unsafe to specify RUBY_TYPED_FREE_IMMEDIATELY because the free function would block
* and we might want to unlock GVL
* TODO(yugui) Unlock GVL?
*/
0};
/* Allocates grpc_rb_server instances. */ /* Allocates grpc_rb_server instances. */
static VALUE grpc_rb_server_alloc(VALUE cls) { static VALUE grpc_rb_server_alloc(VALUE cls) {
grpc_rb_server *wrapper = ALLOC(grpc_rb_server); grpc_rb_server *wrapper = ALLOC(grpc_rb_server);
wrapper->wrapped = NULL; wrapper->wrapped = NULL;
wrapper->mark = Qnil; wrapper->mark = Qnil;
return Data_Wrap_Struct(cls, grpc_rb_server_mark, grpc_rb_server_free, return TypedData_Wrap_Struct(cls, &grpc_rb_server_data_type, wrapper);
wrapper);
} }
/* /*
@ -110,7 +120,8 @@ static VALUE grpc_rb_server_init(VALUE self, VALUE cqueue, VALUE channel_args) {
grpc_channel_args args; grpc_channel_args args;
MEMZERO(&args, grpc_channel_args, 1); MEMZERO(&args, grpc_channel_args, 1);
cq = grpc_rb_get_wrapped_completion_queue(cqueue); cq = grpc_rb_get_wrapped_completion_queue(cqueue);
Data_Get_Struct(self, grpc_rb_server, wrapper); TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type,
wrapper);
grpc_rb_hash_convert_to_channel_args(channel_args, &args); grpc_rb_hash_convert_to_channel_args(channel_args, &args);
srv = grpc_server_create(cq, &args); srv = grpc_server_create(cq, &args);
@ -146,8 +157,10 @@ static VALUE grpc_rb_server_init_copy(VALUE copy, VALUE orig) {
rb_raise(rb_eTypeError, "not a %s", rb_obj_classname(grpc_rb_cServer)); rb_raise(rb_eTypeError, "not a %s", rb_obj_classname(grpc_rb_cServer));
} }
Data_Get_Struct(orig, grpc_rb_server, orig_srv); TypedData_Get_Struct(orig, grpc_rb_server, &grpc_rb_server_data_type,
Data_Get_Struct(copy, grpc_rb_server, copy_srv); orig_srv);
TypedData_Get_Struct(copy, grpc_rb_server, &grpc_rb_server_data_type,
copy_srv);
/* use ruby's MEMCPY to make a byte-for-byte copy of the server wrapper /* use ruby's MEMCPY to make a byte-for-byte copy of the server wrapper
object. */ object. */
@ -194,7 +207,7 @@ static VALUE grpc_rb_server_request_call(VALUE self, VALUE cqueue,
grpc_call_error err; grpc_call_error err;
request_call_stack st; request_call_stack st;
VALUE result; VALUE result;
Data_Get_Struct(self, grpc_rb_server, s); TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
if (s->wrapped == NULL) { if (s->wrapped == NULL) {
rb_raise(rb_eRuntimeError, "closed!"); rb_raise(rb_eRuntimeError, "closed!");
return Qnil; return Qnil;
@ -245,7 +258,7 @@ static VALUE grpc_rb_server_request_call(VALUE self, VALUE cqueue,
static VALUE grpc_rb_server_start(VALUE self) { static VALUE grpc_rb_server_start(VALUE self) {
grpc_rb_server *s = NULL; grpc_rb_server *s = NULL;
Data_Get_Struct(self, grpc_rb_server, s); TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
if (s->wrapped == NULL) { if (s->wrapped == NULL) {
rb_raise(rb_eRuntimeError, "closed!"); rb_raise(rb_eRuntimeError, "closed!");
} else { } else {
@ -256,7 +269,7 @@ static VALUE grpc_rb_server_start(VALUE self) {
static VALUE grpc_rb_server_destroy(VALUE self) { static VALUE grpc_rb_server_destroy(VALUE self) {
grpc_rb_server *s = NULL; grpc_rb_server *s = NULL;
Data_Get_Struct(self, grpc_rb_server, s); TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
if (s->wrapped != NULL) { if (s->wrapped != NULL) {
grpc_server_shutdown(s->wrapped); grpc_server_shutdown(s->wrapped);
grpc_server_destroy(s->wrapped); grpc_server_destroy(s->wrapped);
@ -288,7 +301,7 @@ static VALUE grpc_rb_server_add_http2_port(int argc, VALUE *argv, VALUE self) {
/* "11" == 1 mandatory args, 1 (rb_creds) is optional */ /* "11" == 1 mandatory args, 1 (rb_creds) is optional */
rb_scan_args(argc, argv, "11", &port, &rb_creds); rb_scan_args(argc, argv, "11", &port, &rb_creds);
Data_Get_Struct(self, grpc_rb_server, s); TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
if (s->wrapped == NULL) { if (s->wrapped == NULL) {
rb_raise(rb_eRuntimeError, "closed!"); rb_raise(rb_eRuntimeError, "closed!");
return Qnil; return Qnil;
@ -340,6 +353,6 @@ void Init_grpc_server() {
/* Gets the wrapped server from the ruby wrapper */ /* Gets the wrapped server from the ruby wrapper */
grpc_server *grpc_rb_get_wrapped_server(VALUE v) { grpc_server *grpc_rb_get_wrapped_server(VALUE v) {
grpc_rb_server *wrapper = NULL; grpc_rb_server *wrapper = NULL;
Data_Get_Struct(v, grpc_rb_server, wrapper); TypedData_Get_Struct(v, grpc_rb_server, &grpc_rb_server_data_type, wrapper);
return wrapper->wrapped; return wrapper->wrapped;
} }

@ -86,6 +86,14 @@ static void grpc_rb_server_credentials_mark(void *p) {
} }
} }
static const rb_data_type_t grpc_rb_server_credentials_data_type = {
"grpc_server_credentials",
{grpc_rb_server_credentials_mark, grpc_rb_server_credentials_free,
GRPC_RB_MEMSIZE_UNAVAILABLE},
NULL, NULL,
RUBY_TYPED_FREE_IMMEDIATELY
};
/* Allocates ServerCredential instances. /* Allocates ServerCredential instances.
Provides safe initial defaults for the instance fields. */ Provides safe initial defaults for the instance fields. */
@ -93,8 +101,8 @@ static VALUE grpc_rb_server_credentials_alloc(VALUE cls) {
grpc_rb_server_credentials *wrapper = ALLOC(grpc_rb_server_credentials); grpc_rb_server_credentials *wrapper = ALLOC(grpc_rb_server_credentials);
wrapper->wrapped = NULL; wrapper->wrapped = NULL;
wrapper->mark = Qnil; wrapper->mark = Qnil;
return Data_Wrap_Struct(cls, grpc_rb_server_credentials_mark, return TypedData_Wrap_Struct(cls, &grpc_rb_server_credentials_data_type,
grpc_rb_server_credentials_free, wrapper); wrapper);
} }
/* Clones ServerCredentials instances. /* Clones ServerCredentials instances.
@ -116,8 +124,10 @@ static VALUE grpc_rb_server_credentials_init_copy(VALUE copy, VALUE orig) {
rb_obj_classname(grpc_rb_cServerCredentials)); rb_obj_classname(grpc_rb_cServerCredentials));
} }
Data_Get_Struct(orig, grpc_rb_server_credentials, orig_ch); TypedData_Get_Struct(orig, grpc_rb_server_credentials,
Data_Get_Struct(copy, grpc_rb_server_credentials, copy_ch); &grpc_rb_server_credentials_data_type, orig_ch);
TypedData_Get_Struct(copy, grpc_rb_server_credentials,
&grpc_rb_server_credentials_data_type, copy_ch);
/* use ruby's MEMCPY to make a byte-for-byte copy of the server_credentials /* use ruby's MEMCPY to make a byte-for-byte copy of the server_credentials
wrapper object. */ wrapper object. */
@ -153,7 +163,8 @@ static VALUE grpc_rb_server_credentials_init(VALUE self, VALUE pem_root_certs,
grpc_rb_server_credentials *wrapper = NULL; grpc_rb_server_credentials *wrapper = NULL;
grpc_server_credentials *creds = NULL; grpc_server_credentials *creds = NULL;
grpc_ssl_pem_key_cert_pair key_cert_pair = {NULL, NULL}; grpc_ssl_pem_key_cert_pair key_cert_pair = {NULL, NULL};
Data_Get_Struct(self, grpc_rb_server_credentials, wrapper); TypedData_Get_Struct(self, grpc_rb_server_credentials,
&grpc_rb_server_credentials_data_type, wrapper);
if (pem_cert_chain == Qnil) { if (pem_cert_chain == Qnil) {
rb_raise(rb_eRuntimeError, rb_raise(rb_eRuntimeError,
"could not create a server credential: nil pem_cert_chain"); "could not create a server credential: nil pem_cert_chain");
@ -206,6 +217,7 @@ void Init_grpc_server_credentials() {
/* Gets the wrapped grpc_server_credentials from the ruby wrapper */ /* Gets the wrapped grpc_server_credentials from the ruby wrapper */
grpc_server_credentials *grpc_rb_get_wrapped_server_credentials(VALUE v) { grpc_server_credentials *grpc_rb_get_wrapped_server_credentials(VALUE v) {
grpc_rb_server_credentials *wrapper = NULL; grpc_rb_server_credentials *wrapper = NULL;
Data_Get_Struct(v, grpc_rb_server_credentials, wrapper); TypedData_Get_Struct(v, grpc_rb_server_credentials,
&grpc_rb_server_credentials_data_type, wrapper);
return wrapper->wrapped; return wrapper->wrapped;
} }

Loading…
Cancel
Save