grpc 1.42.0.pre1-arm64-darwin → 1.58.3-arm64-darwin

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/grpc_c.64-ucrt.ruby +0 -0
  3. data/src/ruby/bin/math_pb.rb +24 -18
  4. data/src/ruby/ext/grpc/ext-export-truffleruby-with-ruby-abi-version.clang +2 -0
  5. data/src/ruby/ext/grpc/ext-export-truffleruby-with-ruby-abi-version.gcc +7 -0
  6. data/src/ruby/ext/grpc/ext-export-with-ruby-abi-version.clang +2 -0
  7. data/src/ruby/ext/grpc/ext-export-with-ruby-abi-version.gcc +7 -0
  8. data/src/ruby/ext/grpc/ext-export.gcc +1 -1
  9. data/src/ruby/ext/grpc/extconf.rb +117 -32
  10. data/src/ruby/ext/grpc/rb_call.c +63 -39
  11. data/src/ruby/ext/grpc/rb_call_credentials.c +0 -1
  12. data/src/ruby/ext/grpc/rb_channel.c +113 -84
  13. data/src/ruby/ext/grpc/rb_channel.h +1 -0
  14. data/src/ruby/ext/grpc/rb_channel_args.c +17 -2
  15. data/src/ruby/ext/grpc/rb_channel_args.h +4 -0
  16. data/src/ruby/ext/grpc/rb_channel_credentials.c +0 -1
  17. data/src/ruby/ext/grpc/rb_compression_options.c +1 -2
  18. data/src/ruby/ext/grpc/rb_event_thread.c +22 -6
  19. data/src/ruby/ext/grpc/rb_event_thread.h +1 -0
  20. data/src/ruby/ext/grpc/rb_grpc.c +193 -30
  21. data/src/ruby/ext/grpc/rb_grpc.h +8 -2
  22. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +66 -72
  23. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +102 -111
  24. data/src/ruby/ext/grpc/rb_loader.c +6 -2
  25. data/src/ruby/ext/grpc/rb_server.c +69 -49
  26. data/src/ruby/ext/grpc/rb_server_credentials.c +0 -1
  27. data/src/ruby/ext/grpc/rb_xds_channel_credentials.c +0 -1
  28. data/src/ruby/ext/grpc/rb_xds_server_credentials.c +0 -1
  29. data/src/ruby/lib/grpc/2.6/grpc_c.bundle +0 -0
  30. data/src/ruby/lib/grpc/2.7/grpc_c.bundle +0 -0
  31. data/src/ruby/lib/grpc/3.0/grpc_c.bundle +0 -0
  32. data/src/ruby/lib/grpc/3.1/grpc_c.bundle +0 -0
  33. data/src/ruby/lib/grpc/3.2/grpc_c.bundle +0 -0
  34. data/src/ruby/lib/grpc/errors.rb +1 -1
  35. data/src/ruby/lib/grpc/generic/active_call.rb +16 -15
  36. data/src/ruby/lib/grpc/generic/bidi_call.rb +4 -0
  37. data/src/ruby/lib/grpc/grpc.rb +1 -1
  38. data/src/ruby/lib/grpc/version.rb +1 -1
  39. data/src/ruby/pb/generate_proto_ruby.sh +1 -6
  40. data/src/ruby/pb/grpc/health/v1/health_pb.rb +24 -13
  41. data/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb +24 -3
  42. data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +26 -108
  43. data/src/ruby/pb/src/proto/grpc/testing/test_pb.rb +27 -3
  44. data/src/ruby/pb/test/client.rb +16 -0
  45. data/src/ruby/spec/channel_spec.rb +5 -43
  46. data/src/ruby/spec/client_server_spec.rb +20 -8
  47. data/src/ruby/spec/generic/active_call_spec.rb +12 -3
  48. data/src/ruby/spec/generic/client_stub_spec.rb +23 -23
  49. data/src/ruby/spec/generic/rpc_server_spec.rb +3 -3
  50. data/src/ruby/spec/generic/server_interceptors_spec.rb +1 -1
  51. data/src/ruby/spec/user_agent_spec.rb +1 -1
  52. metadata +61 -59
  53. data/src/ruby/lib/grpc/2.4/grpc_c.bundle +0 -0
  54. data/src/ruby/lib/grpc/2.5/grpc_c.bundle +0 -0
  55. /data/{grpc_c.32.ruby → grpc_c.32-msvcrt.ruby} +0 -0
  56. /data/{grpc_c.64.ruby → grpc_c.64-msvcrt.ruby} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3a3f43b745189a7f5fc2d1ed80975fba571dd148d9d0dc052edf3f9c7e121474
4
- data.tar.gz: 36a667c816e614f0c8512f16d338d0c5773c2f7cd2ebbf995e3dd00df2ea03ac
3
+ metadata.gz: 89f0950b56c8f20a1ea4361ea0db9bf2de57a3c2d9c7afc9f1dbba9422b8db7c
4
+ data.tar.gz: a530e2a1013cd102e62d7209c8629e85296c924df08e285135ee7b014fd347b4
5
5
  SHA512:
6
- metadata.gz: 80c10cc51235057a3667d596e6e608923ef9e35ae1d573d2bd147877c92eb75e8189958cfc1bcd55e300bfc961c58bd2e8932f1775b29aa7a0a580feaeac1fda
7
- data.tar.gz: c3f9468165a426417883075811d1fe70dc621b92ac7ddb656db8313fb2a4917d385dcff6373d2e60e85397c50e751550a78dc26535ccac9fc697ba04da354ea0
6
+ metadata.gz: 889ac492ac615b39bcd1249f07cef075abafebfd640b6089bd4e11674dea9c2397ec0bd7d62d8a9f40eccf93153d24e2c0f1f3305cf67ca8e5cebaa8a8b52996
7
+ data.tar.gz: de2e9287fe616ded55a5de2dfb66035ad152278c1e7cdb8b6eba257f2d6fca4ff2158e7938c30faba486512f0a31c8aa6da7609401ca1732518368a08ebf07df
File without changes
@@ -1,28 +1,34 @@
1
+ # frozen_string_literal: true
1
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
2
3
  # source: math.proto
3
4
 
4
5
  require 'google/protobuf'
5
6
 
6
- Google::Protobuf::DescriptorPool.generated_pool.build do
7
- add_file("math.proto", :syntax => :proto3) do
8
- add_message "math.DivArgs" do
9
- optional :dividend, :int64, 1
10
- optional :divisor, :int64, 2
11
- end
12
- add_message "math.DivReply" do
13
- optional :quotient, :int64, 1
14
- optional :remainder, :int64, 2
15
- end
16
- add_message "math.FibArgs" do
17
- optional :limit, :int64, 1
18
- end
19
- add_message "math.Num" do
20
- optional :num, :int64, 1
21
- end
22
- add_message "math.FibReply" do
23
- optional :count, :int64, 1
7
+
8
+ descriptor_data = "\n\nmath.proto\x12\x04math\",\n\x07\x44ivArgs\x12\x10\n\x08\x64ividend\x18\x01 \x01(\x03\x12\x0f\n\x07\x64ivisor\x18\x02 \x01(\x03\"/\n\x08\x44ivReply\x12\x10\n\x08quotient\x18\x01 \x01(\x03\x12\x11\n\tremainder\x18\x02 \x01(\x03\"\x18\n\x07\x46ibArgs\x12\r\n\x05limit\x18\x01 \x01(\x03\"\x12\n\x03Num\x12\x0b\n\x03num\x18\x01 \x01(\x03\"\x19\n\x08\x46ibReply\x12\r\n\x05\x63ount\x18\x01 \x01(\x03\x32\xa4\x01\n\x04Math\x12&\n\x03\x44iv\x12\r.math.DivArgs\x1a\x0e.math.DivReply\"\x00\x12.\n\x07\x44ivMany\x12\r.math.DivArgs\x1a\x0e.math.DivReply\"\x00(\x01\x30\x01\x12#\n\x03\x46ib\x12\r.math.FibArgs\x1a\t.math.Num\"\x00\x30\x01\x12\x1f\n\x03Sum\x12\t.math.Num\x1a\t.math.Num\"\x00(\x01\x62\x06proto3"
9
+
10
+ pool = Google::Protobuf::DescriptorPool.generated_pool
11
+
12
+ begin
13
+ pool.add_serialized_file(descriptor_data)
14
+ rescue TypeError => e
15
+ # Compatibility code: will be removed in the next major version.
16
+ require 'google/protobuf/descriptor_pb'
17
+ parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data)
18
+ parsed.clear_dependency
19
+ serialized = parsed.class.encode(parsed)
20
+ file = pool.add_serialized_file(serialized)
21
+ warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}"
22
+ imports = [
23
+ ]
24
+ imports.each do |type_name, expected_filename|
25
+ import_file = pool.lookup(type_name).file_descriptor
26
+ if import_file.name != expected_filename
27
+ warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}"
24
28
  end
25
29
  end
30
+ warn "Each proto file must use a consistent fully-qualified name."
31
+ warn "This will become an error in the next major version."
26
32
  end
27
33
 
28
34
  module Math
@@ -0,0 +1,2 @@
1
+ _Init_grpc_c
2
+ _rb_tr_abi_version
@@ -0,0 +1,7 @@
1
+ grpc_1.0 {
2
+ global:
3
+ Init_grpc_c;
4
+ rb_tr_abi_version;
5
+ local:
6
+ *;
7
+ };
@@ -0,0 +1,2 @@
1
+ _Init_grpc_c
2
+ _ruby_abi_version
@@ -0,0 +1,7 @@
1
+ grpc_1.0 {
2
+ global:
3
+ Init_grpc_c;
4
+ ruby_abi_version;
5
+ local:
6
+ *;
7
+ };
@@ -3,4 +3,4 @@ grpc_1.0 {
3
3
  Init_grpc_c;
4
4
  local:
5
5
  *;
6
- };
6
+ };
@@ -16,10 +16,13 @@ require 'etc'
16
16
  require 'mkmf'
17
17
 
18
18
  windows = RUBY_PLATFORM =~ /mingw|mswin/
19
+ windows_ucrt = RUBY_PLATFORM =~ /(mingw|mswin).*ucrt/
19
20
  bsd = RUBY_PLATFORM =~ /bsd/
20
21
  darwin = RUBY_PLATFORM =~ /darwin/
21
22
  linux = RUBY_PLATFORM =~ /linux/
22
23
  cross_compiling = ENV['RCD_HOST_RUBY_VERSION'] # set by rake-compiler-dock in build containers
24
+ # TruffleRuby uses the Sulong LLVM runtime, which is different from Apple's.
25
+ apple_toolchain = darwin && RUBY_ENGINE != 'truffleruby'
23
26
 
24
27
  grpc_root = File.expand_path(File.join(File.dirname(__FILE__), '../../../..'))
25
28
 
@@ -27,30 +30,52 @@ grpc_config = ENV['GRPC_CONFIG'] || 'opt'
27
30
 
28
31
  ENV['MACOSX_DEPLOYMENT_TARGET'] = '10.10'
29
32
 
30
- if ENV['AR'].nil? || ENV['AR'].size == 0
31
- ENV['AR'] = RbConfig::CONFIG['AR']
33
+ def env_unset?(name)
34
+ ENV[name].nil? || ENV[name].size == 0
32
35
  end
33
- if ENV['CC'].nil? || ENV['CC'].size == 0
34
- ENV['CC'] = RbConfig::CONFIG['CC']
36
+
37
+ def inherit_env_or_rbconfig(name)
38
+ ENV[name] = inherit_rbconfig(name) if env_unset?(name)
39
+ end
40
+
41
+ def inherit_rbconfig(name)
42
+ ENV[name] = RbConfig::CONFIG[name] || ''
35
43
  end
36
- if ENV['CXX'].nil? || ENV['CXX'].size == 0
37
- ENV['CXX'] = RbConfig::CONFIG['CXX']
44
+
45
+ def env_append(name, string)
46
+ ENV[name] += ' ' + string
38
47
  end
39
- if ENV['LD'].nil? || ENV['LD'].size == 0
40
- ENV['LD'] = ENV['CC']
48
+
49
+ inherit_env_or_rbconfig 'AR'
50
+ inherit_env_or_rbconfig 'CC'
51
+ inherit_env_or_rbconfig 'CXX'
52
+ inherit_env_or_rbconfig 'RANLIB'
53
+ inherit_env_or_rbconfig 'STRIP'
54
+ inherit_rbconfig 'CPPFLAGS'
55
+ inherit_rbconfig 'LDFLAGS'
56
+
57
+ ENV['LD'] = ENV['CC'] if env_unset?('LD')
58
+ ENV['LDXX'] = ENV['CXX'] if env_unset?('LDXX')
59
+
60
+ if RUBY_ENGINE == 'truffleruby'
61
+ # ensure we can find the system's OpenSSL
62
+ env_append 'CPPFLAGS', RbConfig::CONFIG['cppflags']
41
63
  end
42
64
 
43
- if darwin && !cross_compiling
65
+ if apple_toolchain && !cross_compiling
44
66
  ENV['AR'] = 'libtool'
45
67
  ENV['ARFLAGS'] = '-o'
46
68
  end
47
69
 
48
- ENV['EMBED_OPENSSL'] = 'true'
49
- ENV['EMBED_ZLIB'] = 'true'
70
+ # Don't embed on TruffleRuby (constant-time crypto is unsafe with Sulong, slow build times)
71
+ ENV['EMBED_OPENSSL'] = (RUBY_ENGINE != 'truffleruby').to_s
72
+ # Don't embed on TruffleRuby (the system zlib is already linked for the zlib C extension, slow build times)
73
+ ENV['EMBED_ZLIB'] = (RUBY_ENGINE != 'truffleruby').to_s
74
+
50
75
  ENV['EMBED_CARES'] = 'true'
51
76
 
52
77
  ENV['ARCH_FLAGS'] = RbConfig::CONFIG['ARCH_FLAG']
53
- if darwin && !cross_compiling
78
+ if apple_toolchain && !cross_compiling
54
79
  if RUBY_PLATFORM =~ /arm64/
55
80
  ENV['ARCH_FLAGS'] = '-arch arm64'
56
81
  else
@@ -58,28 +83,83 @@ if darwin && !cross_compiling
58
83
  end
59
84
  end
60
85
 
61
- ENV['CPPFLAGS'] = '-DGPR_BACKWARDS_COMPATIBILITY_MODE'
62
- ENV['CPPFLAGS'] += ' -DGRPC_XDS_USER_AGENT_NAME_SUFFIX="\"RUBY\"" '
63
- ENV['CPPFLAGS'] += ' -DGRPC_XDS_USER_AGENT_VERSION_SUFFIX="\"1.42.0.pre1\"" '
86
+ env_append 'CPPFLAGS', '-DGPR_BACKWARDS_COMPATIBILITY_MODE'
87
+ env_append 'CPPFLAGS', '-DGRPC_XDS_USER_AGENT_NAME_SUFFIX="\"RUBY\""'
88
+
89
+ require_relative '../../lib/grpc/version'
90
+ env_append 'CPPFLAGS', '-DGRPC_XDS_USER_AGENT_VERSION_SUFFIX="\"' + GRPC::VERSION + '\""'
91
+ env_append 'CPPFLAGS', '-DGRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK=1'
64
92
 
65
93
  output_dir = File.expand_path(RbConfig::CONFIG['topdir'])
66
94
  grpc_lib_dir = File.join(output_dir, 'libs', grpc_config)
67
95
  ENV['BUILDDIR'] = output_dir
68
96
 
97
+ strip_tool = RbConfig::CONFIG['STRIP']
98
+ strip_tool += ' -x' if apple_toolchain
99
+
69
100
  unless windows
70
101
  puts 'Building internal gRPC into ' + grpc_lib_dir
71
102
  nproc = 4
72
- nproc = Etc.nprocessors * 2 if Etc.respond_to? :nprocessors
103
+ nproc = Etc.nprocessors if Etc.respond_to? :nprocessors
104
+ nproc_override = ENV['GRPC_RUBY_BUILD_PROCS']
105
+ unless nproc_override.nil? or nproc_override.size == 0
106
+ nproc = nproc_override
107
+ puts "Overriding make parallelism to #{nproc}"
108
+ end
73
109
  make = bsd ? 'gmake' : 'make'
74
- system("#{make} -j#{nproc} -C #{grpc_root} #{grpc_lib_dir}/libgrpc.a CONFIG=#{grpc_config} Q=")
110
+ cmd = "#{make} -j#{nproc} -C #{grpc_root} #{grpc_lib_dir}/libgrpc.a CONFIG=#{grpc_config} Q="
111
+ puts "Building grpc native library: #{cmd}"
112
+ system(cmd)
75
113
  exit 1 unless $? == 0
114
+
115
+ if grpc_config == 'opt'
116
+ rm_obj_cmd = "rm -rf #{File.join(output_dir, 'objs')}"
117
+ puts "Removing grpc object files: #{rm_obj_cmd}"
118
+ system(rm_obj_cmd)
119
+ exit 1 unless $? == 0
120
+ strip_cmd = "#{strip_tool} #{grpc_lib_dir}/*.a"
121
+ puts "Stripping grpc native library: #{strip_cmd}"
122
+ system(strip_cmd)
123
+ exit 1 unless $? == 0
124
+ end
76
125
  end
77
126
 
127
+ $CFLAGS << ' -DGRPC_RUBY_WINDOWS_UCRT' if windows_ucrt
78
128
  $CFLAGS << ' -I' + File.join(grpc_root, 'include')
79
129
 
80
- ext_export_file = File.join(grpc_root, 'src', 'ruby', 'ext', 'grpc', 'ext-export')
130
+ def have_ruby_abi_version()
131
+ return true if RUBY_ENGINE == 'truffleruby'
132
+ # ruby_abi_version is only available in development versions: https://github.com/ruby/ruby/pull/6231
133
+ return false if RUBY_PATCHLEVEL >= 0
134
+
135
+ m = /(\d+)\.(\d+)/.match(RUBY_VERSION)
136
+ if m.nil?
137
+ puts "Failed to parse ruby version: #{RUBY_VERSION}. Assuming ruby_abi_version symbol is NOT present."
138
+ return false
139
+ end
140
+ major = m[1].to_i
141
+ minor = m[2].to_i
142
+ if major >= 3 and minor >= 2
143
+ puts "Ruby version #{RUBY_VERSION} >= 3.2. Assuming ruby_abi_version symbol is present."
144
+ return true
145
+ end
146
+ puts "Ruby version #{RUBY_VERSION} < 3.2. Assuming ruby_abi_version symbol is NOT present."
147
+ false
148
+ end
149
+
150
+ def ext_export_filename()
151
+ name = 'ext-export'
152
+ name += '-truffleruby' if RUBY_ENGINE == 'truffleruby'
153
+ name += '-with-ruby-abi-version' if have_ruby_abi_version()
154
+ name
155
+ end
156
+
157
+ ext_export_file = File.join(grpc_root, 'src', 'ruby', 'ext', 'grpc', ext_export_filename())
81
158
  $LDFLAGS << ' -Wl,--version-script="' + ext_export_file + '.gcc"' if linux
82
- $LDFLAGS << ' -Wl,-exported_symbols_list,"' + ext_export_file + '.clang"' if darwin
159
+ if apple_toolchain
160
+ $LDFLAGS << ' -weak_framework CoreFoundation' if RUBY_PLATFORM =~ /arm64/
161
+ $LDFLAGS << ' -Wl,-exported_symbols_list,"' + ext_export_file + '.clang"'
162
+ end
83
163
 
84
164
  $LDFLAGS << ' ' + File.join(grpc_lib_dir, 'libgrpc.a') unless windows
85
165
  if grpc_config == 'gcov'
@@ -92,10 +172,13 @@ if grpc_config == 'dbg'
92
172
  end
93
173
 
94
174
  $LDFLAGS << ' -Wl,-wrap,memcpy' if linux
95
- $LDFLAGS << ' -static-libgcc -static-libstdc++' if linux
175
+ # Do not statically link standard libraries on TruffleRuby as this does not work when compiling to bitcode
176
+ if linux && RUBY_ENGINE != 'truffleruby'
177
+ $LDFLAGS << ' -static-libgcc -static-libstdc++'
178
+ end
96
179
  $LDFLAGS << ' -static' if windows
97
180
 
98
- $CFLAGS << ' -std=c99 '
181
+ $CFLAGS << ' -std=c11 '
99
182
  $CFLAGS << ' -Wall '
100
183
  $CFLAGS << ' -Wextra '
101
184
  $CFLAGS << ' -pedantic '
@@ -104,20 +187,22 @@ output = File.join('grpc', 'grpc_c')
104
187
  puts 'Generating Makefile for ' + output
105
188
  create_makefile(output)
106
189
 
107
- strip_tool = RbConfig::CONFIG['STRIP']
108
- strip_tool += ' -x' if darwin
109
-
110
- if grpc_config == 'opt'
190
+ if ENV['GRPC_RUBY_TEST_ONLY_WORKAROUND_MAKE_INSTALL_BUG']
191
+ # Note: this env var setting is intended to work around a problem observed
192
+ # with the ginstall command on grpc's macos automated test infrastructure,
193
+ # and is not guaranteed to work in the wild.
194
+ # Also see https://github.com/rake-compiler/rake-compiler/issues/210.
195
+ puts 'Overriding the generated Makefile install target to use cp'
111
196
  File.open('Makefile.new', 'w') do |o|
112
- o.puts 'hijack: all strip'
113
- o.puts
114
197
  File.foreach('Makefile') do |i|
115
- o.puts i
198
+ if i.start_with?('INSTALL_PROG = ')
199
+ override = 'INSTALL_PROG = cp'
200
+ puts "Replacing generated Makefile line: |#{i}|, with: |#{override}|"
201
+ o.puts override
202
+ else
203
+ o.puts i
204
+ end
116
205
  end
117
- o.puts
118
- o.puts 'strip: $(DLLIB)'
119
- o.puts "\t$(ECHO) Stripping $(DLLIB)"
120
- o.puts "\t$(Q) #{strip_tool} $(DLLIB)"
121
206
  end
122
207
  File.rename('Makefile.new', 'Makefile')
123
208
  end
@@ -801,6 +801,56 @@ static VALUE grpc_run_batch_stack_build_result(run_batch_stack* st) {
801
801
  return result;
802
802
  }
803
803
 
804
+ struct call_run_batch_args {
805
+ grpc_rb_call* call;
806
+ unsigned write_flag;
807
+ VALUE ops_hash;
808
+ run_batch_stack* st;
809
+ };
810
+
811
+ static VALUE grpc_rb_call_run_batch_try(VALUE value_args) {
812
+ grpc_rb_fork_unsafe_begin();
813
+ struct call_run_batch_args* args = (struct call_run_batch_args*)value_args;
814
+ void* tag = (void*)&args->st;
815
+
816
+ grpc_event ev;
817
+ grpc_call_error err;
818
+
819
+ args->st = gpr_malloc(sizeof(run_batch_stack));
820
+ grpc_run_batch_stack_init(args->st, args->write_flag);
821
+ grpc_run_batch_stack_fill_ops(args->st, args->ops_hash);
822
+
823
+ /* call grpc_call_start_batch, then wait for it to complete using
824
+ * pluck_event */
825
+ err = grpc_call_start_batch(args->call->wrapped, args->st->ops,
826
+ args->st->op_num, tag, NULL);
827
+ if (err != GRPC_CALL_OK) {
828
+ rb_raise(grpc_rb_eCallError,
829
+ "grpc_call_start_batch failed with %s (code=%d)",
830
+ grpc_call_error_detail_of(err), err);
831
+ }
832
+ ev = rb_completion_queue_pluck(args->call->queue, tag,
833
+ gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
834
+ if (!ev.success) {
835
+ rb_raise(grpc_rb_eCallError, "call#run_batch failed somehow");
836
+ }
837
+ /* Build and return the BatchResult struct result,
838
+ if there is an error, it's reflected in the status */
839
+ return grpc_run_batch_stack_build_result(args->st);
840
+ }
841
+
842
+ static VALUE grpc_rb_call_run_batch_ensure(VALUE value_args) {
843
+ grpc_rb_fork_unsafe_end();
844
+ struct call_run_batch_args* args = (struct call_run_batch_args*)value_args;
845
+
846
+ if (args->st) {
847
+ grpc_run_batch_stack_cleanup(args->st);
848
+ gpr_free(args->st);
849
+ }
850
+
851
+ return Qnil;
852
+ }
853
+
804
854
  /* call-seq:
805
855
  ops = {
806
856
  GRPC::Core::CallOps::SEND_INITIAL_METADATA => <op_value>,
@@ -819,56 +869,29 @@ static VALUE grpc_run_batch_stack_build_result(run_batch_stack* st) {
819
869
  Only one operation of each type can be active at once in any given
820
870
  batch */
821
871
  static VALUE grpc_rb_call_run_batch(VALUE self, VALUE ops_hash) {
822
- run_batch_stack* st = NULL;
823
- grpc_rb_call* call = NULL;
824
- grpc_event ev;
825
- grpc_call_error err;
826
- VALUE result = Qnil;
827
- VALUE rb_write_flag = rb_ivar_get(self, id_write_flag);
828
- unsigned write_flag = 0;
829
- void* tag = (void*)&st;
830
-
831
872
  grpc_ruby_fork_guard();
832
873
  if (RTYPEDDATA_DATA(self) == NULL) {
833
874
  rb_raise(grpc_rb_eCallError, "Cannot run batch on closed call");
834
- return Qnil;
835
875
  }
876
+
877
+ grpc_rb_call* call = NULL;
836
878
  TypedData_Get_Struct(self, grpc_rb_call, &grpc_call_data_type, call);
837
879
 
838
880
  /* Validate the ops args, adding them to a ruby array */
839
881
  if (TYPE(ops_hash) != T_HASH) {
840
882
  rb_raise(rb_eTypeError, "call#run_batch: ops hash should be a hash");
841
- return Qnil;
842
883
  }
843
- if (rb_write_flag != Qnil) {
844
- write_flag = NUM2UINT(rb_write_flag);
845
- }
846
- st = gpr_malloc(sizeof(run_batch_stack));
847
- grpc_run_batch_stack_init(st, write_flag);
848
- grpc_run_batch_stack_fill_ops(st, ops_hash);
849
884
 
850
- /* call grpc_call_start_batch, then wait for it to complete using
851
- * pluck_event */
852
- err = grpc_call_start_batch(call->wrapped, st->ops, st->op_num, tag, NULL);
853
- if (err != GRPC_CALL_OK) {
854
- grpc_run_batch_stack_cleanup(st);
855
- gpr_free(st);
856
- rb_raise(grpc_rb_eCallError,
857
- "grpc_call_start_batch failed with %s (code=%d)",
858
- grpc_call_error_detail_of(err), err);
859
- return Qnil;
860
- }
861
- ev = rb_completion_queue_pluck(call->queue, tag,
862
- gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
863
- if (!ev.success) {
864
- rb_raise(grpc_rb_eCallError, "call#run_batch failed somehow");
865
- }
866
- /* Build and return the BatchResult struct result,
867
- if there is an error, it's reflected in the status */
868
- result = grpc_run_batch_stack_build_result(st);
869
- grpc_run_batch_stack_cleanup(st);
870
- gpr_free(st);
871
- return result;
885
+ VALUE rb_write_flag = rb_ivar_get(self, id_write_flag);
886
+
887
+ struct call_run_batch_args args = {
888
+ .call = call,
889
+ .write_flag = rb_write_flag == Qnil ? 0 : NUM2UINT(rb_write_flag),
890
+ .ops_hash = ops_hash,
891
+ .st = NULL};
892
+
893
+ return rb_ensure(grpc_rb_call_run_batch_try, (VALUE)&args,
894
+ grpc_rb_call_run_batch_ensure, (VALUE)&args);
872
895
  }
873
896
 
874
897
  static void Init_grpc_write_flags() {
@@ -973,6 +996,7 @@ void Init_grpc_call() {
973
996
  grpc_rb_cCall = rb_define_class_under(grpc_rb_mGrpcCore, "Call", rb_cObject);
974
997
  grpc_rb_cMdAry =
975
998
  rb_define_class_under(grpc_rb_mGrpcCore, "MetadataArray", rb_cObject);
999
+ rb_undef_alloc_func(grpc_rb_cMdAry);
976
1000
 
977
1001
  /* Prevent allocation or inialization of the Call class */
978
1002
  rb_define_alloc_func(grpc_rb_cCall, grpc_rb_cannot_alloc);
@@ -193,7 +193,6 @@ static void grpc_rb_call_credentials_free_internal(void* p) {
193
193
  /* Destroys the credentials instances. */
194
194
  static void grpc_rb_call_credentials_free(void* p) {
195
195
  grpc_rb_call_credentials_free_internal(p);
196
- grpc_ruby_shutdown();
197
196
  }
198
197
 
199
198
  /* Protects the mark object from GC */