grpc 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -0
  3. data/.rubocop_todo.yml +12 -20
  4. data/CHANGELOG.md +11 -0
  5. data/Rakefile +1 -0
  6. data/bin/apis/pubsub_demo.rb +3 -6
  7. data/bin/interop/interop_client.rb +43 -3
  8. data/bin/interop/interop_server.rb +1 -1
  9. data/bin/math_server.rb +1 -1
  10. data/bin/noproto_server.rb +1 -1
  11. data/ext/grpc/rb_byte_buffer.c +15 -189
  12. data/ext/grpc/rb_byte_buffer.h +4 -12
  13. data/ext/grpc/rb_call.c +514 -307
  14. data/ext/grpc/rb_call.h +4 -4
  15. data/ext/grpc/rb_channel.c +58 -34
  16. data/ext/grpc/rb_channel.h +0 -3
  17. data/ext/grpc/rb_channel_args.c +13 -4
  18. data/ext/grpc/rb_completion_queue.c +50 -23
  19. data/ext/grpc/rb_completion_queue.h +7 -3
  20. data/ext/grpc/rb_credentials.c +40 -28
  21. data/ext/grpc/rb_credentials.h +0 -4
  22. data/ext/grpc/rb_grpc.c +86 -67
  23. data/ext/grpc/rb_grpc.h +20 -10
  24. data/ext/grpc/rb_server.c +119 -26
  25. data/ext/grpc/rb_server.h +0 -4
  26. data/ext/grpc/rb_server_credentials.c +29 -16
  27. data/ext/grpc/rb_server_credentials.h +0 -4
  28. data/grpc.gemspec +11 -8
  29. data/lib/grpc.rb +1 -1
  30. data/lib/grpc/errors.rb +8 -7
  31. data/lib/grpc/generic/active_call.rb +104 -171
  32. data/lib/grpc/generic/bidi_call.rb +32 -60
  33. data/lib/grpc/generic/client_stub.rb +42 -31
  34. data/lib/grpc/generic/rpc_desc.rb +7 -12
  35. data/lib/grpc/generic/rpc_server.rb +253 -170
  36. data/lib/grpc/{core/event.rb → notifier.rb} +25 -9
  37. data/lib/grpc/version.rb +1 -1
  38. data/spec/call_spec.rb +23 -40
  39. data/spec/channel_spec.rb +11 -20
  40. data/spec/client_server_spec.rb +193 -175
  41. data/spec/credentials_spec.rb +2 -2
  42. data/spec/generic/active_call_spec.rb +59 -85
  43. data/spec/generic/client_stub_spec.rb +46 -64
  44. data/spec/generic/rpc_desc_spec.rb +50 -80
  45. data/spec/generic/rpc_server_pool_spec.rb +2 -3
  46. data/spec/generic/rpc_server_spec.rb +158 -29
  47. data/spec/server_spec.rb +1 -1
  48. data/spec/spec_helper.rb +8 -4
  49. metadata +27 -37
  50. data/ext/grpc/rb_event.c +0 -361
  51. data/ext/grpc/rb_event.h +0 -53
  52. data/ext/grpc/rb_metadata.c +0 -215
  53. data/ext/grpc/rb_metadata.h +0 -53
  54. data/spec/alloc_spec.rb +0 -44
  55. data/spec/byte_buffer_spec.rb +0 -67
  56. data/spec/event_spec.rb +0 -53
  57. data/spec/metadata_spec.rb +0 -64
@@ -46,12 +46,12 @@ VALUE grpc_rb_wrap_call(grpc_call* c);
46
46
  /* Provides the details of an call error */
47
47
  const char* grpc_call_error_detail_of(grpc_call_error err);
48
48
 
49
- /* rb_cCall is the Call class whose instances proxy grpc_call. */
50
- extern VALUE rb_cCall;
49
+ /* Converts a metadata array to a hash. */
50
+ VALUE grpc_rb_md_ary_to_h(grpc_metadata_array *md_ary);
51
51
 
52
- /* rb_cCallError is the ruby class of the exception thrown during call
52
+ /* grpc_rb_eCallError is the ruby class of the exception thrown during call
53
53
  operations. */
54
- extern VALUE rb_eCallError;
54
+ extern VALUE grpc_rb_eCallError;
55
55
 
56
56
  /* Initializes the Call class. */
57
57
  void Init_grpc_call();
@@ -49,12 +49,20 @@
49
49
  static ID id_channel;
50
50
 
51
51
  /* id_target is the name of the hidden ivar that preserves a reference to the
52
- * target string used to create the call, preserved so that is does not get
52
+ * target string used to create the call, preserved so that it does not get
53
53
  * GCed before the channel */
54
54
  static ID id_target;
55
55
 
56
+ /* id_cqueue is the name of the hidden ivar that preserves a reference to the
57
+ * completion queue used to create the call, preserved so that it does not get
58
+ * GCed before the channel */
59
+ static ID id_cqueue;
60
+
61
+ /* grpc_rb_cChannel is the ruby class that proxies grpc_channel. */
62
+ static VALUE grpc_rb_cChannel = Qnil;
63
+
56
64
  /* Used during the conversion of a hash to channel args during channel setup */
57
- static VALUE rb_cChannelArgs;
65
+ static VALUE grpc_rb_cChannelArgs;
58
66
 
59
67
  /* grpc_rb_channel wraps a grpc_channel. It provides a peer ruby object,
60
68
  * 'mark' to minimize copying when a channel is created from ruby. */
@@ -97,13 +105,19 @@ static void grpc_rb_channel_mark(void *p) {
97
105
  }
98
106
  }
99
107
 
108
+ static rb_data_type_t grpc_channel_data_type = {
109
+ "grpc_channel",
110
+ {grpc_rb_channel_mark, grpc_rb_channel_free, GRPC_RB_MEMSIZE_UNAVAILABLE},
111
+ NULL, NULL,
112
+ RUBY_TYPED_FREE_IMMEDIATELY
113
+ };
114
+
100
115
  /* Allocates grpc_rb_channel instances. */
101
116
  static VALUE grpc_rb_channel_alloc(VALUE cls) {
102
117
  grpc_rb_channel *wrapper = ALLOC(grpc_rb_channel);
103
118
  wrapper->wrapped = NULL;
104
119
  wrapper->mark = Qnil;
105
- return Data_Wrap_Struct(cls, grpc_rb_channel_mark, grpc_rb_channel_free,
106
- wrapper);
120
+ return TypedData_Wrap_Struct(cls, &grpc_channel_data_type, wrapper);
107
121
  }
108
122
 
109
123
  /*
@@ -127,7 +141,7 @@ static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) {
127
141
  /* "21" == 2 mandatory args, 1 (credentials) is optional */
128
142
  rb_scan_args(argc, argv, "21", &target, &channel_args, &credentials);
129
143
 
130
- Data_Get_Struct(self, grpc_rb_channel, wrapper);
144
+ TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
131
145
  target_chars = StringValueCStr(target);
132
146
  grpc_rb_hash_convert_to_channel_args(channel_args, &args);
133
147
  if (credentials == Qnil) {
@@ -142,6 +156,7 @@ static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) {
142
156
  if (ch == NULL) {
143
157
  rb_raise(rb_eRuntimeError, "could not create an rpc channel to target:%s",
144
158
  target_chars);
159
+ return Qnil;
145
160
  }
146
161
  rb_ivar_set(self, id_target, target);
147
162
  wrapper->wrapped = ch;
@@ -163,11 +178,12 @@ static VALUE grpc_rb_channel_init_copy(VALUE copy, VALUE orig) {
163
178
  /* Raise an error if orig is not a channel object or a subclass. */
164
179
  if (TYPE(orig) != T_DATA ||
165
180
  RDATA(orig)->dfree != (RUBY_DATA_FUNC)grpc_rb_channel_free) {
166
- rb_raise(rb_eTypeError, "not a %s", rb_obj_classname(rb_cChannel));
181
+ rb_raise(rb_eTypeError, "not a %s", rb_obj_classname(grpc_rb_cChannel));
182
+ return Qnil;
167
183
  }
168
184
 
169
- Data_Get_Struct(orig, grpc_rb_channel, orig_ch);
170
- Data_Get_Struct(copy, grpc_rb_channel, copy_ch);
185
+ TypedData_Get_Struct(orig, grpc_rb_channel, &grpc_channel_data_type, orig_ch);
186
+ TypedData_Get_Struct(copy, grpc_rb_channel, &grpc_channel_data_type, copy_ch);
171
187
 
172
188
  /* use ruby's MEMCPY to make a byte-for-byte copy of the channel wrapper
173
189
  * object. */
@@ -177,34 +193,42 @@ static VALUE grpc_rb_channel_init_copy(VALUE copy, VALUE orig) {
177
193
 
178
194
  /* Create a call given a grpc_channel, in order to call method. The request
179
195
  is not sent until grpc_call_invoke is called. */
180
- static VALUE grpc_rb_channel_create_call(VALUE self, VALUE method, VALUE host,
181
- VALUE deadline) {
196
+ static VALUE grpc_rb_channel_create_call(VALUE self, VALUE cqueue, VALUE method,
197
+ VALUE host, VALUE deadline) {
182
198
  VALUE res = Qnil;
183
199
  grpc_rb_channel *wrapper = NULL;
184
- grpc_channel *ch = NULL;
185
200
  grpc_call *call = NULL;
201
+ grpc_channel *ch = NULL;
202
+ grpc_completion_queue *cq = NULL;
186
203
  char *method_chars = StringValueCStr(method);
187
204
  char *host_chars = StringValueCStr(host);
188
205
 
189
- Data_Get_Struct(self, grpc_rb_channel, wrapper);
206
+ cq = grpc_rb_get_wrapped_completion_queue(cqueue);
207
+ TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
190
208
  ch = wrapper->wrapped;
191
209
  if (ch == NULL) {
192
210
  rb_raise(rb_eRuntimeError, "closed!");
211
+ return Qnil;
193
212
  }
194
213
 
195
214
  call =
196
- grpc_channel_create_call_old(ch, method_chars, host_chars,
197
- grpc_rb_time_timeval(deadline,
198
- /* absolute time */ 0));
215
+ grpc_channel_create_call(ch, cq, method_chars, host_chars,
216
+ grpc_rb_time_timeval(deadline,
217
+ /* absolute time */ 0));
199
218
  if (call == NULL) {
200
219
  rb_raise(rb_eRuntimeError, "cannot create call with method %s",
201
220
  method_chars);
221
+ return Qnil;
202
222
  }
203
223
  res = grpc_rb_wrap_call(call);
204
224
 
205
- /* Make this channel an instance attribute of the call so that is is not GCed
225
+ /* Make this channel an instance attribute of the call so that it is not GCed
206
226
  * before the call. */
207
227
  rb_ivar_set(res, id_channel, self);
228
+
229
+ /* Make the completion queue an instance attribute of the call so that it is
230
+ * not GCed before the call. */
231
+ rb_ivar_set(res, id_cqueue, cqueue);
208
232
  return res;
209
233
  }
210
234
 
@@ -213,7 +237,7 @@ static VALUE grpc_rb_channel_destroy(VALUE self) {
213
237
  grpc_rb_channel *wrapper = NULL;
214
238
  grpc_channel *ch = NULL;
215
239
 
216
- Data_Get_Struct(self, grpc_rb_channel, wrapper);
240
+ TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
217
241
  ch = wrapper->wrapped;
218
242
  if (ch != NULL) {
219
243
  grpc_channel_destroy(ch);
@@ -224,41 +248,41 @@ static VALUE grpc_rb_channel_destroy(VALUE self) {
224
248
  return Qnil;
225
249
  }
226
250
 
227
- /* rb_cChannel is the ruby class that proxies grpc_channel. */
228
- VALUE rb_cChannel = Qnil;
229
-
230
251
  void Init_grpc_channel() {
231
- rb_cChannelArgs = rb_define_class("TmpChannelArgs", rb_cObject);
232
- rb_cChannel = rb_define_class_under(rb_mGrpcCore, "Channel", rb_cObject);
252
+ grpc_rb_cChannelArgs = rb_define_class("TmpChannelArgs", rb_cObject);
253
+ grpc_rb_cChannel =
254
+ rb_define_class_under(grpc_rb_mGrpcCore, "Channel", rb_cObject);
233
255
 
234
256
  /* Allocates an object managed by the ruby runtime */
235
- rb_define_alloc_func(rb_cChannel, grpc_rb_channel_alloc);
257
+ rb_define_alloc_func(grpc_rb_cChannel, grpc_rb_channel_alloc);
236
258
 
237
259
  /* Provides a ruby constructor and support for dup/clone. */
238
- rb_define_method(rb_cChannel, "initialize", grpc_rb_channel_init, -1);
239
- rb_define_method(rb_cChannel, "initialize_copy", grpc_rb_channel_init_copy,
240
- 1);
260
+ rb_define_method(grpc_rb_cChannel, "initialize", grpc_rb_channel_init, -1);
261
+ rb_define_method(grpc_rb_cChannel, "initialize_copy",
262
+ grpc_rb_channel_init_copy, 1);
241
263
 
242
264
  /* Add ruby analogues of the Channel methods. */
243
- rb_define_method(rb_cChannel, "create_call", grpc_rb_channel_create_call, 3);
244
- rb_define_method(rb_cChannel, "destroy", grpc_rb_channel_destroy, 0);
245
- rb_define_alias(rb_cChannel, "close", "destroy");
265
+ rb_define_method(grpc_rb_cChannel, "create_call",
266
+ grpc_rb_channel_create_call, 4);
267
+ rb_define_method(grpc_rb_cChannel, "destroy", grpc_rb_channel_destroy, 0);
268
+ rb_define_alias(grpc_rb_cChannel, "close", "destroy");
246
269
 
247
270
  id_channel = rb_intern("__channel");
271
+ id_cqueue = rb_intern("__cqueue");
248
272
  id_target = rb_intern("__target");
249
- rb_define_const(rb_cChannel, "SSL_TARGET",
273
+ rb_define_const(grpc_rb_cChannel, "SSL_TARGET",
250
274
  ID2SYM(rb_intern(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)));
251
- rb_define_const(rb_cChannel, "ENABLE_CENSUS",
275
+ rb_define_const(grpc_rb_cChannel, "ENABLE_CENSUS",
252
276
  ID2SYM(rb_intern(GRPC_ARG_ENABLE_CENSUS)));
253
- rb_define_const(rb_cChannel, "MAX_CONCURRENT_STREAMS",
277
+ rb_define_const(grpc_rb_cChannel, "MAX_CONCURRENT_STREAMS",
254
278
  ID2SYM(rb_intern(GRPC_ARG_MAX_CONCURRENT_STREAMS)));
255
- rb_define_const(rb_cChannel, "MAX_MESSAGE_LENGTH",
279
+ rb_define_const(grpc_rb_cChannel, "MAX_MESSAGE_LENGTH",
256
280
  ID2SYM(rb_intern(GRPC_ARG_MAX_MESSAGE_LENGTH)));
257
281
  }
258
282
 
259
283
  /* Gets the wrapped channel from the ruby wrapper */
260
284
  grpc_channel *grpc_rb_get_wrapped_channel(VALUE v) {
261
285
  grpc_rb_channel *wrapper = NULL;
262
- Data_Get_Struct(v, grpc_rb_channel, wrapper);
286
+ TypedData_Get_Struct(v, grpc_rb_channel, &grpc_channel_data_type, wrapper);
263
287
  return wrapper->wrapped;
264
288
  }
@@ -37,9 +37,6 @@
37
37
  #include <ruby.h>
38
38
  #include <grpc/grpc.h>
39
39
 
40
- /* rb_cChannel is the Channel class whose instances proxy grpc_channel. */
41
- extern VALUE rb_cChannel;
42
-
43
40
  /* Initializes the Channel class. */
44
41
  void Init_grpc_channel();
45
42
 
@@ -38,6 +38,13 @@
38
38
 
39
39
  #include "rb_grpc.h"
40
40
 
41
+ static rb_data_type_t grpc_rb_channel_args_data_type = {
42
+ "grpc_channel_args",
43
+ {GRPC_RB_GC_NOT_MARKED, GRPC_RB_GC_DONT_FREE, GRPC_RB_MEMSIZE_UNAVAILABLE},
44
+ NULL, NULL,
45
+ RUBY_TYPED_FREE_IMMEDIATELY
46
+ };
47
+
41
48
  /* A callback the processes the hash key values in channel_args hash */
42
49
  static int grpc_rb_channel_create_in_process_add_args_hash_cb(VALUE key,
43
50
  VALUE val,
@@ -60,7 +67,8 @@ static int grpc_rb_channel_create_in_process_add_args_hash_cb(VALUE key,
60
67
  return ST_STOP;
61
68
  }
62
69
 
63
- Data_Get_Struct(args_obj, grpc_channel_args, args);
70
+ TypedData_Get_Struct(args_obj, grpc_channel_args,
71
+ &grpc_rb_channel_args_data_type, args);
64
72
  if (args->num_args <= 0) {
65
73
  rb_raise(rb_eRuntimeError, "hash_cb bug: num_args is %lu for key:%s",
66
74
  args->num_args, StringValueCStr(key));
@@ -109,7 +117,7 @@ typedef struct channel_convert_params {
109
117
 
110
118
  static VALUE grpc_rb_hash_convert_to_channel_args0(VALUE as_value) {
111
119
  ID id_size = rb_intern("size");
112
- VALUE rb_cChannelArgs = rb_define_class("TmpChannelArgs", rb_cObject);
120
+ VALUE grpc_rb_cChannelArgs = rb_define_class("TmpChannelArgs", rb_cObject);
113
121
  channel_convert_params* params = (channel_convert_params*)as_value;
114
122
  size_t num_args = 0;
115
123
 
@@ -126,8 +134,9 @@ static VALUE grpc_rb_hash_convert_to_channel_args0(VALUE as_value) {
126
134
  MEMZERO(params->dst->args, grpc_arg, num_args);
127
135
  rb_hash_foreach(params->src_hash,
128
136
  grpc_rb_channel_create_in_process_add_args_hash_cb,
129
- Data_Wrap_Struct(rb_cChannelArgs, GC_NOT_MARKED,
130
- GC_DONT_FREE, params->dst));
137
+ TypedData_Wrap_Struct(grpc_rb_cChannelArgs,
138
+ &grpc_rb_channel_args_data_type,
139
+ params->dst));
131
140
  /* reset num_args as grpc_rb_channel_create_in_process_add_args_hash_cb
132
141
  * decrements it during has processing */
133
142
  params->dst->num_args = num_args;
@@ -33,12 +33,16 @@
33
33
 
34
34
  #include "rb_completion_queue.h"
35
35
 
36
- #include <ruby.h>
36
+ #include <ruby/ruby.h>
37
+ #include <ruby/thread.h>
37
38
 
38
39
  #include <grpc/grpc.h>
39
40
  #include <grpc/support/time.h>
40
41
  #include "rb_grpc.h"
41
- #include "rb_event.h"
42
+
43
+ /* grpc_rb_cCompletionQueue is the ruby class that proxies
44
+ * grpc_completion_queue. */
45
+ static VALUE grpc_rb_cCompletionQueue = Qnil;
42
46
 
43
47
  /* Used to allow grpc_completion_queue_next call to release the GIL */
44
48
  typedef struct next_call_stack {
@@ -49,14 +53,16 @@ typedef struct next_call_stack {
49
53
  } next_call_stack;
50
54
 
51
55
  /* Calls grpc_completion_queue_next without holding the ruby GIL */
52
- static void *grpc_rb_completion_queue_next_no_gil(next_call_stack *next_call) {
56
+ static void *grpc_rb_completion_queue_next_no_gil(void *param) {
57
+ next_call_stack *const next_call = (next_call_stack*)param;
53
58
  next_call->event =
54
59
  grpc_completion_queue_next(next_call->cq, next_call->timeout);
55
60
  return NULL;
56
61
  }
57
62
 
58
63
  /* Calls grpc_completion_queue_pluck without holding the ruby GIL */
59
- static void *grpc_rb_completion_queue_pluck_no_gil(next_call_stack *next_call) {
64
+ static void *grpc_rb_completion_queue_pluck_no_gil(void *param) {
65
+ next_call_stack *const next_call = (next_call_stack*)param;
60
66
  next_call->event = grpc_completion_queue_pluck(next_call->cq, next_call->tag,
61
67
  next_call->timeout);
62
68
  return NULL;
@@ -113,21 +119,31 @@ static void grpc_rb_completion_queue_destroy(void *p) {
113
119
  grpc_completion_queue_destroy(cq);
114
120
  }
115
121
 
122
+ static rb_data_type_t grpc_rb_completion_queue_data_type = {
123
+ "grpc_completion_queue",
124
+ {GRPC_RB_GC_NOT_MARKED, grpc_rb_completion_queue_destroy,
125
+ GRPC_RB_MEMSIZE_UNAVAILABLE},
126
+ NULL, NULL,
127
+ /* cannot immediately free because grpc_rb_completion_queue_shutdown_drain
128
+ * calls rb_thread_call_without_gvl. */
129
+ 0
130
+ };
131
+
116
132
  /* Allocates a completion queue. */
117
133
  static VALUE grpc_rb_completion_queue_alloc(VALUE cls) {
118
134
  grpc_completion_queue *cq = grpc_completion_queue_create();
119
135
  if (cq == NULL) {
120
136
  rb_raise(rb_eArgError, "could not create a completion queue: not sure why");
121
137
  }
122
- return Data_Wrap_Struct(cls, GC_NOT_MARKED, grpc_rb_completion_queue_destroy,
123
- cq);
138
+ return TypedData_Wrap_Struct(cls, &grpc_rb_completion_queue_data_type, cq);
124
139
  }
125
140
 
126
141
  /* Blocks until the next event is available, and returns the event. */
127
142
  static VALUE grpc_rb_completion_queue_next(VALUE self, VALUE timeout) {
128
143
  next_call_stack next_call;
129
144
  MEMZERO(&next_call, next_call_stack, 1);
130
- Data_Get_Struct(self, grpc_completion_queue, next_call.cq);
145
+ TypedData_Get_Struct(self, grpc_completion_queue,
146
+ &grpc_rb_completion_queue_data_type, next_call.cq);
131
147
  next_call.timeout = grpc_rb_time_timeval(timeout, /* absolute time*/ 0);
132
148
  next_call.event = NULL;
133
149
  rb_thread_call_without_gvl(grpc_rb_completion_queue_next_no_gil,
@@ -140,46 +156,57 @@ static VALUE grpc_rb_completion_queue_next(VALUE self, VALUE timeout) {
140
156
 
141
157
  /* Blocks until the next event for given tag is available, and returns the
142
158
  * event. */
143
- static VALUE grpc_rb_completion_queue_pluck(VALUE self, VALUE tag,
144
- VALUE timeout) {
159
+ VALUE grpc_rb_completion_queue_pluck(VALUE self, VALUE tag,
160
+ VALUE timeout) {
161
+ grpc_event *ev = grpc_rb_completion_queue_pluck_event(self, tag, timeout);
162
+ if (ev == NULL) {
163
+ return Qnil;
164
+ }
165
+ return grpc_rb_new_event(ev);
166
+ }
167
+
168
+ /* Blocks until the next event for given tag is available, and returns the
169
+ * event. */
170
+ grpc_event* grpc_rb_completion_queue_pluck_event(VALUE self, VALUE tag,
171
+ VALUE timeout) {
145
172
  next_call_stack next_call;
146
173
  MEMZERO(&next_call, next_call_stack, 1);
147
- Data_Get_Struct(self, grpc_completion_queue, next_call.cq);
174
+ TypedData_Get_Struct(self, grpc_completion_queue,
175
+ &grpc_rb_completion_queue_data_type, next_call.cq);
148
176
  next_call.timeout = grpc_rb_time_timeval(timeout, /* absolute time*/ 0);
149
177
  next_call.tag = ROBJECT(tag);
150
178
  next_call.event = NULL;
151
179
  rb_thread_call_without_gvl(grpc_rb_completion_queue_pluck_no_gil,
152
180
  (void *)&next_call, NULL, NULL);
153
181
  if (next_call.event == NULL) {
154
- return Qnil;
182
+ return NULL;
155
183
  }
156
- return grpc_rb_new_event(next_call.event);
184
+ return next_call.event;
157
185
  }
158
186
 
159
- /* rb_cCompletionQueue is the ruby class that proxies grpc_completion_queue. */
160
- VALUE rb_cCompletionQueue = Qnil;
161
-
162
187
  void Init_grpc_completion_queue() {
163
- rb_cCompletionQueue =
164
- rb_define_class_under(rb_mGrpcCore, "CompletionQueue", rb_cObject);
188
+ grpc_rb_cCompletionQueue =
189
+ rb_define_class_under(grpc_rb_mGrpcCore, "CompletionQueue", rb_cObject);
165
190
 
166
191
  /* constructor: uses an alloc func without an initializer. Using a simple
167
192
  alloc func works here as the grpc header does not specify any args for
168
193
  this func, so no separate initialization step is necessary. */
169
- rb_define_alloc_func(rb_cCompletionQueue, grpc_rb_completion_queue_alloc);
194
+ rb_define_alloc_func(grpc_rb_cCompletionQueue,
195
+ grpc_rb_completion_queue_alloc);
170
196
 
171
197
  /* Add the next method that waits for the next event. */
172
- rb_define_method(rb_cCompletionQueue, "next", grpc_rb_completion_queue_next,
173
- 1);
198
+ rb_define_method(grpc_rb_cCompletionQueue, "next",
199
+ grpc_rb_completion_queue_next, 1);
174
200
 
175
201
  /* Add the pluck method that waits for the next event of given tag */
176
- rb_define_method(rb_cCompletionQueue, "pluck", grpc_rb_completion_queue_pluck,
177
- 2);
202
+ rb_define_method(grpc_rb_cCompletionQueue, "pluck",
203
+ grpc_rb_completion_queue_pluck, 2);
178
204
  }
179
205
 
180
206
  /* Gets the wrapped completion queue from the ruby wrapper */
181
207
  grpc_completion_queue *grpc_rb_get_wrapped_completion_queue(VALUE v) {
182
208
  grpc_completion_queue *cq = NULL;
183
- Data_Get_Struct(v, grpc_completion_queue, cq);
209
+ TypedData_Get_Struct(v, grpc_completion_queue,
210
+ &grpc_rb_completion_queue_data_type, cq);
184
211
  return cq;
185
212
  }
@@ -40,9 +40,13 @@
40
40
  /* Gets the wrapped completion queue from the ruby wrapper */
41
41
  grpc_completion_queue *grpc_rb_get_wrapped_completion_queue(VALUE v);
42
42
 
43
- /* rb_cCompletionQueue is the CompletionQueue class whose instances proxy
44
- grpc_completion_queue. */
45
- extern VALUE rb_cCompletionQueue;
43
+ /**
44
+ * Makes the implementation of CompletionQueue#pluck available in other files
45
+ *
46
+ * This avoids having code that holds the GIL repeated at multiple sites.
47
+ */
48
+ grpc_event* grpc_rb_completion_queue_pluck_event(VALUE cqueue, VALUE tag,
49
+ VALUE timeout);
46
50
 
47
51
  /* Initializes the CompletionQueue class. */
48
52
  void Init_grpc_completion_queue();
@@ -40,6 +40,9 @@
40
40
 
41
41
  #include "rb_grpc.h"
42
42
 
43
+ /* grpc_rb_cCredentials is the ruby class that proxies grpc_credentials. */
44
+ static VALUE grpc_rb_cCredentials = Qnil;
45
+
43
46
  /* grpc_rb_credentials wraps a grpc_credentials. It provides a
44
47
  * peer ruby object, 'mark' to minimize copying when a credential is
45
48
  * created from ruby. */
@@ -83,14 +86,21 @@ static void grpc_rb_credentials_mark(void *p) {
83
86
  }
84
87
  }
85
88
 
89
+ static rb_data_type_t grpc_rb_credentials_data_type = {
90
+ "grpc_credentials",
91
+ {grpc_rb_credentials_mark, grpc_rb_credentials_free,
92
+ GRPC_RB_MEMSIZE_UNAVAILABLE},
93
+ NULL,
94
+ NULL,
95
+ RUBY_TYPED_FREE_IMMEDIATELY};
96
+
86
97
  /* Allocates Credential instances.
87
98
  Provides safe initial defaults for the instance fields. */
88
99
  static VALUE grpc_rb_credentials_alloc(VALUE cls) {
89
100
  grpc_rb_credentials *wrapper = ALLOC(grpc_rb_credentials);
90
101
  wrapper->wrapped = NULL;
91
102
  wrapper->mark = Qnil;
92
- return Data_Wrap_Struct(cls, grpc_rb_credentials_mark,
93
- grpc_rb_credentials_free, wrapper);
103
+ return TypedData_Wrap_Struct(cls, &grpc_rb_credentials_data_type, wrapper);
94
104
  }
95
105
 
96
106
  /* Clones Credentials instances.
@@ -107,11 +117,13 @@ static VALUE grpc_rb_credentials_init_copy(VALUE copy, VALUE orig) {
107
117
  /* Raise an error if orig is not a credentials object or a subclass. */
108
118
  if (TYPE(orig) != T_DATA ||
109
119
  RDATA(orig)->dfree != (RUBY_DATA_FUNC)grpc_rb_credentials_free) {
110
- rb_raise(rb_eTypeError, "not a %s", rb_obj_classname(rb_cCredentials));
120
+ rb_raise(rb_eTypeError, "not a %s", rb_obj_classname(grpc_rb_cCredentials));
111
121
  }
112
122
 
113
- Data_Get_Struct(orig, grpc_rb_credentials, orig_cred);
114
- Data_Get_Struct(copy, grpc_rb_credentials, copy_cred);
123
+ TypedData_Get_Struct(orig, grpc_rb_credentials,
124
+ &grpc_rb_credentials_data_type, orig_cred);
125
+ TypedData_Get_Struct(copy, grpc_rb_credentials,
126
+ &grpc_rb_credentials_data_type, copy_cred);
115
127
 
116
128
  /* use ruby's MEMCPY to make a byte-for-byte copy of the credentials
117
129
  * wrapper object. */
@@ -133,8 +145,7 @@ static VALUE grpc_rb_default_credentials_create(VALUE cls) {
133
145
  }
134
146
 
135
147
  wrapper->mark = Qnil;
136
- return Data_Wrap_Struct(cls, grpc_rb_credentials_mark,
137
- grpc_rb_credentials_free, wrapper);
148
+ return TypedData_Wrap_Struct(cls, &grpc_rb_credentials_data_type, wrapper);
138
149
  }
139
150
 
140
151
  /*
@@ -151,8 +162,7 @@ static VALUE grpc_rb_compute_engine_credentials_create(VALUE cls) {
151
162
  }
152
163
 
153
164
  wrapper->mark = Qnil;
154
- return Data_Wrap_Struct(cls, grpc_rb_credentials_mark,
155
- grpc_rb_credentials_free, wrapper);
165
+ return TypedData_Wrap_Struct(cls, &grpc_rb_credentials_data_type, wrapper);
156
166
  }
157
167
 
158
168
  /*
@@ -166,8 +176,10 @@ static VALUE grpc_rb_composite_credentials_create(VALUE self, VALUE other) {
166
176
  grpc_rb_credentials *other_wrapper = NULL;
167
177
  grpc_rb_credentials *wrapper = NULL;
168
178
 
169
- Data_Get_Struct(self, grpc_rb_credentials, self_wrapper);
170
- Data_Get_Struct(other, grpc_rb_credentials, other_wrapper);
179
+ TypedData_Get_Struct(self, grpc_rb_credentials,
180
+ &grpc_rb_credentials_data_type, self_wrapper);
181
+ TypedData_Get_Struct(other, grpc_rb_credentials,
182
+ &grpc_rb_credentials_data_type, other_wrapper);
171
183
  wrapper = ALLOC(grpc_rb_credentials);
172
184
  wrapper->wrapped = grpc_composite_credentials_create(self_wrapper->wrapped,
173
185
  other_wrapper->wrapped);
@@ -178,8 +190,8 @@ static VALUE grpc_rb_composite_credentials_create(VALUE self, VALUE other) {
178
190
  }
179
191
 
180
192
  wrapper->mark = Qnil;
181
- return Data_Wrap_Struct(rb_cCredentials, grpc_rb_credentials_mark,
182
- grpc_rb_credentials_free, wrapper);
193
+ return TypedData_Wrap_Struct(grpc_rb_cCredentials,
194
+ &grpc_rb_credentials_data_type, wrapper);
183
195
  }
184
196
 
185
197
  /* The attribute used on the mark object to hold the pem_root_certs. */
@@ -214,7 +226,8 @@ static VALUE grpc_rb_credentials_init(int argc, VALUE *argv, VALUE self) {
214
226
  rb_scan_args(argc, argv, "12", &pem_root_certs, &pem_private_key,
215
227
  &pem_cert_chain);
216
228
 
217
- Data_Get_Struct(self, grpc_rb_credentials, wrapper);
229
+ TypedData_Get_Struct(self, grpc_rb_credentials,
230
+ &grpc_rb_credentials_data_type, wrapper);
218
231
  if (pem_root_certs == Qnil) {
219
232
  rb_raise(rb_eRuntimeError,
220
233
  "could not create a credential: nil pem_root_certs");
@@ -225,8 +238,8 @@ static VALUE grpc_rb_credentials_init(int argc, VALUE *argv, VALUE self) {
225
238
  } else {
226
239
  key_cert_pair.private_key = RSTRING_PTR(pem_private_key);
227
240
  key_cert_pair.cert_chain = RSTRING_PTR(pem_cert_chain);
228
- creds = grpc_ssl_credentials_create(
229
- RSTRING_PTR(pem_root_certs), &key_cert_pair);
241
+ creds = grpc_ssl_credentials_create(RSTRING_PTR(pem_root_certs),
242
+ &key_cert_pair);
230
243
  }
231
244
  if (creds == NULL) {
232
245
  rb_raise(rb_eRuntimeError, "could not create a credentials, not sure why");
@@ -242,30 +255,28 @@ static VALUE grpc_rb_credentials_init(int argc, VALUE *argv, VALUE self) {
242
255
  return self;
243
256
  }
244
257
 
245
- /* rb_cCredentials is the ruby class that proxies grpc_credentials. */
246
- VALUE rb_cCredentials = Qnil;
247
-
248
258
  void Init_grpc_credentials() {
249
- rb_cCredentials =
250
- rb_define_class_under(rb_mGrpcCore, "Credentials", rb_cObject);
259
+ grpc_rb_cCredentials =
260
+ rb_define_class_under(grpc_rb_mGrpcCore, "Credentials", rb_cObject);
251
261
 
252
262
  /* Allocates an object managed by the ruby runtime */
253
- rb_define_alloc_func(rb_cCredentials, grpc_rb_credentials_alloc);
263
+ rb_define_alloc_func(grpc_rb_cCredentials, grpc_rb_credentials_alloc);
254
264
 
255
265
  /* Provides a ruby constructor and support for dup/clone. */
256
- rb_define_method(rb_cCredentials, "initialize", grpc_rb_credentials_init, -1);
257
- rb_define_method(rb_cCredentials, "initialize_copy",
266
+ rb_define_method(grpc_rb_cCredentials, "initialize", grpc_rb_credentials_init,
267
+ -1);
268
+ rb_define_method(grpc_rb_cCredentials, "initialize_copy",
258
269
  grpc_rb_credentials_init_copy, 1);
259
270
 
260
271
  /* Provide static funcs that create new special instances. */
261
- rb_define_singleton_method(rb_cCredentials, "default",
272
+ rb_define_singleton_method(grpc_rb_cCredentials, "default",
262
273
  grpc_rb_default_credentials_create, 0);
263
274
 
264
- rb_define_singleton_method(rb_cCredentials, "compute_engine",
275
+ rb_define_singleton_method(grpc_rb_cCredentials, "compute_engine",
265
276
  grpc_rb_compute_engine_credentials_create, 0);
266
277
 
267
278
  /* Provide other methods. */
268
- rb_define_method(rb_cCredentials, "compose",
279
+ rb_define_method(grpc_rb_cCredentials, "compose",
269
280
  grpc_rb_composite_credentials_create, 1);
270
281
 
271
282
  id_pem_cert_chain = rb_intern("__pem_cert_chain");
@@ -276,6 +287,7 @@ void Init_grpc_credentials() {
276
287
  /* Gets the wrapped grpc_credentials from the ruby wrapper */
277
288
  grpc_credentials *grpc_rb_get_wrapped_credentials(VALUE v) {
278
289
  grpc_rb_credentials *wrapper = NULL;
279
- Data_Get_Struct(v, grpc_rb_credentials, wrapper);
290
+ TypedData_Get_Struct(v, grpc_rb_credentials, &grpc_rb_credentials_data_type,
291
+ wrapper);
280
292
  return wrapper->wrapped;
281
293
  }