From d441c2e5b3dcdd2a0eebeeb9fb580da4a875187c Mon Sep 17 00:00:00 2001
From: Yuki Yugui Sonoda <yugui@yugui.jp>
Date: Sat, 11 Apr 2015 15:33:58 +0900
Subject: [PATCH] Use TypedData for GRPC::Core::TimeSpec

---
 src/ruby/ext/grpc/rb_grpc.c | 37 +++++++++++++++++++++++--------------
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/src/ruby/ext/grpc/rb_grpc.c b/src/ruby/ext/grpc/rb_grpc.c
index e721a9b3e7..b431636c75 100644
--- a/src/ruby/ext/grpc/rb_grpc.c
+++ b/src/ruby/ext/grpc/rb_grpc.c
@@ -48,6 +48,13 @@
 
 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
  * exception. */
 VALUE grpc_rb_cannot_alloc(VALUE cls) {
@@ -93,7 +100,8 @@ gpr_timespec grpc_rb_time_timeval(VALUE time, int interval) {
   switch (TYPE(time)) {
     case T_DATA:
       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;
       } else if (CLASS_OF(time) == rb_cTime) {
         t.tv_sec = NUM2INT(rb_funcall(time, id_tv_sec, 0));
@@ -197,7 +205,8 @@ static ID id_to_s;
 /* Converts a wrapped time constant to a standard time. */
 VALUE grpc_rb_time_val_to_time(VALUE self) {
   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),
                     INT2NUM(time_const->tv_nsec));
 }
@@ -218,18 +227,18 @@ void Init_grpc_time_consts() {
       rb_define_module_under(grpc_rb_mGrpcCore, "TimeConsts");
   grpc_rb_cTimeVal =
       rb_define_class_under(grpc_rb_mGrpcCore, "TimeSpec", rb_cObject);
-  rb_define_const(grpc_rb_mTimeConsts, "ZERO",
-                  Data_Wrap_Struct(grpc_rb_cTimeVal,
-                                   GRPC_RB_GC_NOT_MARKED, GRPC_RB_GC_DONT_FREE,
-                                   (void *)&gpr_time_0));
-  rb_define_const(grpc_rb_mTimeConsts, "INFINITE_FUTURE",
-                  Data_Wrap_Struct(grpc_rb_cTimeVal,
-                                   GRPC_RB_GC_NOT_MARKED, GRPC_RB_GC_DONT_FREE,
-                                   (void *)&gpr_inf_future));
-  rb_define_const(grpc_rb_mTimeConsts, "INFINITE_PAST",
-                  Data_Wrap_Struct(grpc_rb_cTimeVal,
-                                   GRPC_RB_GC_NOT_MARKED, GRPC_RB_GC_DONT_FREE,
-                                   (void *)&gpr_inf_past));
+  rb_define_const(
+      grpc_rb_mTimeConsts, "ZERO",
+      TypedData_Wrap_Struct(grpc_rb_cTimeVal, &grpc_rb_timespec_data_type,
+                            (void *)&gpr_time_0));
+  rb_define_const(
+      grpc_rb_mTimeConsts, "INFINITE_FUTURE",
+      TypedData_Wrap_Struct(grpc_rb_cTimeVal, &grpc_rb_timespec_data_type,
+                            (void *)&gpr_inf_future));
+  rb_define_const(
+      grpc_rb_mTimeConsts, "INFINITE_PAST",
+      TypedData_Wrap_Struct(grpc_rb_cTimeVal, &grpc_rb_timespec_data_type,
+                            (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, "inspect", grpc_rb_time_val_inspect, 0);
   rb_define_method(grpc_rb_cTimeVal, "to_s", grpc_rb_time_val_to_s, 0);
-- 
GitLab