blob: f065a857db8ffeed207856c7e0dc53d28f38b4ee [file] [log] [blame]
nnoble097ef9b2014-12-01 17:06:10 -08001/*
2 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003 * Copyright 2015 gRPC authors.
nnoble097ef9b2014-12-01 17:06:10 -08004 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02005 * 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
nnoble097ef9b2014-12-01 17:06:10 -08008 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009 * http://www.apache.org/licenses/LICENSE-2.0
nnoble097ef9b2014-12-01 17:06:10 -080010 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +020011 * 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.
nnoble097ef9b2014-12-01 17:06:10 -080016 *
17 */
18
Nicolas "Pixel" Nobled51d1212016-01-31 11:33:19 +010019#include <ruby/ruby.h>
Nicolas "Pixel" Noble9fcdc872016-05-05 06:15:34 +020020
nnoble097ef9b2014-12-01 17:06:10 -080021#include "rb_grpc.h"
Craig Tiller5b1c5f22017-04-19 09:52:18 -070022#include "rb_grpc_imports.generated.h"
nnoble097ef9b2014-12-01 17:06:10 -080023
24#include <math.h>
Yuki Yugui Sonoda22887912015-04-16 20:57:17 +090025#include <ruby/vm.h>
nnoble097ef9b2014-12-01 17:06:10 -080026#include <sys/time.h>
27
28#include <grpc/grpc.h>
29#include <grpc/support/time.h>
nnoble097ef9b2014-12-01 17:06:10 -080030#include "rb_call.h"
murgatroid999946f2b2015-12-04 14:36:27 -080031#include "rb_call_credentials.h"
nnoble097ef9b2014-12-01 17:06:10 -080032#include "rb_channel.h"
Tim Emiola9332ea62015-10-27 23:48:29 -070033#include "rb_channel_credentials.h"
Craig Tiller5b1c5f22017-04-19 09:52:18 -070034#include "rb_compression_options.h"
murgatroid99ce67bff2017-04-19 15:54:27 -070035#include "rb_event_thread.h"
Nicolas "Pixel" Nobled51d1212016-01-31 11:33:19 +010036#include "rb_loader.h"
nnoble097ef9b2014-12-01 17:06:10 -080037#include "rb_server.h"
nnoble0c475f02014-12-05 15:37:39 -080038#include "rb_server_credentials.h"
nnoble097ef9b2014-12-01 17:06:10 -080039
Yuki Yugui Sonoda3c88e5d2015-04-16 20:09:00 +090040static VALUE grpc_rb_cTimeVal = Qnil;
nnoble097ef9b2014-12-01 17:06:10 -080041
Yuki Yugui Sonodad441c2e2015-04-11 15:33:58 +090042static rb_data_type_t grpc_rb_timespec_data_type = {
43 "gpr_timespec",
Craig Tiller5b1c5f22017-04-19 09:52:18 -070044 {GRPC_RB_GC_NOT_MARKED,
45 GRPC_RB_GC_DONT_FREE,
46 GRPC_RB_MEMSIZE_UNAVAILABLE,
murgatroid9987afb5d2015-07-16 16:01:02 -070047 {NULL, NULL}},
Yuki Yugui Sonodad441c2e2015-04-11 15:33:58 +090048 NULL,
49 NULL,
Tim Emiola9161a822015-11-11 15:58:44 -080050#ifdef RUBY_TYPED_FREE_IMMEDIATELY
51 RUBY_TYPED_FREE_IMMEDIATELY
52#endif
53};
Yuki Yugui Sonodad441c2e2015-04-11 15:33:58 +090054
nnoble097ef9b2014-12-01 17:06:10 -080055/* Alloc func that blocks allocation of a given object by raising an
56 * exception. */
57VALUE grpc_rb_cannot_alloc(VALUE cls) {
58 rb_raise(rb_eTypeError,
59 "allocation of %s only allowed from the gRPC native layer",
60 rb_class2name(cls));
61 return Qnil;
62}
63
64/* Init func that fails by raising an exception. */
65VALUE grpc_rb_cannot_init(VALUE self) {
66 rb_raise(rb_eTypeError,
67 "initialization of %s only allowed from the gRPC native layer",
68 rb_obj_classname(self));
69 return Qnil;
70}
71
72/* Init/Clone func that fails by raising an exception. */
73VALUE grpc_rb_cannot_init_copy(VALUE copy, VALUE self) {
murgatroid9987afb5d2015-07-16 16:01:02 -070074 (void)self;
Craig Tiller5b1c5f22017-04-19 09:52:18 -070075 rb_raise(rb_eTypeError, "Copy initialization of %s is not supported",
nnoble097ef9b2014-12-01 17:06:10 -080076 rb_obj_classname(copy));
77 return Qnil;
78}
79
80/* id_tv_{,u}sec are accessor methods on Ruby Time instances. */
81static ID id_tv_sec;
82static ID id_tv_nsec;
83
84/**
Jan Tattermusch88086372015-12-10 10:54:12 -080085 * grpc_rb_time_timeval creates a timeval from a ruby time object.
nnoble097ef9b2014-12-01 17:06:10 -080086 *
87 * This func is copied from ruby source, MRI/source/time.c, which is published
88 * under the same license as the ruby.h, on which the entire extensions is
89 * based.
90 */
91gpr_timespec grpc_rb_time_timeval(VALUE time, int interval) {
92 gpr_timespec t;
Craig Tillerbaa14a92017-11-03 09:09:36 -070093 gpr_timespec* time_const;
94 const char* tstr = interval ? "time interval" : "time";
95 const char* want = " want <secs from epoch>|<Time>|<GRPC::TimeConst.*>";
nnoble097ef9b2014-12-01 17:06:10 -080096
Craig Tiller5a1e7fd2015-07-14 07:14:47 -070097 t.clock_type = GPR_CLOCK_REALTIME;
nnoble097ef9b2014-12-01 17:06:10 -080098 switch (TYPE(time)) {
nnoble097ef9b2014-12-01 17:06:10 -080099 case T_DATA:
Yuki Yugui Sonodaa7d369e2015-04-11 11:48:36 +0900100 if (CLASS_OF(time) == grpc_rb_cTimeVal) {
Yuki Yugui Sonodad441c2e2015-04-11 15:33:58 +0900101 TypedData_Get_Struct(time, gpr_timespec, &grpc_rb_timespec_data_type,
102 time_const);
nnoble097ef9b2014-12-01 17:06:10 -0800103 t = *time_const;
104 } else if (CLASS_OF(time) == rb_cTime) {
Craig Tillerb5dcec52015-01-13 11:13:42 -0800105 t.tv_sec = NUM2INT(rb_funcall(time, id_tv_sec, 0));
nnoble097ef9b2014-12-01 17:06:10 -0800106 t.tv_nsec = NUM2INT(rb_funcall(time, id_tv_nsec, 0));
107 } else {
Craig Tillerb5dcec52015-01-13 11:13:42 -0800108 rb_raise(rb_eTypeError, "bad input: (%s)->c_timeval, got <%s>,%s", tstr,
109 rb_obj_classname(time), want);
nnoble097ef9b2014-12-01 17:06:10 -0800110 }
111 break;
112
113 case T_FIXNUM:
114 t.tv_sec = FIX2LONG(time);
115 if (interval && t.tv_sec < 0)
116 rb_raise(rb_eArgError, "%s must be positive", tstr);
117 t.tv_nsec = 0;
118 break;
119
120 case T_FLOAT:
mattnb9e15632015-02-28 23:45:58 +0900121 if (interval && RFLOAT_VALUE(time) < 0.0)
nnoble097ef9b2014-12-01 17:06:10 -0800122 rb_raise(rb_eArgError, "%s must be positive", tstr);
123 else {
124 double f, d;
125
mattnb9e15632015-02-28 23:45:58 +0900126 d = modf(RFLOAT_VALUE(time), &f);
nnoble097ef9b2014-12-01 17:06:10 -0800127 if (d < 0) {
128 d += 1;
129 f -= 1;
130 }
Craig Tiller7536af02015-12-22 13:49:30 -0800131 t.tv_sec = (int64_t)f;
nnoble097ef9b2014-12-01 17:06:10 -0800132 if (f != t.tv_sec) {
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700133 rb_raise(rb_eRangeError, "%f out of Time range", RFLOAT_VALUE(time));
nnoble097ef9b2014-12-01 17:06:10 -0800134 }
Marcin Wyszynski1a2ac332015-07-23 20:12:33 +0200135 t.tv_nsec = (int)(d * 1e9 + 0.5);
nnoble097ef9b2014-12-01 17:06:10 -0800136 }
137 break;
138
139 case T_BIGNUM:
140 t.tv_sec = NUM2LONG(time);
141 if (interval && t.tv_sec < 0)
142 rb_raise(rb_eArgError, "%s must be positive", tstr);
143 t.tv_nsec = 0;
144 break;
145
146 default:
Craig Tillerb5dcec52015-01-13 11:13:42 -0800147 rb_raise(rb_eTypeError, "bad input: (%s)->c_timeval, got <%s>,%s", tstr,
148 rb_obj_classname(time), want);
nnoble097ef9b2014-12-01 17:06:10 -0800149 break;
150 }
151 return t;
152}
153
Yuki Yugui Sonodaf0eee5f2015-04-16 20:25:28 +0900154static void Init_grpc_status_codes() {
temiola58327912014-12-15 17:51:16 -0800155 /* Constants representing the status codes or grpc_status_code in status.h */
Yuki Yugui Sonodaa7d369e2015-04-11 11:48:36 +0900156 VALUE grpc_rb_mStatusCodes =
157 rb_define_module_under(grpc_rb_mGrpcCore, "StatusCodes");
158 rb_define_const(grpc_rb_mStatusCodes, "OK", INT2NUM(GRPC_STATUS_OK));
159 rb_define_const(grpc_rb_mStatusCodes, "CANCELLED",
160 INT2NUM(GRPC_STATUS_CANCELLED));
161 rb_define_const(grpc_rb_mStatusCodes, "UNKNOWN",
162 INT2NUM(GRPC_STATUS_UNKNOWN));
163 rb_define_const(grpc_rb_mStatusCodes, "INVALID_ARGUMENT",
temiola58327912014-12-15 17:51:16 -0800164 INT2NUM(GRPC_STATUS_INVALID_ARGUMENT));
Yuki Yugui Sonodaa7d369e2015-04-11 11:48:36 +0900165 rb_define_const(grpc_rb_mStatusCodes, "DEADLINE_EXCEEDED",
temiola58327912014-12-15 17:51:16 -0800166 INT2NUM(GRPC_STATUS_DEADLINE_EXCEEDED));
Yuki Yugui Sonodaa7d369e2015-04-11 11:48:36 +0900167 rb_define_const(grpc_rb_mStatusCodes, "NOT_FOUND",
168 INT2NUM(GRPC_STATUS_NOT_FOUND));
169 rb_define_const(grpc_rb_mStatusCodes, "ALREADY_EXISTS",
temiola58327912014-12-15 17:51:16 -0800170 INT2NUM(GRPC_STATUS_ALREADY_EXISTS));
Yuki Yugui Sonodaa7d369e2015-04-11 11:48:36 +0900171 rb_define_const(grpc_rb_mStatusCodes, "PERMISSION_DENIED",
temiola58327912014-12-15 17:51:16 -0800172 INT2NUM(GRPC_STATUS_PERMISSION_DENIED));
Yuki Yugui Sonodaa7d369e2015-04-11 11:48:36 +0900173 rb_define_const(grpc_rb_mStatusCodes, "UNAUTHENTICATED",
temiola58327912014-12-15 17:51:16 -0800174 INT2NUM(GRPC_STATUS_UNAUTHENTICATED));
Yuki Yugui Sonodaa7d369e2015-04-11 11:48:36 +0900175 rb_define_const(grpc_rb_mStatusCodes, "RESOURCE_EXHAUSTED",
temiola58327912014-12-15 17:51:16 -0800176 INT2NUM(GRPC_STATUS_RESOURCE_EXHAUSTED));
Yuki Yugui Sonodaa7d369e2015-04-11 11:48:36 +0900177 rb_define_const(grpc_rb_mStatusCodes, "FAILED_PRECONDITION",
temiola58327912014-12-15 17:51:16 -0800178 INT2NUM(GRPC_STATUS_FAILED_PRECONDITION));
Yuki Yugui Sonodaa7d369e2015-04-11 11:48:36 +0900179 rb_define_const(grpc_rb_mStatusCodes, "ABORTED",
180 INT2NUM(GRPC_STATUS_ABORTED));
181 rb_define_const(grpc_rb_mStatusCodes, "OUT_OF_RANGE",
temiola58327912014-12-15 17:51:16 -0800182 INT2NUM(GRPC_STATUS_OUT_OF_RANGE));
Yuki Yugui Sonodaa7d369e2015-04-11 11:48:36 +0900183 rb_define_const(grpc_rb_mStatusCodes, "UNIMPLEMENTED",
temiola58327912014-12-15 17:51:16 -0800184 INT2NUM(GRPC_STATUS_UNIMPLEMENTED));
Yuki Yugui Sonodaa7d369e2015-04-11 11:48:36 +0900185 rb_define_const(grpc_rb_mStatusCodes, "INTERNAL",
186 INT2NUM(GRPC_STATUS_INTERNAL));
187 rb_define_const(grpc_rb_mStatusCodes, "UNAVAILABLE",
temiola58327912014-12-15 17:51:16 -0800188 INT2NUM(GRPC_STATUS_UNAVAILABLE));
Yuki Yugui Sonodaa7d369e2015-04-11 11:48:36 +0900189 rb_define_const(grpc_rb_mStatusCodes, "DATA_LOSS",
190 INT2NUM(GRPC_STATUS_DATA_LOSS));
temiola58327912014-12-15 17:51:16 -0800191}
192
nnoble097ef9b2014-12-01 17:06:10 -0800193/* id_at is the constructor method of the ruby standard Time class. */
194static ID id_at;
195
196/* id_inspect is the inspect method found on various ruby objects. */
197static ID id_inspect;
198
199/* id_to_s is the to_s method found on various ruby objects. */
200static ID id_to_s;
201
Tim Emiola98a32d32015-03-28 01:48:44 -0700202/* Converts a wrapped time constant to a standard time. */
Yuki Yugui Sonodaf0eee5f2015-04-16 20:25:28 +0900203static VALUE grpc_rb_time_val_to_time(VALUE self) {
Craig Tillerbaa14a92017-11-03 09:09:36 -0700204 gpr_timespec* time_const = NULL;
Craig Tiller94329d02015-07-23 09:52:11 -0700205 gpr_timespec real_time;
Yuki Yugui Sonodad441c2e2015-04-11 15:33:58 +0900206 TypedData_Get_Struct(self, gpr_timespec, &grpc_rb_timespec_data_type,
207 time_const);
Craig Tiller94329d02015-07-23 09:52:11 -0700208 real_time = gpr_convert_clock_type(*time_const, GPR_CLOCK_REALTIME);
209 return rb_funcall(rb_cTime, id_at, 2, INT2NUM(real_time.tv_sec),
Eric Richardson8e769fd2016-07-08 12:36:54 -0400210 INT2NUM(real_time.tv_nsec / 1000));
nnoble097ef9b2014-12-01 17:06:10 -0800211}
212
213/* Invokes inspect on the ctime version of the time val. */
Yuki Yugui Sonodaf0eee5f2015-04-16 20:25:28 +0900214static VALUE grpc_rb_time_val_inspect(VALUE self) {
nnoble097ef9b2014-12-01 17:06:10 -0800215 return rb_funcall(grpc_rb_time_val_to_time(self), id_inspect, 0);
216}
217
218/* Invokes to_s on the ctime version of the time val. */
Yuki Yugui Sonodaf0eee5f2015-04-16 20:25:28 +0900219static VALUE grpc_rb_time_val_to_s(VALUE self) {
nnoble097ef9b2014-12-01 17:06:10 -0800220 return rb_funcall(grpc_rb_time_val_to_time(self), id_to_s, 0);
221}
222
Craig Tiller354398f2015-07-13 09:16:03 -0700223static gpr_timespec zero_realtime;
224static gpr_timespec inf_future_realtime;
225static gpr_timespec inf_past_realtime;
226
nnoble097ef9b2014-12-01 17:06:10 -0800227/* Adds a module with constants that map to gpr's static timeval structs. */
Yuki Yugui Sonodaf0eee5f2015-04-16 20:25:28 +0900228static void Init_grpc_time_consts() {
Yuki Yugui Sonodaa7d369e2015-04-11 11:48:36 +0900229 VALUE grpc_rb_mTimeConsts =
230 rb_define_module_under(grpc_rb_mGrpcCore, "TimeConsts");
231 grpc_rb_cTimeVal =
232 rb_define_class_under(grpc_rb_mGrpcCore, "TimeSpec", rb_cObject);
Craig Tiller354398f2015-07-13 09:16:03 -0700233 zero_realtime = gpr_time_0(GPR_CLOCK_REALTIME);
234 inf_future_realtime = gpr_inf_future(GPR_CLOCK_REALTIME);
235 inf_past_realtime = gpr_inf_past(GPR_CLOCK_REALTIME);
Yuki Yugui Sonodad441c2e2015-04-11 15:33:58 +0900236 rb_define_const(
237 grpc_rb_mTimeConsts, "ZERO",
238 TypedData_Wrap_Struct(grpc_rb_cTimeVal, &grpc_rb_timespec_data_type,
Craig Tillerbaa14a92017-11-03 09:09:36 -0700239 (void*)&zero_realtime));
Yuki Yugui Sonodad441c2e2015-04-11 15:33:58 +0900240 rb_define_const(
241 grpc_rb_mTimeConsts, "INFINITE_FUTURE",
242 TypedData_Wrap_Struct(grpc_rb_cTimeVal, &grpc_rb_timespec_data_type,
Craig Tillerbaa14a92017-11-03 09:09:36 -0700243 (void*)&inf_future_realtime));
Yuki Yugui Sonodad441c2e2015-04-11 15:33:58 +0900244 rb_define_const(
245 grpc_rb_mTimeConsts, "INFINITE_PAST",
246 TypedData_Wrap_Struct(grpc_rb_cTimeVal, &grpc_rb_timespec_data_type,
Craig Tillerbaa14a92017-11-03 09:09:36 -0700247 (void*)&inf_past_realtime));
Yuki Yugui Sonodaa7d369e2015-04-11 11:48:36 +0900248 rb_define_method(grpc_rb_cTimeVal, "to_time", grpc_rb_time_val_to_time, 0);
249 rb_define_method(grpc_rb_cTimeVal, "inspect", grpc_rb_time_val_inspect, 0);
250 rb_define_method(grpc_rb_cTimeVal, "to_s", grpc_rb_time_val_to_s, 0);
nnoble097ef9b2014-12-01 17:06:10 -0800251 id_at = rb_intern("at");
252 id_inspect = rb_intern("inspect");
253 id_to_s = rb_intern("to_s");
254 id_tv_sec = rb_intern("tv_sec");
255 id_tv_nsec = rb_intern("tv_nsec");
256}
257
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700258static void grpc_rb_shutdown(void) { grpc_shutdown(); }
nnoble097ef9b2014-12-01 17:06:10 -0800259
Tim Emiola409e6c82015-02-17 17:46:35 -0800260/* Initialize the GRPC module structs */
temiola21bb60c2014-12-18 10:58:22 -0800261
Yuki Yugui Sonodaa7d369e2015-04-11 11:48:36 +0900262/* grpc_rb_sNewServerRpc is the struct that holds new server rpc details. */
263VALUE grpc_rb_sNewServerRpc = Qnil;
264/* grpc_rb_sStatus is the struct that holds status details. */
265VALUE grpc_rb_sStatus = Qnil;
temiola21bb60c2014-12-18 10:58:22 -0800266
Tim Emiola409e6c82015-02-17 17:46:35 -0800267/* Initialize the GRPC module. */
Yuki Yugui Sonodaa7d369e2015-04-11 11:48:36 +0900268VALUE grpc_rb_mGRPC = Qnil;
269VALUE grpc_rb_mGrpcCore = Qnil;
temiola21bb60c2014-12-18 10:58:22 -0800270
Yuki Yugui Sonoda99eb9f92015-04-16 20:09:55 +0900271/* cached Symbols for members in Status struct */
272VALUE sym_code = Qundef;
273VALUE sym_details = Qundef;
274VALUE sym_metadata = Qundef;
275
Nicolas "Pixel" Noblecb903972016-02-21 22:58:26 +0100276static gpr_once g_once_init = GPR_ONCE_INIT;
277
Alexander Polcyn2a9b5d72017-04-14 12:10:55 -0700278static void grpc_ruby_once_init_internal() {
Nicolas "Pixel" Noblecb903972016-02-21 22:58:26 +0100279 grpc_init();
280 atexit(grpc_rb_shutdown);
281}
282
Alexander Polcyn5c6dda82017-05-17 13:08:34 -0700283static VALUE bg_thread_init_rb_mu = Qundef;
284static int bg_thread_init_done = 0;
285
Alexander Polcyn2a9b5d72017-04-14 12:10:55 -0700286void grpc_ruby_once_init() {
Nicolas "Pixel" Noble88dc3c52016-02-22 03:21:08 +0100287 /* ruby_vm_at_exit doesn't seem to be working. It would crash once every
288 * blue moon, and some users are getting it repeatedly. See the discussions
289 * - https://github.com/grpc/grpc/pull/5337
290 * - https://bugs.ruby-lang.org/issues/12095
291 *
292 * In order to still be able to handle the (unlikely) situation where the
293 * extension is loaded by a first Ruby VM that is subsequently destroyed,
294 * then loaded again by another VM within the same process, we need to
295 * schedule our initialization and destruction only once.
296 */
Alexander Polcyn2a9b5d72017-04-14 12:10:55 -0700297 gpr_once_init(&g_once_init, grpc_ruby_once_init_internal);
Alexander Polcyn5c6dda82017-05-17 13:08:34 -0700298
299 // Avoid calling calling into ruby library (when creating threads here)
300 // in gpr_once_init. In general, it appears to be unsafe to call
301 // into the ruby library while holding a non-ruby mutex, because a gil yield
302 // could end up trying to lock onto that same mutex and deadlocking.
303 rb_mutex_lock(bg_thread_init_rb_mu);
304 if (!bg_thread_init_done) {
305 grpc_rb_event_queue_thread_start();
306 grpc_rb_channel_polling_thread_start();
307 bg_thread_init_done = 1;
308 }
309 rb_mutex_unlock(bg_thread_init_rb_mu);
Alexander Polcyn2a9b5d72017-04-14 12:10:55 -0700310}
311
312void Init_grpc_c() {
313 if (!grpc_rb_load_core()) {
314 rb_raise(rb_eLoadError, "Couldn't find or load gRPC's dynamic C core");
315 return;
316 }
Tim Emiola9161a822015-11-11 15:58:44 -0800317
Alexander Polcyn5c6dda82017-05-17 13:08:34 -0700318 rb_global_variable(&bg_thread_init_rb_mu);
Alexander Polcyn8c12d9e2017-10-05 08:47:39 -0700319 bg_thread_init_rb_mu = rb_mutex_new();
Alexander Polcyn5c6dda82017-05-17 13:08:34 -0700320
Yuki Yugui Sonodaa7d369e2015-04-11 11:48:36 +0900321 grpc_rb_mGRPC = rb_define_module("GRPC");
322 grpc_rb_mGrpcCore = rb_define_module_under(grpc_rb_mGRPC, "Core");
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700323 grpc_rb_sNewServerRpc = rb_struct_define(
324 "NewServerRpc", "method", "host", "deadline", "metadata", "call", NULL);
Yuki Yugui Sonodaa7d369e2015-04-11 11:48:36 +0900325 grpc_rb_sStatus =
326 rb_struct_define("Status", "code", "details", "metadata", NULL);
Tim Emiola98a32d32015-03-28 01:48:44 -0700327 sym_code = ID2SYM(rb_intern("code"));
328 sym_details = ID2SYM(rb_intern("details"));
329 sym_metadata = ID2SYM(rb_intern("metadata"));
nnoble097ef9b2014-12-01 17:06:10 -0800330
Tim Emiola409e6c82015-02-17 17:46:35 -0800331 Init_grpc_channel();
Tim Emiola409e6c82015-02-17 17:46:35 -0800332 Init_grpc_call();
murgatroid999946f2b2015-12-04 14:36:27 -0800333 Init_grpc_call_credentials();
Tim Emiola9332ea62015-10-27 23:48:29 -0700334 Init_grpc_channel_credentials();
Tim Emiola409e6c82015-02-17 17:46:35 -0800335 Init_grpc_server();
336 Init_grpc_server_credentials();
337 Init_grpc_status_codes();
338 Init_grpc_time_consts();
Alexander Polcyn0dccf102016-06-27 13:11:07 -0700339 Init_grpc_compression_options();
nnoble097ef9b2014-12-01 17:06:10 -0800340}