rb_channel.c
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #include <ruby/ruby.h>
20 
21 #include "rb_channel.h"
22 
23 #include <ruby/thread.h>
24 
25 #include "rb_byte_buffer.h"
26 #include "rb_call.h"
27 #include "rb_channel_args.h"
28 #include "rb_channel_credentials.h"
29 #include "rb_completion_queue.h"
30 #include "rb_grpc.h"
32 #include "rb_server.h"
34 
35 #include <grpc/grpc.h>
36 #include <grpc/grpc_security.h>
37 #include <grpc/support/alloc.h>
38 #include <grpc/support/log.h>
39 #include <grpc/support/time.h>
40 
41 /* id_channel is the name of the hidden ivar that preserves a reference to the
42  * channel on a call, so that calls are not GCed before their channel. */
43 static ID id_channel;
44 
45 /* id_target is the name of the hidden ivar that preserves a reference to the
46  * target string used to create the call, preserved so that it does not get
47  * GCed before the channel */
48 static ID id_target;
49 
50 /* id_insecure_channel is used to indicate that a channel is insecure */
51 static VALUE id_insecure_channel;
52 
53 /* grpc_rb_cChannel is the ruby class that proxies grpc_channel. */
54 static VALUE grpc_rb_cChannel = Qnil;
55 
56 /* Used during the conversion of a hash to channel args during channel setup */
57 static VALUE grpc_rb_cChannelArgs;
58 
59 typedef struct bg_watched_channel {
61  // these fields must only be accessed under global_connection_polling_mu
64  int refcount;
66 
67 /* grpc_rb_channel wraps a grpc_channel. */
68 typedef struct grpc_rb_channel {
69  VALUE credentials;
70 
71  /* The actual channel (protected in a wrapper to tell when it's safe to
72  * destroy) */
75 
77 
78 typedef struct watch_state_op {
80  // from event.success
81  union {
82  struct {
83  int success;
84  // has been called back due to a cq next call
87  struct {
90  } op;
92 
94 
96  bg_watched_channel* bg);
100  void* arg);
101 
106 
110 static int abort_channel_polling = 0;
112 
118 
119 // Needs to be called under global_connection_polling_mu
121  watch_state_op* op, int success) {
122  GPR_ASSERT(!op->op.api_callback_args.called_back);
123  op->op.api_callback_args.called_back = 1;
124  op->op.api_callback_args.success = success;
125  // wake up the watch API call that's waiting on this op
127 }
128 
129 /* Avoids destroying a channel twice. */
133  if (!bg->channel_destroyed) {
135  bg->channel_destroyed = 1;
136  }
137  bg->refcount--;
138  if (bg->refcount == 0) {
140  }
142 }
143 
146  return NULL;
147 }
148 
149 static void grpc_rb_channel_free_internal(void* p) {
150  grpc_rb_channel* ch = NULL;
151  if (p == NULL) {
152  return;
153  };
154  ch = (grpc_rb_channel*)p;
155  if (ch->bg_wrapped != NULL) {
156  /* assumption made here: it's ok to directly gpr_mu_lock the global
157  * connection polling mutex because we're in a finalizer,
158  * and we can count on this thread to not be interrupted or
159  * yield the gil. */
160  grpc_rb_channel_safe_destroy(ch->bg_wrapped);
161  ch->bg_wrapped = NULL;
162  }
163  xfree(p);
164 }
165 
166 /* Destroys Channel instances. */
167 static void grpc_rb_channel_free(void* p) {
170 }
171 
172 /* Protects the mark object from GC */
173 static void grpc_rb_channel_mark(void* p) {
174  grpc_rb_channel* channel = NULL;
175  if (p == NULL) {
176  return;
177  }
179  if (channel->credentials != Qnil) {
180  rb_gc_mark(channel->credentials);
181  }
182 }
183 
184 static rb_data_type_t grpc_channel_data_type = {"grpc_channel",
188  {NULL, NULL}},
189  NULL,
190  NULL,
191 #ifdef RUBY_TYPED_FREE_IMMEDIATELY
192  RUBY_TYPED_FREE_IMMEDIATELY
193 #endif
194 };
195 
196 /* Allocates grpc_rb_channel instances. */
197 static VALUE grpc_rb_channel_alloc(VALUE cls) {
198  grpc_ruby_init();
200  wrapper->bg_wrapped = NULL;
201  wrapper->credentials = Qnil;
202  return TypedData_Wrap_Struct(cls, &grpc_channel_data_type, wrapper);
203 }
204 
205 /*
206  call-seq:
207  insecure_channel = Channel:new("myhost:8080", {'arg1': 'value1'},
208  :this_channel_is_insecure)
209  creds = ...
210  secure_channel = Channel:new("myhost:443", {'arg1': 'value1'}, creds)
211 
212  Creates channel instances. */
213 static VALUE grpc_rb_channel_init(int argc, VALUE* argv, VALUE self) {
214  VALUE channel_args = Qnil;
215  VALUE credentials = Qnil;
216  VALUE target = Qnil;
217  grpc_rb_channel* wrapper = NULL;
218  grpc_channel* ch = NULL;
219  grpc_channel_credentials* creds = NULL;
220  char* target_chars = NULL;
223  int stop_waiting_for_thread_start = 0;
224  MEMZERO(&args, grpc_channel_args, 1);
225 
227  rb_thread_call_without_gvl(
229  &stop_waiting_for_thread_start,
231  &stop_waiting_for_thread_start);
232 
233  /* "3" == 3 mandatory args */
234  rb_scan_args(argc, argv, "3", &target, &channel_args, &credentials);
235 
236  TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
237  target_chars = StringValueCStr(target);
239  if (TYPE(credentials) == T_SYMBOL) {
240  if (id_insecure_channel != SYM2ID(credentials)) {
241  rb_raise(rb_eTypeError,
242  "bad creds symbol, want :this_channel_is_insecure");
243  return Qnil;
244  }
245  grpc_channel_credentials* insecure_creds =
247  ch = grpc_channel_create(target_chars, insecure_creds, &args);
248  grpc_channel_credentials_release(insecure_creds);
249  } else {
250  wrapper->credentials = credentials;
251  if (grpc_rb_is_channel_credentials(credentials)) {
252  creds = grpc_rb_get_wrapped_channel_credentials(credentials);
253  } else if (grpc_rb_is_xds_channel_credentials(credentials)) {
254  creds = grpc_rb_get_wrapped_xds_channel_credentials(credentials);
255  } else {
256  rb_raise(rb_eTypeError,
257  "bad creds, want ChannelCredentials or XdsChannelCredentials");
258  return Qnil;
259  }
260  ch = grpc_channel_create(target_chars, creds, &args);
261  }
262 
263  GPR_ASSERT(ch);
264  stack.channel = ch;
265  stack.wrapper = wrapper;
266  rb_thread_call_without_gvl(
268  NULL);
269 
270  if (args.args != NULL) {
271  xfree(args.args); /* Allocated by grpc_rb_hash_convert_to_channel_args */
272  }
273  if (ch == NULL) {
274  rb_raise(rb_eRuntimeError, "could not create an rpc channel to target:%s",
275  target_chars);
276  return Qnil;
277  }
278  rb_ivar_set(self, id_target, target);
279  return self;
280 }
281 
282 typedef struct get_state_stack {
285  int out;
287 
288 static void* get_state_without_gil(void* arg) {
290 
293  if (stack->bg->channel_destroyed) {
295  } else {
297  stack->try_to_connect);
298  }
300 
301  return NULL;
302 }
303 
304 /*
305  call-seq:
306  ch.connectivity_state -> state
307  ch.connectivity_state(true) -> state
308 
309  Indicates the current state of the channel, whose value is one of the
310  constants defined in GRPC::Core::ConnectivityStates.
311 
312  It also tries to connect if the channel is idle in the second form. */
313 static VALUE grpc_rb_channel_get_connectivity_state(int argc, VALUE* argv,
314  VALUE self) {
315  VALUE try_to_connect_param = Qfalse;
316  grpc_rb_channel* wrapper = NULL;
318 
319  /* "01" == 0 mandatory args, 1 (try_to_connect) is optional */
320  rb_scan_args(argc, argv, "01", &try_to_connect_param);
321 
322  TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
323  if (wrapper->bg_wrapped == NULL) {
324  rb_raise(rb_eRuntimeError, "closed!");
325  return Qnil;
326  }
327 
328  stack.bg = wrapper->bg_wrapped;
329  stack.try_to_connect = RTEST(try_to_connect_param) ? 1 : 0;
330  rb_thread_call_without_gvl(get_state_without_gil, &stack, NULL, NULL);
331 
332  return LONG2NUM(stack.out);
333 }
334 
335 typedef struct watch_state_stack {
340 
343  watch_state_op* op = NULL;
344  void* success = (void*)0;
345 
347  // it's unsafe to do a "watch" after "channel polling abort" because the cq
348  // has been shut down.
349  if (abort_channel_polling || stack->bg_wrapped->channel_destroyed) {
351  return (void*)0;
352  }
353  op = gpr_zalloc(sizeof(watch_state_op));
354  op->op_type = WATCH_STATE_API;
355  grpc_channel_watch_connectivity_state(stack->bg_wrapped->channel,
356  stack->last_state, stack->deadline,
358 
359  while (!op->op.api_callback_args.called_back) {
362  }
363  if (op->op.api_callback_args.success) {
364  success = (void*)1;
365  }
366  gpr_free(op);
368 
369  return success;
370 }
374  if (!bg->channel_destroyed) {
376  bg->channel_destroyed = 1;
377  }
379 }
380 
381 /* Wait until the channel's connectivity state becomes different from
382  * "last_state", or "deadline" expires.
383  * Returns true if the channel's connectivity state becomes different
384  * from "last_state" within "deadline".
385  * Returns false if "deadline" expires before the channel's connectivity
386  * state changes from "last_state".
387  * */
389  VALUE last_state,
390  VALUE deadline) {
391  grpc_rb_channel* wrapper = NULL;
393  void* op_success = 0;
394 
396  TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
397 
398  if (wrapper->bg_wrapped == NULL) {
399  rb_raise(rb_eRuntimeError, "closed!");
400  return Qnil;
401  }
402 
403  if (!FIXNUM_P(last_state)) {
404  rb_raise(
405  rb_eTypeError,
406  "bad type for last_state. want a GRPC::Core::ChannelState constant");
407  return Qnil;
408  }
409 
410  stack.bg_wrapped = wrapper->bg_wrapped;
411  stack.deadline = grpc_rb_time_timeval(deadline, 0),
412  stack.last_state = NUM2LONG(last_state);
413 
414  op_success = rb_thread_call_without_gvl(
417 
418  return op_success ? Qtrue : Qfalse;
419 }
420 
421 /* Create a call given a grpc_channel, in order to call method. The request
422  is not sent until grpc_call_invoke is called. */
423 static VALUE grpc_rb_channel_create_call(VALUE self, VALUE parent, VALUE mask,
424  VALUE method, VALUE host,
425  VALUE deadline) {
426  VALUE res = Qnil;
427  grpc_rb_channel* wrapper = NULL;
428  grpc_call* call = NULL;
429  grpc_call* parent_call = NULL;
430  grpc_completion_queue* cq = NULL;
432  grpc_slice method_slice;
433  grpc_slice host_slice;
434  grpc_slice* host_slice_ptr = NULL;
435  char* tmp_str = NULL;
436 
438  if (host != Qnil) {
439  host_slice =
440  grpc_slice_from_copied_buffer(RSTRING_PTR(host), RSTRING_LEN(host));
441  host_slice_ptr = &host_slice;
442  }
443  if (mask != Qnil) {
444  flags = NUM2UINT(mask);
445  }
446  if (parent != Qnil) {
447  parent_call = grpc_rb_get_wrapped_call(parent);
448  }
449 
450  TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
451  if (wrapper->bg_wrapped == NULL) {
452  rb_raise(rb_eRuntimeError, "closed!");
453  return Qnil;
454  }
455 
457  method_slice =
458  grpc_slice_from_copied_buffer(RSTRING_PTR(method), RSTRING_LEN(method));
459  call = grpc_channel_create_call(wrapper->bg_wrapped->channel, parent_call,
460  flags, cq, method_slice, host_slice_ptr,
461  grpc_rb_time_timeval(deadline,
462  /* absolute time */ 0),
463  NULL);
464 
465  if (call == NULL) {
466  tmp_str = grpc_slice_to_c_string(method_slice);
467  rb_raise(rb_eRuntimeError, "cannot create call with method %s", tmp_str);
468  return Qnil;
469  }
470 
471  grpc_slice_unref(method_slice);
472  if (host_slice_ptr != NULL) {
473  grpc_slice_unref(host_slice);
474  }
475 
476  res = grpc_rb_wrap_call(call, cq);
477 
478  /* Make this channel an instance attribute of the call so that it is not GCed
479  * before the call. */
480  rb_ivar_set(res, id_channel, self);
481  return res;
482 }
483 
484 /* Closes the channel, calling it's destroy method */
485 /* Note this is an API-level call; a wrapped channel's finalizer doesn't call
486  * this */
487 static VALUE grpc_rb_channel_destroy(VALUE self) {
488  grpc_rb_channel* wrapper = NULL;
489 
490  TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
491  if (wrapper->bg_wrapped != NULL) {
492  rb_thread_call_without_gvl(channel_safe_destroy_without_gil,
493  wrapper->bg_wrapped, NULL, NULL);
494  wrapper->bg_wrapped = NULL;
495  }
496 
497  return Qnil;
498 }
499 
500 /* Called to obtain the target that this channel accesses. */
501 static VALUE grpc_rb_channel_get_target(VALUE self) {
502  grpc_rb_channel* wrapper = NULL;
503  VALUE res = Qnil;
504  char* target = NULL;
505 
506  TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
507  target = grpc_channel_get_target(wrapper->bg_wrapped->channel);
508  res = rb_str_new2(target);
509  gpr_free(target);
510 
511  return res;
512 }
513 
514 /* Needs to be called under global_connection_polling_mu */
517 
518  while (cur != NULL) {
519  if (cur == target) {
520  return 1;
521  }
522  cur = cur->next;
523  }
524 
525  return 0;
526 }
527 
528 /* Needs to be called under global_connection_polling_mu */
532 
533  watched->channel = channel;
535  watched->refcount = 1;
537  return watched;
538 }
539 
540 /* Needs to be called under global_connection_polling_mu */
543  bg_watched_channel* bg = NULL;
544 
546  GPR_ASSERT(target->channel_destroyed && target->refcount == 0);
549  gpr_free(target);
550  return;
551  }
553  while (bg != NULL && bg->next != NULL) {
554  if (bg->next == target) {
555  bg->next = bg->next->next;
556  gpr_free(target);
557  return;
558  }
559  bg = bg->next;
560  }
561  GPR_ASSERT(0);
562 }
563 
564 /* Initialize a grpc_rb_channel's "protected grpc_channel" and try to push
565  * it onto the background thread for constant watches. */
567  void* arg) {
570 
572  stack->wrapper->bg_wrapped =
576  return NULL;
577 }
578 
579 // Needs to be called under global_connection_poolling_mu
581  bg_watched_channel* bg) {
583  watch_state_op* op = NULL;
584 
586 
587  if (bg->refcount == 0) {
590  return;
591  }
592  GPR_ASSERT(bg->refcount == 1);
594  return;
595  }
596 
599  return;
600  }
602  // prevent bg from being free'd by GC while background thread is watching it
603  bg->refcount++;
604 
605  op = gpr_zalloc(sizeof(watch_state_op));
606  op->op_type = CONTINUOUS_WATCH;
607  op->op.continuous_watch_callback_args.bg = bg;
611 }
612 
613 // Note this loop breaks out with a single call of
614 // "run_poll_channels_loop_no_gil".
615 // This assumes that a ruby call the unblocking func
616 // indicates process shutdown.
617 // In the worst case, this stops polling channel connectivity
618 // early and falls back to current behavior.
619 static void* run_poll_channels_loop_no_gil(void* arg) {
620  grpc_event event;
621  watch_state_op* op = NULL;
622  bg_watched_channel* bg = NULL;
623  (void)arg;
624  gpr_log(GPR_DEBUG, "GRPC_RUBY: run_poll_channels_loop_no_gil - begin");
625 
631 
632  for (;;) {
635  if (event.type == GRPC_QUEUE_SHUTDOWN) {
636  break;
637  }
639  if (event.type == GRPC_OP_COMPLETE) {
640  op = (watch_state_op*)event.tag;
641  if (op->op_type == CONTINUOUS_WATCH) {
642  bg = (bg_watched_channel*)op->op.continuous_watch_callback_args.bg;
643  bg->refcount--;
645  gpr_free(op);
646  } else if (op->op_type == WATCH_STATE_API) {
648  (watch_state_op*)event.tag, event.success);
649  } else {
650  GPR_ASSERT(0);
651  }
652  }
654  }
657  "GRPC_RUBY: run_poll_channels_loop_no_gil - exit connection polling "
658  "loop");
659  return NULL;
660 }
661 
662 // Notify the channel polling loop to cleanup and shutdown.
664  bg_watched_channel* bg = NULL;
665  (void)arg;
666 
669  "GRPC_RUBY: run_poll_channels_loop_unblocking_func - begin aborting "
670  "connection polling");
671  // early out after first time through
672  if (abort_channel_polling) {
674  return;
675  }
677 
678  // force pending watches to end by switching to shutdown state
680  while (bg != NULL) {
681  if (!bg->channel_destroyed) {
683  bg->channel_destroyed = 1;
684  }
685  bg = bg->next;
686  }
687 
692  "GRPC_RUBY: run_poll_channels_loop_unblocking_func - end aborting "
693  "connection polling");
694 }
695 
696 // Poll channel connectivity states in background thread without the GIL.
697 static VALUE run_poll_channels_loop(VALUE arg) {
698  (void)arg;
699  gpr_log(
700  GPR_DEBUG,
701  "GRPC_RUBY: run_poll_channels_loop - create connection polling thread");
702  grpc_ruby_init();
703  rb_thread_call_without_gvl(run_poll_channels_loop_no_gil, NULL,
706  return Qnil;
707 }
708 
710  int* stop_waiting = (int*)arg;
711  gpr_log(GPR_DEBUG, "GRPC_RUBY: wait for channel polling thread to start");
714  !*stop_waiting) {
717  }
719 
720  return NULL;
721 }
722 
724  void* arg) {
725  int* stop_waiting = (int*)arg;
728  "GRPC_RUBY: interrupt wait for channel polling thread to start");
729  *stop_waiting = 1;
732 }
733 
735  (void)arg;
740  return NULL;
741 }
742 
743 /* Temporary fix for
744  * https://github.com/GoogleCloudPlatform/google-cloud-ruby/issues/899.
745  * Transports in idle channels can get destroyed. Normally c-core re-connects,
746  * but in grpc-ruby core never gets a thread until an RPC is made, because ruby
747  * only calls c-core's "completion_queu_pluck" API.
748  * This uses a global background thread that calls
749  * "completion_queue_next" on registered "watch_channel_connectivity_state"
750  * calls - so that c-core can reconnect if needed, when there aren't any RPC's.
751  * TODO(apolcyn) remove this when core handles new RPCs on dead connections.
752  */
754  VALUE background_thread = Qnil;
755 
759 
762 
764  background_thread = rb_thread_create(run_poll_channels_loop, NULL);
765 
766  if (!RTEST(background_thread)) {
767  gpr_log(GPR_DEBUG, "GRPC_RUBY: failed to spawn channel polling thread");
768  rb_thread_call_without_gvl(set_abort_channel_polling_without_gil, NULL,
769  NULL, NULL);
770  }
771 }
772 
774  /* Constants representing call propagation masks in grpc.h */
775  VALUE grpc_rb_mPropagateMasks =
776  rb_define_module_under(grpc_rb_mGrpcCore, "PropagateMasks");
777  rb_define_const(grpc_rb_mPropagateMasks, "DEADLINE",
778  UINT2NUM(GRPC_PROPAGATE_DEADLINE));
779  rb_define_const(grpc_rb_mPropagateMasks, "CENSUS_STATS_CONTEXT",
781  rb_define_const(grpc_rb_mPropagateMasks, "CENSUS_TRACING_CONTEXT",
783  rb_define_const(grpc_rb_mPropagateMasks, "CANCELLATION",
784  UINT2NUM(GRPC_PROPAGATE_CANCELLATION));
785  rb_define_const(grpc_rb_mPropagateMasks, "DEFAULTS",
786  UINT2NUM(GRPC_PROPAGATE_DEFAULTS));
787 }
788 
790  /* Constants representing call propagation masks in grpc.h */
791  VALUE grpc_rb_mConnectivityStates =
792  rb_define_module_under(grpc_rb_mGrpcCore, "ConnectivityStates");
793  rb_define_const(grpc_rb_mConnectivityStates, "IDLE",
794  LONG2NUM(GRPC_CHANNEL_IDLE));
795  rb_define_const(grpc_rb_mConnectivityStates, "CONNECTING",
796  LONG2NUM(GRPC_CHANNEL_CONNECTING));
797  rb_define_const(grpc_rb_mConnectivityStates, "READY",
798  LONG2NUM(GRPC_CHANNEL_READY));
799  rb_define_const(grpc_rb_mConnectivityStates, "TRANSIENT_FAILURE",
801  rb_define_const(grpc_rb_mConnectivityStates, "FATAL_FAILURE",
802  LONG2NUM(GRPC_CHANNEL_SHUTDOWN));
803 }
804 
806  grpc_rb_cChannelArgs = rb_define_class("TmpChannelArgs", rb_cObject);
808  rb_define_class_under(grpc_rb_mGrpcCore, "Channel", rb_cObject);
809 
810  /* Allocates an object managed by the ruby runtime */
811  rb_define_alloc_func(grpc_rb_cChannel, grpc_rb_channel_alloc);
812 
813  /* Provides a ruby constructor and support for dup/clone. */
814  rb_define_method(grpc_rb_cChannel, "initialize", grpc_rb_channel_init, -1);
815  rb_define_method(grpc_rb_cChannel, "initialize_copy",
817 
818  /* Add ruby analogues of the Channel methods. */
819  rb_define_method(grpc_rb_cChannel, "connectivity_state",
821  rb_define_method(grpc_rb_cChannel, "watch_connectivity_state",
823  rb_define_method(grpc_rb_cChannel, "create_call", grpc_rb_channel_create_call,
824  5);
825  rb_define_method(grpc_rb_cChannel, "target", grpc_rb_channel_get_target, 0);
826  rb_define_method(grpc_rb_cChannel, "destroy", grpc_rb_channel_destroy, 0);
827  rb_define_alias(grpc_rb_cChannel, "close", "destroy");
828 
829  id_channel = rb_intern("__channel");
830  id_target = rb_intern("__target");
831  rb_define_const(grpc_rb_cChannel, "SSL_TARGET",
832  ID2SYM(rb_intern(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)));
833  rb_define_const(grpc_rb_cChannel, "ENABLE_CENSUS",
834  ID2SYM(rb_intern(GRPC_ARG_ENABLE_CENSUS)));
835  rb_define_const(grpc_rb_cChannel, "MAX_CONCURRENT_STREAMS",
836  ID2SYM(rb_intern(GRPC_ARG_MAX_CONCURRENT_STREAMS)));
837  rb_define_const(grpc_rb_cChannel, "MAX_MESSAGE_LENGTH",
838  ID2SYM(rb_intern(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH)));
839  id_insecure_channel = rb_intern("this_channel_is_insecure");
842 }
843 
844 /* Gets the wrapped channel from the ruby wrapper */
846  grpc_rb_channel* wrapper = NULL;
847  TypedData_Get_Struct(v, grpc_rb_channel, &grpc_channel_data_type, wrapper);
848  return wrapper->bg_wrapped->channel;
849 }
rb_completion_queue.h
get_state_stack::out
int out
Definition: rb_channel.c:285
grpc_slice_unref
GPRAPI void grpc_slice_unref(grpc_slice s)
Definition: slice_api.cc:32
get_state_without_gil
static void * get_state_without_gil(void *arg)
Definition: rb_channel.c:288
GRPC_CHANNEL_READY
@ GRPC_CHANNEL_READY
Definition: include/grpc/impl/codegen/connectivity_state.h:36
gpr_mu_unlock
GPRAPI void gpr_mu_unlock(gpr_mu *mu)
run_poll_channels_loop
static VALUE run_poll_channels_loop(VALUE arg)
Definition: rb_channel.c:697
run_poll_channels_loop_unblocking_func
static void run_poll_channels_loop_unblocking_func(void *arg)
Definition: rb_channel.c:663
log.h
set_abort_channel_polling_without_gil
static void * set_abort_channel_polling_without_gil(void *arg)
Definition: rb_channel.c:734
watch_state_op::api_callback_args
struct watch_state_op::@49::@50 api_callback_args
rb_grpc_imports.generated.h
GRPC_RB_MEMSIZE_UNAVAILABLE
#define GRPC_RB_MEMSIZE_UNAVAILABLE
Definition: rb_grpc.h:57
grpc_completion_queue_create_for_pluck
GRPCAPI grpc_completion_queue * grpc_completion_queue_create_for_pluck(void *reserved)
Definition: completion_queue_factory.cc:69
grpc_rb_hash_convert_to_channel_args
void grpc_rb_hash_convert_to_channel_args(VALUE src_hash, grpc_channel_args *dst)
Definition: rb_channel_args.c:139
grpc_ruby_shutdown
void grpc_ruby_shutdown()
Definition: rb_grpc.c:296
GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH
#define GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH
Definition: grpc_types.h:153
grpc_rb_get_wrapped_channel
grpc_channel * grpc_rb_get_wrapped_channel(VALUE v)
Definition: rb_channel.c:845
channel_init_try_register_stack
struct channel_init_try_register_stack channel_init_try_register_stack
grpc_rb_channel::credentials
VALUE credentials
Definition: rb_channel.c:69
gpr_cv
pthread_cond_t gpr_cv
Definition: impl/codegen/sync_posix.h:48
watch_state_op::called_back
int called_back
Definition: rb_channel.c:85
bg_watched_channel::channel
grpc_channel * channel
Definition: rb_channel.c:60
grpc_channel_check_connectivity_state
GRPCAPI grpc_connectivity_state grpc_channel_check_connectivity_state(grpc_channel *channel, int try_to_connect)
Definition: channel_connectivity.cc:56
grpc_rb_channel_create_call
static VALUE grpc_rb_channel_create_call(VALUE self, VALUE parent, VALUE mask, VALUE method, VALUE host, VALUE deadline)
Definition: rb_channel.c:423
gpr_free
GPRAPI void gpr_free(void *ptr)
Definition: alloc.cc:51
bg_watched_channel
Definition: rb_channel.c:59
get_state_stack::bg
bg_watched_channel * bg
Definition: rb_channel.c:283
watch_state_op::op
union watch_state_op::@49 op
GRPC_QUEUE_SHUTDOWN
@ GRPC_QUEUE_SHUTDOWN
Definition: grpc_types.h:554
GRPC_OP_COMPLETE
@ GRPC_OP_COMPLETE
Definition: grpc_types.h:558
GRPC_CHANNEL_TRANSIENT_FAILURE
@ GRPC_CHANNEL_TRANSIENT_FAILURE
Definition: include/grpc/impl/codegen/connectivity_state.h:38
grpc_channel_get_target
GRPCAPI char * grpc_channel_get_target(grpc_channel *channel)
Definition: channel.cc:256
GRPC_ARG_ENABLE_CENSUS
#define GRPC_ARG_ENABLE_CENSUS
Definition: grpc_types.h:142
gpr_inf_future
GPRAPI gpr_timespec gpr_inf_future(gpr_clock_type type)
Definition: src/core/lib/gpr/time.cc:55
watch_state_stack
Definition: rb_channel.c:335
time.h
xds_manager.p
p
Definition: xds_manager.py:60
grpc_security.h
get_state_stack
struct get_state_stack get_state_stack
grpc_channel_args
Definition: grpc_types.h:132
bg_watched_channel_list_create_and_add
static bg_watched_channel * bg_watched_channel_list_create_and_add(grpc_channel *channel)
Definition: rb_channel.c:529
watch_state_op
struct watch_state_op watch_state_op
grpc_connectivity_state
grpc_connectivity_state
Definition: include/grpc/impl/codegen/connectivity_state.h:30
call
FilterStackCall * call
Definition: call.cc:750
conn_state
static int conn_state(BIO *bio, BIO_CONNECT *c)
Definition: connect.c:168
gpr_zalloc
GPRAPI void * gpr_zalloc(size_t size)
Definition: alloc.cc:40
wait_for_watch_state_op_complete_without_gvl
static void * wait_for_watch_state_op_complete_without_gvl(void *arg)
Definition: rb_channel.c:341
wait_until_channel_polling_thread_started_no_gil
static void * wait_until_channel_polling_thread_started_no_gil(void *)
Definition: rb_channel.c:709
grpc_rb_channel
Definition: rb_channel.c:68
watch_state_op_type
watch_state_op_type
Definition: rb_channel.c:76
grpc_rb_get_wrapped_channel_credentials
grpc_channel_credentials * grpc_rb_get_wrapped_channel_credentials(VALUE v)
Definition: rb_channel_credentials.c:275
grpc_rb_channel_polling_thread_start
void grpc_rb_channel_polling_thread_start()
Definition: rb_channel.c:753
watch_state_stack::bg_wrapped
bg_watched_channel * bg_wrapped
Definition: rb_channel.c:336
Init_grpc_propagate_masks
static void Init_grpc_propagate_masks()
Definition: rb_channel.c:773
channel
wrapped_grpc_channel * channel
Definition: src/php/ext/grpc/call.h:33
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
channel_init_try_register_stack::channel
grpc_channel * channel
Definition: rb_channel.c:103
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
GRPC_SSL_TARGET_NAME_OVERRIDE_ARG
#define GRPC_SSL_TARGET_NAME_OVERRIDE_ARG
Definition: grpc_types.h:278
grpc_rb_channel
struct grpc_rb_channel grpc_rb_channel
watch_state_op
Definition: rb_channel.c:78
channel_polling_thread_started
static int channel_polling_thread_started
Definition: rb_channel.c:111
grpc_rb_channel_destroy
static VALUE grpc_rb_channel_destroy(VALUE self)
Definition: rb_channel.c:487
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
gpr_mu_init
GPRAPI void gpr_mu_init(gpr_mu *mu)
setup.v
v
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
grpc_event
Definition: grpc_types.h:564
grpc_completion_queue
Definition: completion_queue.cc:347
run_poll_channels_loop_no_gil
static void * run_poll_channels_loop_no_gil(void *arg)
Definition: rb_channel.c:619
grpc_rb_is_channel_credentials
bool grpc_rb_is_channel_credentials(VALUE v)
Definition: rb_channel_credentials.c:284
wait_for_watch_state_op_complete_unblocking_func
static void wait_for_watch_state_op_complete_unblocking_func(void *arg)
Definition: rb_channel.c:371
grpc.h
grpc_call
struct grpc_call grpc_call
Definition: grpc_types.h:70
Init_grpc_channel
void Init_grpc_channel()
Definition: rb_channel.c:805
GRPC_PROPAGATE_CENSUS_STATS_CONTEXT
#define GRPC_PROPAGATE_CENSUS_STATS_CONTEXT
Definition: propagation_bits.h:35
grpc_insecure_credentials_create
GRPCAPI grpc_channel_credentials * grpc_insecure_credentials_create()
Definition: core/lib/security/credentials/insecure/insecure_credentials.cc:64
GRPC_CHANNEL_IDLE
@ GRPC_CHANNEL_IDLE
Definition: include/grpc/impl/codegen/connectivity_state.h:32
rb_channel_args.h
bg_watched_channel_list_head
static bg_watched_channel * bg_watched_channel_list_head
Definition: rb_channel.c:93
arg
Definition: cmdline.cc:40
gpr_cv_wait
GPRAPI int gpr_cv_wait(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline)
id_target
static ID id_target
Definition: rb_channel.c:48
grpc_slice
Definition: include/grpc/impl/codegen/slice.h:65
gpr_mu_lock
GPRAPI void gpr_mu_lock(gpr_mu *mu)
grpc_rb_channel_init
static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self)
Definition: rb_channel.c:213
watch_state_stack::deadline
gpr_timespec deadline
Definition: rb_channel.c:337
grpc_rb_cChannel
static VALUE grpc_rb_cChannel
Definition: rb_channel.c:54
stack
NodeStack stack
Definition: cord_rep_btree.cc:356
grpc_rb_channel_mark
static void grpc_rb_channel_mark(void *p)
Definition: rb_channel.c:173
Init_grpc_connectivity_states
static void Init_grpc_connectivity_states()
Definition: rb_channel.c:789
wrapper
grpc_channel_wrapper * wrapper
Definition: src/php/ext/grpc/channel.h:48
grpc_rb_channel_watch_connection_state_op_complete
static void grpc_rb_channel_watch_connection_state_op_complete(watch_state_op *op, int success)
Definition: rb_channel.c:120
grpc_rb_cChannelArgs
static VALUE grpc_rb_cChannelArgs
Definition: rb_channel.c:57
WATCH_STATE_API
@ WATCH_STATE_API
Definition: rb_channel.c:76
channel_polling_cq
static grpc_completion_queue * channel_polling_cq
Definition: rb_channel.c:107
rb_byte_buffer.h
grpc_rb_channel_free_internal
static void grpc_rb_channel_free_internal(void *p)
Definition: rb_channel.c:149
get_state_stack::try_to_connect
int try_to_connect
Definition: rb_channel.c:284
watch_state_op::success
int success
Definition: rb_channel.c:83
bg_watched_channel_list_free_and_remove
static void bg_watched_channel_list_free_and_remove(bg_watched_channel *bg)
Definition: rb_channel.c:541
grpc_op::op
grpc_op_type op
Definition: grpc_types.h:642
grpc_rb_channel_get_target
static VALUE grpc_rb_channel_get_target(VALUE self)
Definition: rb_channel.c:501
GRPC_CHANNEL_CONNECTING
@ GRPC_CHANNEL_CONNECTING
Definition: include/grpc/impl/codegen/connectivity_state.h:34
channel_init_try_register_stack::wrapper
grpc_rb_channel * wrapper
Definition: rb_channel.c:104
grpc_rb_channel_alloc
static VALUE grpc_rb_channel_alloc(VALUE cls)
Definition: rb_channel.c:197
grpc_slice_to_c_string
GPRAPI char * grpc_slice_to_c_string(grpc_slice s)
Definition: slice/slice.cc:35
grpc_channel_credentials_release
GRPCAPI void grpc_channel_credentials_release(grpc_channel_credentials *creds)
Definition: credentials.cc:36
grpc_channel_create_call
GRPCAPI grpc_call * grpc_channel_create_call(grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, grpc_completion_queue *completion_queue, grpc_slice method, const grpc_slice *host, gpr_timespec deadline, void *reserved)
Definition: channel.cc:311
rb_xds_channel_credentials.h
grpc_rb_channel_free
static void grpc_rb_channel_free(void *p)
Definition: rb_channel.c:167
memory_diff.cur
def cur
Definition: memory_diff.py:83
grpc_rb_channel_try_register_connection_polling
static void grpc_rb_channel_try_register_connection_polling(bg_watched_channel *bg)
Definition: rb_channel.c:580
rb_grpc.h
channel_init_try_register_stack
Definition: rb_channel.c:102
grpc_rb_get_wrapped_xds_channel_credentials
grpc_channel_credentials * grpc_rb_get_wrapped_xds_channel_credentials(VALUE v)
Definition: rb_xds_channel_credentials.c:208
grpc_channel_create
GRPCAPI grpc_channel * grpc_channel_create(const char *target, grpc_channel_credentials *creds, const grpc_channel_args *args)
Definition: chttp2_connector.cc:366
grpc_rb_mGrpcCore
VALUE grpc_rb_mGrpcCore
Definition: rb_grpc.c:252
grpc_slice_from_copied_buffer
GPRAPI grpc_slice grpc_slice_from_copied_buffer(const char *source, size_t len)
Definition: slice/slice.cc:170
grpc_rb_channel_get_connectivity_state
static VALUE grpc_rb_channel_get_connectivity_state(int argc, VALUE *argv, VALUE self)
Definition: rb_channel.c:313
GRPC_PROPAGATE_DEFAULTS
#define GRPC_PROPAGATE_DEFAULTS
Definition: propagation_bits.h:45
wait_until_channel_polling_thread_started_unblocking_func
static void wait_until_channel_polling_thread_started_unblocking_func(void *)
Definition: rb_channel.c:723
id_insecure_channel
static VALUE id_insecure_channel
Definition: rb_channel.c:51
absl::flags_internal
Definition: abseil-cpp/absl/flags/commandlineflag.h:40
channel_safe_destroy_without_gil
static void * channel_safe_destroy_without_gil(void *arg)
Definition: rb_channel.c:144
grpc_rb_time_timeval
gpr_timespec grpc_rb_time_timeval(VALUE time, int interval)
Definition: rb_grpc.c:98
gpr_mu
pthread_mutex_t gpr_mu
Definition: impl/codegen/sync_posix.h:47
grpc_completion_queue_destroy
GRPCAPI void grpc_completion_queue_destroy(grpc_completion_queue *cq)
Definition: completion_queue.cc:1424
watch_state_stack
struct watch_state_stack watch_state_stack
ALLOC
#define ALLOC(class_name)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1486
grpc_rb_wrap_call
VALUE grpc_rb_wrap_call(grpc_call *c, grpc_completion_queue *q)
Definition: rb_call.c:1042
grpc_rb_cannot_init_copy
VALUE grpc_rb_cannot_init_copy(VALUE copy, VALUE self)
Definition: rb_grpc.c:80
bg_watched_channel::refcount
int refcount
Definition: rb_channel.c:64
bg_watched_channel::next
struct bg_watched_channel * next
Definition: rb_channel.c:62
watch_state_op::bg
bg_watched_channel * bg
Definition: rb_channel.c:88
GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT
#define GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT
Definition: propagation_bits.h:36
alloc.h
global_connection_polling_mu
static gpr_mu global_connection_polling_mu
Definition: rb_channel.c:108
watch_state_stack::last_state
int last_state
Definition: rb_channel.c:338
grpc_channel_data_type
static rb_data_type_t grpc_channel_data_type
Definition: rb_channel.c:184
grpc_completion_queue_next
GRPCAPI grpc_event grpc_completion_queue_next(grpc_completion_queue *cq, gpr_timespec deadline, void *reserved)
Definition: completion_queue.cc:1133
grpc_completion_queue_shutdown
GRPCAPI void grpc_completion_queue_shutdown(grpc_completion_queue *cq)
Definition: completion_queue.cc:1416
rb_call.h
grpc_channel_destroy
GRPCAPI void grpc_channel_destroy(grpc_channel *channel)
Definition: channel.cc:437
grpc_rb_channel_watch_connectivity_state
static VALUE grpc_rb_channel_watch_connectivity_state(VALUE self, VALUE last_state, VALUE deadline)
Definition: rb_channel.c:388
grpc_ruby_fork_guard
void grpc_ruby_fork_guard()
Definition: rb_grpc.c:261
grpc_rb_channel_safe_destroy
static void grpc_rb_channel_safe_destroy(bg_watched_channel *bg)
Definition: rb_channel.c:130
rb_channel_credentials.h
grpc_channel
struct grpc_channel grpc_channel
Definition: grpc_types.h:62
grpc_rb_get_wrapped_call
grpc_call * grpc_rb_get_wrapped_call(VALUE v)
Definition: rb_call.c:1035
rb_channel.h
bg_watched_channel::channel_destroyed
int channel_destroyed
Definition: rb_channel.c:63
TYPE
#define TYPE(u, l)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:8202
grpc_channel_watch_connectivity_state
GRPCAPI void grpc_channel_watch_connectivity_state(grpc_channel *channel, grpc_connectivity_state last_observed_state, gpr_timespec deadline, grpc_completion_queue *cq, void *tag)
Definition: channel_connectivity.cc:227
gpr_cv_broadcast
GPRAPI void gpr_cv_broadcast(gpr_cv *cv)
GPR_DEBUG
#define GPR_DEBUG
Definition: include/grpc/impl/codegen/log.h:55
global_connection_polling_cv
static gpr_cv global_connection_polling_cv
Definition: rb_channel.c:109
grpc_rb_channel::bg_wrapped
bg_watched_channel * bg_wrapped
Definition: rb_channel.c:73
watch_state_op::continuous_watch_callback_args
struct watch_state_op::@49::@51 continuous_watch_callback_args
grpc_completion_queue_create_for_next
GRPCAPI grpc_completion_queue * grpc_completion_queue_create_for_next(void *reserved)
Definition: completion_queue_factory.cc:62
GRPC_CHANNEL_SHUTDOWN
@ GRPC_CHANNEL_SHUTDOWN
Definition: include/grpc/impl/codegen/connectivity_state.h:40
GRPC_PROPAGATE_DEADLINE
#define GRPC_PROPAGATE_DEADLINE
Definition: propagation_bits.h:33
ch
char ch
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3621
gpr_timespec
Definition: gpr_types.h:50
grpc_event::type
grpc_completion_type type
Definition: grpc_types.h:566
GPR_CLOCK_REALTIME
@ GPR_CLOCK_REALTIME
Definition: gpr_types.h:39
method
NSString * method
Definition: ProtoMethod.h:28
abort_channel_polling
static int abort_channel_polling
Definition: rb_channel.c:110
watch_state_op::op_type
watch_state_op_type op_type
Definition: rb_channel.c:79
bg_watched_channel_list_lookup
static int bg_watched_channel_list_lookup(bg_watched_channel *bg)
Definition: rb_channel.c:515
rb_server.h
CONTINUOUS_WATCH
@ CONTINUOUS_WATCH
Definition: rb_channel.c:76
op
static grpc_op * op
Definition: test/core/fling/client.cc:47
get_state_stack
Definition: rb_channel.c:282
grpc_event::success
int success
Definition: grpc_types.h:572
setup.target
target
Definition: third_party/bloaty/third_party/protobuf/python/setup.py:179
grpc_channel_credentials
Definition: src/core/lib/security/credentials/credentials.h:96
if
if(p->owned &&p->wrapped !=NULL)
Definition: call.c:42
grpc_event::tag
void * tag
Definition: grpc_types.h:576
cq
static grpc_completion_queue * cq
Definition: test/core/fling/client.cc:37
channel_init_try_register_connection_polling_without_gil
static void * channel_init_try_register_connection_polling_without_gil(void *arg)
Definition: rb_channel.c:566
grpc_ruby_init
void grpc_ruby_init()
Definition: rb_grpc.c:286
id_channel
static ID id_channel
Definition: rb_channel.c:43
gpr_cv_init
GPRAPI void gpr_cv_init(gpr_cv *cv)
grpc_rb_is_xds_channel_credentials
bool grpc_rb_is_xds_channel_credentials(VALUE v)
Definition: rb_xds_channel_credentials.c:216
GRPC_ARG_MAX_CONCURRENT_STREAMS
#define GRPC_ARG_MAX_CONCURRENT_STREAMS
Definition: grpc_types.h:150
GRPC_PROPAGATE_CANCELLATION
#define GRPC_PROPAGATE_CANCELLATION
Definition: propagation_bits.h:38
bg_watched_channel
struct bg_watched_channel bg_watched_channel


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:59