grpc 1.30.2-x86-linux

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 (121) hide show
  1. checksums.yaml +7 -0
  2. data/etc/roots.pem +4644 -0
  3. data/grpc_c.32.ruby +0 -0
  4. data/grpc_c.64.ruby +0 -0
  5. data/src/ruby/bin/math_client.rb +140 -0
  6. data/src/ruby/bin/math_pb.rb +34 -0
  7. data/src/ruby/bin/math_server.rb +191 -0
  8. data/src/ruby/bin/math_services_pb.rb +51 -0
  9. data/src/ruby/bin/noproto_client.rb +93 -0
  10. data/src/ruby/bin/noproto_server.rb +97 -0
  11. data/src/ruby/ext/grpc/ext-export.clang +1 -0
  12. data/src/ruby/ext/grpc/ext-export.gcc +6 -0
  13. data/src/ruby/ext/grpc/extconf.rb +107 -0
  14. data/src/ruby/ext/grpc/rb_byte_buffer.c +64 -0
  15. data/src/ruby/ext/grpc/rb_byte_buffer.h +35 -0
  16. data/src/ruby/ext/grpc/rb_call.c +1050 -0
  17. data/src/ruby/ext/grpc/rb_call.h +53 -0
  18. data/src/ruby/ext/grpc/rb_call_credentials.c +297 -0
  19. data/src/ruby/ext/grpc/rb_call_credentials.h +31 -0
  20. data/src/ruby/ext/grpc/rb_channel.c +835 -0
  21. data/src/ruby/ext/grpc/rb_channel.h +34 -0
  22. data/src/ruby/ext/grpc/rb_channel_args.c +155 -0
  23. data/src/ruby/ext/grpc/rb_channel_args.h +38 -0
  24. data/src/ruby/ext/grpc/rb_channel_credentials.c +267 -0
  25. data/src/ruby/ext/grpc/rb_channel_credentials.h +32 -0
  26. data/src/ruby/ext/grpc/rb_completion_queue.c +100 -0
  27. data/src/ruby/ext/grpc/rb_completion_queue.h +36 -0
  28. data/src/ruby/ext/grpc/rb_compression_options.c +470 -0
  29. data/src/ruby/ext/grpc/rb_compression_options.h +29 -0
  30. data/src/ruby/ext/grpc/rb_enable_cpp.cc +22 -0
  31. data/src/ruby/ext/grpc/rb_event_thread.c +143 -0
  32. data/src/ruby/ext/grpc/rb_event_thread.h +21 -0
  33. data/src/ruby/ext/grpc/rb_grpc.c +328 -0
  34. data/src/ruby/ext/grpc/rb_grpc.h +76 -0
  35. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +573 -0
  36. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +865 -0
  37. data/src/ruby/ext/grpc/rb_loader.c +57 -0
  38. data/src/ruby/ext/grpc/rb_loader.h +25 -0
  39. data/src/ruby/ext/grpc/rb_server.c +372 -0
  40. data/src/ruby/ext/grpc/rb_server.h +32 -0
  41. data/src/ruby/ext/grpc/rb_server_credentials.c +243 -0
  42. data/src/ruby/ext/grpc/rb_server_credentials.h +32 -0
  43. data/src/ruby/lib/grpc.rb +37 -0
  44. data/src/ruby/lib/grpc/2.3/grpc_c.so +0 -0
  45. data/src/ruby/lib/grpc/2.4/grpc_c.so +0 -0
  46. data/src/ruby/lib/grpc/2.5/grpc_c.so +0 -0
  47. data/src/ruby/lib/grpc/2.6/grpc_c.so +0 -0
  48. data/src/ruby/lib/grpc/2.7/grpc_c.so +0 -0
  49. data/src/ruby/lib/grpc/core/status_codes.rb +135 -0
  50. data/src/ruby/lib/grpc/core/time_consts.rb +56 -0
  51. data/src/ruby/lib/grpc/errors.rb +277 -0
  52. data/src/ruby/lib/grpc/generic/active_call.rb +669 -0
  53. data/src/ruby/lib/grpc/generic/bidi_call.rb +233 -0
  54. data/src/ruby/lib/grpc/generic/client_stub.rb +501 -0
  55. data/src/ruby/lib/grpc/generic/interceptor_registry.rb +53 -0
  56. data/src/ruby/lib/grpc/generic/interceptors.rb +186 -0
  57. data/src/ruby/lib/grpc/generic/rpc_desc.rb +204 -0
  58. data/src/ruby/lib/grpc/generic/rpc_server.rb +551 -0
  59. data/src/ruby/lib/grpc/generic/service.rb +211 -0
  60. data/src/ruby/lib/grpc/google_rpc_status_utils.rb +40 -0
  61. data/src/ruby/lib/grpc/grpc.rb +24 -0
  62. data/src/ruby/lib/grpc/logconfig.rb +44 -0
  63. data/src/ruby/lib/grpc/notifier.rb +45 -0
  64. data/src/ruby/lib/grpc/structs.rb +15 -0
  65. data/src/ruby/lib/grpc/version.rb +18 -0
  66. data/src/ruby/pb/README.md +42 -0
  67. data/src/ruby/pb/generate_proto_ruby.sh +51 -0
  68. data/src/ruby/pb/grpc/health/checker.rb +75 -0
  69. data/src/ruby/pb/grpc/health/v1/health_pb.rb +31 -0
  70. data/src/ruby/pb/grpc/health/v1/health_services_pb.rb +62 -0
  71. data/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services_pb.rb +44 -0
  72. data/src/ruby/pb/grpc/testing/metrics_pb.rb +28 -0
  73. data/src/ruby/pb/grpc/testing/metrics_services_pb.rb +49 -0
  74. data/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb +17 -0
  75. data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +105 -0
  76. data/src/ruby/pb/src/proto/grpc/testing/test_pb.rb +16 -0
  77. data/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb +118 -0
  78. data/src/ruby/pb/test/client.rb +769 -0
  79. data/src/ruby/pb/test/server.rb +252 -0
  80. data/src/ruby/pb/test/xds_client.rb +213 -0
  81. data/src/ruby/spec/call_credentials_spec.rb +42 -0
  82. data/src/ruby/spec/call_spec.rb +180 -0
  83. data/src/ruby/spec/channel_connection_spec.rb +126 -0
  84. data/src/ruby/spec/channel_credentials_spec.rb +82 -0
  85. data/src/ruby/spec/channel_spec.rb +234 -0
  86. data/src/ruby/spec/client_auth_spec.rb +126 -0
  87. data/src/ruby/spec/client_server_spec.rb +664 -0
  88. data/src/ruby/spec/compression_options_spec.rb +149 -0
  89. data/src/ruby/spec/debug_message_spec.rb +134 -0
  90. data/src/ruby/spec/error_sanity_spec.rb +49 -0
  91. data/src/ruby/spec/errors_spec.rb +142 -0
  92. data/src/ruby/spec/generic/active_call_spec.rb +672 -0
  93. data/src/ruby/spec/generic/client_interceptors_spec.rb +153 -0
  94. data/src/ruby/spec/generic/client_stub_spec.rb +1083 -0
  95. data/src/ruby/spec/generic/interceptor_registry_spec.rb +65 -0
  96. data/src/ruby/spec/generic/rpc_desc_spec.rb +374 -0
  97. data/src/ruby/spec/generic/rpc_server_pool_spec.rb +127 -0
  98. data/src/ruby/spec/generic/rpc_server_spec.rb +748 -0
  99. data/src/ruby/spec/generic/server_interceptors_spec.rb +218 -0
  100. data/src/ruby/spec/generic/service_spec.rb +263 -0
  101. data/src/ruby/spec/google_rpc_status_utils_spec.rb +282 -0
  102. data/src/ruby/spec/pb/codegen/grpc/testing/package_options.proto +28 -0
  103. data/src/ruby/spec/pb/codegen/grpc/testing/package_options_import.proto +22 -0
  104. data/src/ruby/spec/pb/codegen/grpc/testing/package_options_import2.proto +23 -0
  105. data/src/ruby/spec/pb/codegen/grpc/testing/package_options_ruby_style.proto +41 -0
  106. data/src/ruby/spec/pb/codegen/package_option_spec.rb +82 -0
  107. data/src/ruby/spec/pb/duplicate/codegen_spec.rb +57 -0
  108. data/src/ruby/spec/pb/health/checker_spec.rb +236 -0
  109. data/src/ruby/spec/server_credentials_spec.rb +79 -0
  110. data/src/ruby/spec/server_spec.rb +209 -0
  111. data/src/ruby/spec/spec_helper.rb +61 -0
  112. data/src/ruby/spec/support/helpers.rb +107 -0
  113. data/src/ruby/spec/support/services.rb +160 -0
  114. data/src/ruby/spec/testdata/README +1 -0
  115. data/src/ruby/spec/testdata/ca.pem +20 -0
  116. data/src/ruby/spec/testdata/client.key +28 -0
  117. data/src/ruby/spec/testdata/client.pem +20 -0
  118. data/src/ruby/spec/testdata/server1.key +28 -0
  119. data/src/ruby/spec/testdata/server1.pem +22 -0
  120. data/src/ruby/spec/time_consts_spec.rb +74 -0
  121. metadata +394 -0
@@ -0,0 +1,29 @@
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
+ #ifndef GRPC_RB_COMPRESSION_OPTIONS_H_
20
+ #define GRPC_RB_COMPRESSION_OPTIONS_H_
21
+
22
+ #include <ruby/ruby.h>
23
+
24
+ #include <grpc/grpc.h>
25
+
26
+ /* Initializes the compression options ruby wrapper. */
27
+ void Init_grpc_compression_options();
28
+
29
+ #endif /* GRPC_RB_COMPRESSION_OPTIONS_H_ */
@@ -0,0 +1,22 @@
1
+ /*
2
+ *
3
+ * Copyright 2019 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
+ // This is a dummy C++ source file to trigger ruby extension builder to
22
+ // pick C++ rather than C linker to link with c++ library properly.
@@ -0,0 +1,143 @@
1
+ /*
2
+ *
3
+ * Copyright 2016 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_event_thread.h"
22
+ #include "rb_grpc_imports.generated.h"
23
+
24
+ #include <stdbool.h>
25
+
26
+ #include <grpc/support/alloc.h>
27
+ #include <grpc/support/log.h>
28
+ #include <grpc/support/sync.h>
29
+ #include <grpc/support/time.h>
30
+ #include <ruby/thread.h>
31
+
32
+ typedef struct grpc_rb_event {
33
+ // callback will be called with argument while holding the GVL
34
+ void (*callback)(void*);
35
+ void* argument;
36
+
37
+ struct grpc_rb_event* next;
38
+ } grpc_rb_event;
39
+
40
+ typedef struct grpc_rb_event_queue {
41
+ grpc_rb_event* head;
42
+ grpc_rb_event* tail;
43
+
44
+ gpr_mu mu;
45
+ gpr_cv cv;
46
+
47
+ // Indicates that the thread should stop waiting
48
+ bool abort;
49
+ } grpc_rb_event_queue;
50
+
51
+ static grpc_rb_event_queue event_queue;
52
+
53
+ void grpc_rb_event_queue_enqueue(void (*callback)(void*), void* argument) {
54
+ grpc_rb_event* event = gpr_malloc(sizeof(grpc_rb_event));
55
+ event->callback = callback;
56
+ event->argument = argument;
57
+ event->next = NULL;
58
+ gpr_mu_lock(&event_queue.mu);
59
+ if (event_queue.tail == NULL) {
60
+ event_queue.head = event_queue.tail = event;
61
+ } else {
62
+ event_queue.tail->next = event;
63
+ event_queue.tail = event;
64
+ }
65
+ gpr_cv_signal(&event_queue.cv);
66
+ gpr_mu_unlock(&event_queue.mu);
67
+ }
68
+
69
+ static grpc_rb_event* grpc_rb_event_queue_dequeue() {
70
+ grpc_rb_event* event;
71
+ if (event_queue.head == NULL) {
72
+ event = NULL;
73
+ } else {
74
+ event = event_queue.head;
75
+ if (event_queue.head->next == NULL) {
76
+ event_queue.head = event_queue.tail = NULL;
77
+ } else {
78
+ event_queue.head = event_queue.head->next;
79
+ }
80
+ }
81
+ return event;
82
+ }
83
+
84
+ static void grpc_rb_event_queue_destroy() {
85
+ gpr_mu_destroy(&event_queue.mu);
86
+ gpr_cv_destroy(&event_queue.cv);
87
+ }
88
+
89
+ static void* grpc_rb_wait_for_event_no_gil(void* param) {
90
+ grpc_rb_event* event = NULL;
91
+ (void)param;
92
+ gpr_mu_lock(&event_queue.mu);
93
+ while (!event_queue.abort) {
94
+ if ((event = grpc_rb_event_queue_dequeue()) != NULL) {
95
+ gpr_mu_unlock(&event_queue.mu);
96
+ return event;
97
+ }
98
+ gpr_cv_wait(&event_queue.cv, &event_queue.mu,
99
+ gpr_inf_future(GPR_CLOCK_REALTIME));
100
+ }
101
+ gpr_mu_unlock(&event_queue.mu);
102
+ return NULL;
103
+ }
104
+
105
+ static void grpc_rb_event_unblocking_func(void* arg) {
106
+ (void)arg;
107
+ gpr_mu_lock(&event_queue.mu);
108
+ event_queue.abort = true;
109
+ gpr_cv_signal(&event_queue.cv);
110
+ gpr_mu_unlock(&event_queue.mu);
111
+ }
112
+
113
+ /* This is the implementation of the thread that handles auth metadata plugin
114
+ * events */
115
+ static VALUE grpc_rb_event_thread(VALUE arg) {
116
+ grpc_rb_event* event;
117
+ (void)arg;
118
+ grpc_ruby_init();
119
+ while (true) {
120
+ event = (grpc_rb_event*)rb_thread_call_without_gvl(
121
+ grpc_rb_wait_for_event_no_gil, NULL, grpc_rb_event_unblocking_func,
122
+ NULL);
123
+ if (event == NULL) {
124
+ // Indicates that the thread needs to shut down
125
+ break;
126
+ } else {
127
+ event->callback(event->argument);
128
+ gpr_free(event);
129
+ }
130
+ }
131
+ grpc_rb_event_queue_destroy();
132
+ grpc_ruby_shutdown();
133
+ return Qnil;
134
+ }
135
+
136
+ void grpc_rb_event_queue_thread_start() {
137
+ event_queue.head = event_queue.tail = NULL;
138
+ event_queue.abort = false;
139
+ gpr_mu_init(&event_queue.mu);
140
+ gpr_cv_init(&event_queue.cv);
141
+
142
+ rb_thread_create(grpc_rb_event_thread, NULL);
143
+ }
@@ -0,0 +1,21 @@
1
+ /*
2
+ *
3
+ * Copyright 2016 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
+ void grpc_rb_event_queue_thread_start();
20
+
21
+ void grpc_rb_event_queue_enqueue(void (*callback)(void*), void* argument);
@@ -0,0 +1,328 @@
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_grpc.h"
22
+ #include "rb_grpc_imports.generated.h"
23
+
24
+ #include <math.h>
25
+ #include <ruby/vm.h>
26
+ #include <stdbool.h>
27
+ #include <sys/time.h>
28
+ #include <sys/types.h>
29
+ #include <unistd.h>
30
+
31
+ #include <grpc/grpc.h>
32
+ #include <grpc/support/log.h>
33
+ #include <grpc/support/time.h>
34
+ #include "rb_call.h"
35
+ #include "rb_call_credentials.h"
36
+ #include "rb_channel.h"
37
+ #include "rb_channel_credentials.h"
38
+ #include "rb_compression_options.h"
39
+ #include "rb_event_thread.h"
40
+ #include "rb_loader.h"
41
+ #include "rb_server.h"
42
+ #include "rb_server_credentials.h"
43
+
44
+ static VALUE grpc_rb_cTimeVal = Qnil;
45
+
46
+ static rb_data_type_t grpc_rb_timespec_data_type = {
47
+ "gpr_timespec",
48
+ {GRPC_RB_GC_NOT_MARKED,
49
+ GRPC_RB_GC_DONT_FREE,
50
+ GRPC_RB_MEMSIZE_UNAVAILABLE,
51
+ {NULL, NULL}},
52
+ NULL,
53
+ NULL,
54
+ #ifdef RUBY_TYPED_FREE_IMMEDIATELY
55
+ RUBY_TYPED_FREE_IMMEDIATELY
56
+ #endif
57
+ };
58
+
59
+ /* Alloc func that blocks allocation of a given object by raising an
60
+ * exception. */
61
+ VALUE grpc_rb_cannot_alloc(VALUE cls) {
62
+ rb_raise(rb_eTypeError,
63
+ "allocation of %s only allowed from the gRPC native layer",
64
+ rb_class2name(cls));
65
+ return Qnil;
66
+ }
67
+
68
+ /* Init func that fails by raising an exception. */
69
+ VALUE grpc_rb_cannot_init(VALUE self) {
70
+ rb_raise(rb_eTypeError,
71
+ "initialization of %s only allowed from the gRPC native layer",
72
+ rb_obj_classname(self));
73
+ return Qnil;
74
+ }
75
+
76
+ /* Init/Clone func that fails by raising an exception. */
77
+ VALUE grpc_rb_cannot_init_copy(VALUE copy, VALUE self) {
78
+ (void)self;
79
+ rb_raise(rb_eTypeError, "Copy initialization of %s is not supported",
80
+ rb_obj_classname(copy));
81
+ return Qnil;
82
+ }
83
+
84
+ /* id_tv_{,u}sec are accessor methods on Ruby Time instances. */
85
+ static ID id_tv_sec;
86
+ static ID id_tv_nsec;
87
+
88
+ /**
89
+ * grpc_rb_time_timeval creates a timeval from a ruby time object.
90
+ *
91
+ * This func is copied from ruby source, MRI/source/time.c, which is published
92
+ * under the same license as the ruby.h, on which the entire extensions is
93
+ * based.
94
+ */
95
+ gpr_timespec grpc_rb_time_timeval(VALUE time, int interval) {
96
+ gpr_timespec t;
97
+ gpr_timespec* time_const;
98
+ const char* tstr = interval ? "time interval" : "time";
99
+ const char* want = " want <secs from epoch>|<Time>|<GRPC::TimeConst.*>";
100
+
101
+ t.clock_type = GPR_CLOCK_REALTIME;
102
+ switch (TYPE(time)) {
103
+ case T_DATA:
104
+ if (CLASS_OF(time) == grpc_rb_cTimeVal) {
105
+ TypedData_Get_Struct(time, gpr_timespec, &grpc_rb_timespec_data_type,
106
+ time_const);
107
+ t = *time_const;
108
+ } else if (CLASS_OF(time) == rb_cTime) {
109
+ t.tv_sec = NUM2INT(rb_funcall(time, id_tv_sec, 0));
110
+ t.tv_nsec = NUM2INT(rb_funcall(time, id_tv_nsec, 0));
111
+ } else {
112
+ rb_raise(rb_eTypeError, "bad input: (%s)->c_timeval, got <%s>,%s", tstr,
113
+ rb_obj_classname(time), want);
114
+ }
115
+ break;
116
+
117
+ case T_FIXNUM:
118
+ t.tv_sec = FIX2LONG(time);
119
+ if (interval && t.tv_sec < 0)
120
+ rb_raise(rb_eArgError, "%s must be positive", tstr);
121
+ t.tv_nsec = 0;
122
+ break;
123
+
124
+ case T_FLOAT:
125
+ if (interval && RFLOAT_VALUE(time) < 0.0)
126
+ rb_raise(rb_eArgError, "%s must be positive", tstr);
127
+ else {
128
+ double f, d;
129
+
130
+ d = modf(RFLOAT_VALUE(time), &f);
131
+ if (d < 0) {
132
+ d += 1;
133
+ f -= 1;
134
+ }
135
+ t.tv_sec = (int64_t)f;
136
+ if (f != t.tv_sec) {
137
+ rb_raise(rb_eRangeError, "%f out of Time range", RFLOAT_VALUE(time));
138
+ }
139
+ t.tv_nsec = (int)(d * 1e9 + 0.5);
140
+ }
141
+ break;
142
+
143
+ case T_BIGNUM:
144
+ t.tv_sec = NUM2LONG(time);
145
+ if (interval && t.tv_sec < 0)
146
+ rb_raise(rb_eArgError, "%s must be positive", tstr);
147
+ t.tv_nsec = 0;
148
+ break;
149
+
150
+ default:
151
+ rb_raise(rb_eTypeError, "bad input: (%s)->c_timeval, got <%s>,%s", tstr,
152
+ rb_obj_classname(time), want);
153
+ break;
154
+ }
155
+ return t;
156
+ }
157
+
158
+ /* id_at is the constructor method of the ruby standard Time class. */
159
+ static ID id_at;
160
+
161
+ /* id_inspect is the inspect method found on various ruby objects. */
162
+ static ID id_inspect;
163
+
164
+ /* id_to_s is the to_s method found on various ruby objects. */
165
+ static ID id_to_s;
166
+
167
+ /* Converts a wrapped time constant to a standard time. */
168
+ static VALUE grpc_rb_time_val_to_time(VALUE self) {
169
+ gpr_timespec* time_const = NULL;
170
+ gpr_timespec real_time;
171
+ TypedData_Get_Struct(self, gpr_timespec, &grpc_rb_timespec_data_type,
172
+ time_const);
173
+ real_time = gpr_convert_clock_type(*time_const, GPR_CLOCK_REALTIME);
174
+ return rb_funcall(rb_cTime, id_at, 2, INT2NUM(real_time.tv_sec),
175
+ INT2NUM(real_time.tv_nsec / 1000));
176
+ }
177
+
178
+ /* Invokes inspect on the ctime version of the time val. */
179
+ static VALUE grpc_rb_time_val_inspect(VALUE self) {
180
+ return rb_funcall(grpc_rb_time_val_to_time(self), id_inspect, 0);
181
+ }
182
+
183
+ /* Invokes to_s on the ctime version of the time val. */
184
+ static VALUE grpc_rb_time_val_to_s(VALUE self) {
185
+ return rb_funcall(grpc_rb_time_val_to_time(self), id_to_s, 0);
186
+ }
187
+
188
+ static gpr_timespec zero_realtime;
189
+ static gpr_timespec inf_future_realtime;
190
+ static gpr_timespec inf_past_realtime;
191
+
192
+ /* Adds a module with constants that map to gpr's static timeval structs. */
193
+ static void Init_grpc_time_consts() {
194
+ VALUE grpc_rb_mTimeConsts =
195
+ rb_define_module_under(grpc_rb_mGrpcCore, "TimeConsts");
196
+ grpc_rb_cTimeVal =
197
+ rb_define_class_under(grpc_rb_mGrpcCore, "TimeSpec", rb_cObject);
198
+ zero_realtime = gpr_time_0(GPR_CLOCK_REALTIME);
199
+ inf_future_realtime = gpr_inf_future(GPR_CLOCK_REALTIME);
200
+ inf_past_realtime = gpr_inf_past(GPR_CLOCK_REALTIME);
201
+ rb_define_const(
202
+ grpc_rb_mTimeConsts, "ZERO",
203
+ TypedData_Wrap_Struct(grpc_rb_cTimeVal, &grpc_rb_timespec_data_type,
204
+ (void*)&zero_realtime));
205
+ rb_define_const(
206
+ grpc_rb_mTimeConsts, "INFINITE_FUTURE",
207
+ TypedData_Wrap_Struct(grpc_rb_cTimeVal, &grpc_rb_timespec_data_type,
208
+ (void*)&inf_future_realtime));
209
+ rb_define_const(
210
+ grpc_rb_mTimeConsts, "INFINITE_PAST",
211
+ TypedData_Wrap_Struct(grpc_rb_cTimeVal, &grpc_rb_timespec_data_type,
212
+ (void*)&inf_past_realtime));
213
+ rb_define_method(grpc_rb_cTimeVal, "to_time", grpc_rb_time_val_to_time, 0);
214
+ rb_define_method(grpc_rb_cTimeVal, "inspect", grpc_rb_time_val_inspect, 0);
215
+ rb_define_method(grpc_rb_cTimeVal, "to_s", grpc_rb_time_val_to_s, 0);
216
+ id_at = rb_intern("at");
217
+ id_inspect = rb_intern("inspect");
218
+ id_to_s = rb_intern("to_s");
219
+ id_tv_sec = rb_intern("tv_sec");
220
+ id_tv_nsec = rb_intern("tv_nsec");
221
+ }
222
+
223
+ #if GPR_WINDOWS
224
+ static void grpc_ruby_set_init_pid(void) {}
225
+ static bool grpc_ruby_forked_after_init(void) { return false; }
226
+ #else
227
+ static pid_t grpc_init_pid;
228
+
229
+ static void grpc_ruby_set_init_pid(void) {
230
+ GPR_ASSERT(grpc_init_pid == 0);
231
+ grpc_init_pid = getpid();
232
+ }
233
+
234
+ static bool grpc_ruby_forked_after_init(void) {
235
+ GPR_ASSERT(grpc_init_pid != 0);
236
+ return grpc_init_pid != getpid();
237
+ }
238
+ #endif
239
+
240
+ /* Initialize the GRPC module structs */
241
+
242
+ /* grpc_rb_sNewServerRpc is the struct that holds new server rpc details. */
243
+ VALUE grpc_rb_sNewServerRpc = Qnil;
244
+ /* grpc_rb_sStatus is the struct that holds status details. */
245
+ VALUE grpc_rb_sStatus = Qnil;
246
+
247
+ /* Initialize the GRPC module. */
248
+ VALUE grpc_rb_mGRPC = Qnil;
249
+ VALUE grpc_rb_mGrpcCore = Qnil;
250
+
251
+ /* cached Symbols for members in Status struct */
252
+ VALUE sym_code = Qundef;
253
+ VALUE sym_details = Qundef;
254
+ VALUE sym_metadata = Qundef;
255
+
256
+ static gpr_once g_once_init = GPR_ONCE_INIT;
257
+
258
+ void grpc_ruby_fork_guard() {
259
+ if (grpc_ruby_forked_after_init()) {
260
+ rb_raise(rb_eRuntimeError, "grpc cannot be used before and after forking");
261
+ }
262
+ }
263
+
264
+ static VALUE bg_thread_init_rb_mu = Qundef;
265
+ static int bg_thread_init_done = 0;
266
+
267
+ static void grpc_ruby_init_threads() {
268
+ // Avoid calling into ruby library (when creating threads here)
269
+ // in gpr_once_init. In general, it appears to be unsafe to call
270
+ // into the ruby library while holding a non-ruby mutex, because a gil yield
271
+ // could end up trying to lock onto that same mutex and deadlocking.
272
+ rb_mutex_lock(bg_thread_init_rb_mu);
273
+ if (!bg_thread_init_done) {
274
+ grpc_rb_event_queue_thread_start();
275
+ grpc_rb_channel_polling_thread_start();
276
+ bg_thread_init_done = 1;
277
+ }
278
+ rb_mutex_unlock(bg_thread_init_rb_mu);
279
+ }
280
+
281
+ static int64_t g_grpc_ruby_init_count;
282
+
283
+ void grpc_ruby_init() {
284
+ gpr_once_init(&g_once_init, grpc_ruby_set_init_pid);
285
+ grpc_init();
286
+ grpc_ruby_init_threads();
287
+ // (only gpr_log after logging has been initialized)
288
+ gpr_log(GPR_DEBUG,
289
+ "GRPC_RUBY: grpc_ruby_init - prev g_grpc_ruby_init_count:%" PRId64,
290
+ g_grpc_ruby_init_count++);
291
+ }
292
+
293
+ void grpc_ruby_shutdown() {
294
+ GPR_ASSERT(g_grpc_ruby_init_count > 0);
295
+ if (!grpc_ruby_forked_after_init()) grpc_shutdown();
296
+ gpr_log(
297
+ GPR_DEBUG,
298
+ "GRPC_RUBY: grpc_ruby_shutdown - prev g_grpc_ruby_init_count:%" PRId64,
299
+ g_grpc_ruby_init_count--);
300
+ }
301
+
302
+ void Init_grpc_c() {
303
+ if (!grpc_rb_load_core()) {
304
+ rb_raise(rb_eLoadError, "Couldn't find or load gRPC's dynamic C core");
305
+ return;
306
+ }
307
+
308
+ rb_global_variable(&bg_thread_init_rb_mu);
309
+ bg_thread_init_rb_mu = rb_mutex_new();
310
+
311
+ grpc_rb_mGRPC = rb_define_module("GRPC");
312
+ grpc_rb_mGrpcCore = rb_define_module_under(grpc_rb_mGRPC, "Core");
313
+ grpc_rb_sNewServerRpc = rb_struct_define(
314
+ "NewServerRpc", "method", "host", "deadline", "metadata", "call", NULL);
315
+ grpc_rb_sStatus = rb_const_get(rb_cStruct, rb_intern("Status"));
316
+ sym_code = ID2SYM(rb_intern("code"));
317
+ sym_details = ID2SYM(rb_intern("details"));
318
+ sym_metadata = ID2SYM(rb_intern("metadata"));
319
+
320
+ Init_grpc_channel();
321
+ Init_grpc_call();
322
+ Init_grpc_call_credentials();
323
+ Init_grpc_channel_credentials();
324
+ Init_grpc_server();
325
+ Init_grpc_server_credentials();
326
+ Init_grpc_time_consts();
327
+ Init_grpc_compression_options();
328
+ }