grpc 1.19.0 → 1.20.0.pre1

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 (224) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +4131 -7903
  3. data/include/grpc/grpc.h +11 -6
  4. data/include/grpc/grpc_security.h +51 -9
  5. data/include/grpc/impl/codegen/byte_buffer.h +13 -0
  6. data/include/grpc/impl/codegen/grpc_types.h +4 -0
  7. data/include/grpc/impl/codegen/port_platform.h +37 -6
  8. data/include/grpc/impl/codegen/sync_posix.h +18 -0
  9. data/src/core/ext/filters/client_channel/client_channel.cc +560 -236
  10. data/src/core/ext/filters/client_channel/client_channel_channelz.h +2 -2
  11. data/src/core/ext/filters/client_channel/client_channel_factory.cc +22 -34
  12. data/src/core/ext/filters/client_channel/client_channel_factory.h +19 -38
  13. data/src/core/ext/filters/client_channel/global_subchannel_pool.cc +7 -4
  14. data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +2 -2
  15. data/src/core/ext/filters/client_channel/lb_policy.cc +105 -28
  16. data/src/core/ext/filters/client_channel/lb_policy.h +259 -141
  17. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +29 -32
  18. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +789 -803
  19. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h +3 -1
  20. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +2 -6
  21. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc +1 -1
  22. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +7 -1
  23. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +8 -8
  24. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +2 -2
  25. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +127 -219
  26. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +103 -282
  27. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +4 -10
  28. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +709 -906
  29. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc +0 -43
  30. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc +8 -8
  31. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h +2 -2
  32. data/src/core/ext/filters/client_channel/lb_policy_factory.h +1 -6
  33. data/src/core/ext/filters/client_channel/resolver.cc +54 -1
  34. data/src/core/ext/filters/client_channel/resolver.h +51 -22
  35. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +34 -86
  36. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +29 -41
  37. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +32 -78
  38. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +109 -72
  39. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +13 -8
  40. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +28 -63
  41. data/src/core/ext/filters/client_channel/resolver_factory.h +3 -1
  42. data/src/core/ext/filters/client_channel/resolver_registry.cc +5 -2
  43. data/src/core/ext/filters/client_channel/resolver_registry.h +5 -4
  44. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +69 -49
  45. data/src/core/ext/filters/client_channel/resolver_result_parsing.h +11 -8
  46. data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +568 -0
  47. data/src/core/ext/filters/client_channel/resolving_lb_policy.h +141 -0
  48. data/src/core/ext/filters/client_channel/server_address.cc +0 -48
  49. data/src/core/ext/filters/client_channel/server_address.h +0 -10
  50. data/src/core/{lib/transport → ext/filters/client_channel}/service_config.cc +10 -5
  51. data/src/core/{lib/transport → ext/filters/client_channel}/service_config.h +16 -12
  52. data/src/core/ext/filters/client_channel/subchannel.cc +11 -16
  53. data/src/core/ext/filters/client_channel/subchannel.h +3 -0
  54. data/src/core/ext/filters/max_age/max_age_filter.cc +4 -1
  55. data/src/core/ext/filters/message_size/message_size_filter.cc +2 -2
  56. data/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +45 -45
  57. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +133 -134
  58. data/src/core/ext/transport/chttp2/transport/bin_decoder.cc +4 -4
  59. data/src/core/ext/transport/chttp2/transport/bin_decoder.h +4 -4
  60. data/src/core/ext/transport/chttp2/transport/bin_encoder.cc +7 -6
  61. data/src/core/ext/transport/chttp2/transport/bin_encoder.h +4 -3
  62. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +37 -29
  63. data/src/core/ext/transport/chttp2/transport/flow_control.cc +1 -1
  64. data/src/core/ext/transport/chttp2/transport/frame_data.cc +2 -1
  65. data/src/core/ext/transport/chttp2/transport/frame_data.h +1 -1
  66. data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +6 -5
  67. data/src/core/ext/transport/chttp2/transport/frame_goaway.h +3 -2
  68. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +5 -4
  69. data/src/core/ext/transport/chttp2/transport/frame_ping.h +1 -1
  70. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +5 -4
  71. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +2 -1
  72. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +2 -1
  73. data/src/core/ext/transport/chttp2/transport/frame_settings.h +2 -1
  74. data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +4 -4
  75. data/src/core/ext/transport/chttp2/transport/frame_window_update.h +1 -1
  76. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +7 -6
  77. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +3 -2
  78. data/src/core/ext/transport/chttp2/transport/incoming_metadata.cc +9 -5
  79. data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +6 -1
  80. data/src/core/ext/transport/chttp2/transport/internal.h +5 -4
  81. data/src/core/ext/transport/chttp2/transport/parsing.cc +9 -9
  82. data/src/core/ext/transport/chttp2/transport/writing.cc +1 -1
  83. data/src/core/ext/transport/inproc/inproc_transport.cc +8 -0
  84. data/src/core/lib/channel/channel_args.cc +2 -0
  85. data/src/core/lib/channel/channel_args.h +3 -0
  86. data/src/core/lib/channel/channel_stack.h +1 -1
  87. data/src/core/lib/channel/channel_trace.cc +4 -4
  88. data/src/core/lib/channel/channel_trace.h +4 -4
  89. data/src/core/lib/channel/channelz.cc +32 -19
  90. data/src/core/lib/channel/channelz.h +4 -4
  91. data/src/core/lib/channel/channelz_registry.cc +1 -1
  92. data/src/core/lib/channel/context.h +0 -3
  93. data/src/core/lib/channel/handshaker_registry.cc +7 -3
  94. data/src/core/lib/compression/algorithm_metadata.h +3 -3
  95. data/src/core/lib/compression/compression.cc +1 -1
  96. data/src/core/lib/compression/compression_internal.cc +2 -2
  97. data/src/core/lib/compression/stream_compression_gzip.cc +1 -1
  98. data/src/core/lib/debug/trace.h +2 -1
  99. data/src/core/lib/gpr/cpu_posix.cc +5 -3
  100. data/src/core/lib/gpr/sync_posix.cc +65 -4
  101. data/src/core/lib/gprpp/atomic.h +75 -5
  102. data/src/core/lib/gprpp/fork.cc +0 -2
  103. data/src/core/lib/gprpp/orphanable.h +3 -2
  104. data/src/core/lib/gprpp/ref_counted.h +9 -11
  105. data/src/core/lib/gprpp/thd.h +42 -7
  106. data/src/core/lib/gprpp/thd_posix.cc +31 -13
  107. data/src/core/lib/gprpp/thd_windows.cc +47 -34
  108. data/src/core/lib/http/httpcli.cc +3 -2
  109. data/src/core/lib/http/httpcli_security_connector.cc +0 -1
  110. data/src/core/lib/http/parser.cc +2 -1
  111. data/src/core/lib/http/parser.h +2 -1
  112. data/src/core/lib/iomgr/buffer_list.h +1 -1
  113. data/src/core/lib/iomgr/endpoint.cc +2 -2
  114. data/src/core/lib/iomgr/endpoint.h +3 -2
  115. data/src/core/lib/iomgr/error.cc +9 -9
  116. data/src/core/lib/iomgr/error.h +4 -3
  117. data/src/core/lib/iomgr/ev_epoll1_linux.cc +6 -0
  118. data/src/core/lib/iomgr/ev_epollex_linux.cc +14 -9
  119. data/src/core/lib/iomgr/ev_poll_posix.cc +7 -481
  120. data/src/core/lib/iomgr/ev_posix.cc +7 -3
  121. data/src/core/lib/iomgr/ev_posix.h +8 -0
  122. data/src/core/lib/iomgr/executor.cc +13 -0
  123. data/src/core/lib/iomgr/executor.h +2 -1
  124. data/src/core/lib/iomgr/internal_errqueue.cc +2 -4
  125. data/src/core/lib/iomgr/iomgr.cc +5 -0
  126. data/src/core/lib/iomgr/iomgr.h +7 -0
  127. data/src/core/lib/iomgr/iomgr_custom.cc +9 -2
  128. data/src/core/lib/iomgr/iomgr_internal.cc +6 -0
  129. data/src/core/lib/iomgr/iomgr_internal.h +9 -1
  130. data/src/core/lib/iomgr/iomgr_posix.cc +10 -2
  131. data/src/core/lib/iomgr/iomgr_windows.cc +10 -2
  132. data/src/core/lib/iomgr/port.h +19 -0
  133. data/src/core/lib/iomgr/tcp_client_windows.cc +6 -4
  134. data/src/core/lib/iomgr/tcp_custom.cc +1 -1
  135. data/src/core/lib/iomgr/tcp_posix.cc +158 -54
  136. data/src/core/lib/iomgr/tcp_windows.cc +1 -1
  137. data/src/core/lib/iomgr/wakeup_fd_posix.cc +1 -19
  138. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +10 -6
  139. data/src/core/lib/security/credentials/jwt/jwt_verifier.h +2 -1
  140. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +3 -6
  141. data/src/core/lib/security/credentials/tls/spiffe_credentials.cc +129 -0
  142. data/src/core/lib/security/credentials/tls/spiffe_credentials.h +62 -0
  143. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +7 -2
  144. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +28 -17
  145. data/src/core/lib/security/security_connector/ssl_utils.cc +134 -0
  146. data/src/core/lib/security/security_connector/ssl_utils.h +32 -0
  147. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc +426 -0
  148. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.h +122 -0
  149. data/src/core/lib/security/transport/auth_filters.h +2 -2
  150. data/src/core/lib/security/transport/client_auth_filter.cc +35 -39
  151. data/src/core/lib/security/transport/secure_endpoint.cc +2 -2
  152. data/src/core/lib/security/transport/security_handshaker.cc +4 -3
  153. data/src/core/lib/slice/percent_encoding.cc +3 -3
  154. data/src/core/lib/slice/percent_encoding.h +3 -3
  155. data/src/core/lib/slice/slice.cc +27 -30
  156. data/src/core/lib/slice/slice_hash_table.h +2 -2
  157. data/src/core/lib/slice/slice_intern.cc +1 -1
  158. data/src/core/lib/slice/slice_internal.h +14 -3
  159. data/src/core/lib/slice/slice_weak_hash_table.h +4 -4
  160. data/src/core/lib/surface/byte_buffer_reader.cc +17 -0
  161. data/src/core/lib/surface/call.cc +8 -3
  162. data/src/core/lib/surface/completion_queue.cc +134 -148
  163. data/src/core/lib/surface/init.cc +78 -30
  164. data/src/core/lib/surface/init.h +1 -0
  165. data/src/core/lib/surface/lame_client.cc +4 -6
  166. data/src/core/lib/surface/version.cc +1 -1
  167. data/src/core/lib/transport/metadata.cc +66 -33
  168. data/src/core/lib/transport/metadata_batch.cc +1 -1
  169. data/src/core/lib/transport/metadata_batch.h +1 -1
  170. data/src/core/lib/transport/timeout_encoding.cc +1 -1
  171. data/src/core/lib/transport/timeout_encoding.h +1 -1
  172. data/src/core/lib/transport/transport.h +4 -3
  173. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +3 -3
  174. data/src/core/tsi/alts/handshaker/alts_handshaker_client.h +1 -1
  175. data/src/core/tsi/alts/handshaker/transport_security_common_api.cc +4 -3
  176. data/src/core/tsi/alts/handshaker/transport_security_common_api.h +1 -1
  177. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +1 -1
  178. data/src/core/tsi/ssl_transport_security.cc +1 -5
  179. data/src/core/tsi/ssl_transport_security.h +24 -4
  180. data/src/ruby/bin/math_pb.rb +18 -16
  181. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +4 -0
  182. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +6 -0
  183. data/src/ruby/lib/grpc/generic/rpc_server.rb +1 -1
  184. data/src/ruby/lib/grpc/version.rb +1 -1
  185. data/src/ruby/pb/README.md +1 -1
  186. data/src/ruby/pb/grpc/health/v1/health_pb.rb +13 -10
  187. data/src/ruby/pb/grpc/health/v1/health_services_pb.rb +18 -0
  188. data/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb +3 -1
  189. data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +58 -56
  190. data/src/ruby/pb/src/proto/grpc/testing/test_pb.rb +2 -0
  191. data/third_party/cares/cares/ares.h +12 -0
  192. data/third_party/cares/cares/ares_create_query.c +5 -1
  193. data/third_party/cares/cares/ares_data.c +74 -73
  194. data/third_party/cares/cares/ares_destroy.c +6 -1
  195. data/third_party/cares/cares/ares_gethostbyaddr.c +5 -5
  196. data/third_party/cares/cares/ares_gethostbyname.c +15 -4
  197. data/third_party/cares/cares/ares_getnameinfo.c +11 -0
  198. data/third_party/cares/cares/ares_init.c +274 -173
  199. data/third_party/cares/cares/ares_library_init.c +21 -3
  200. data/third_party/cares/cares/ares_options.c +6 -2
  201. data/third_party/cares/cares/ares_parse_naptr_reply.c +7 -6
  202. data/third_party/cares/cares/ares_parse_ptr_reply.c +4 -2
  203. data/third_party/cares/cares/ares_platform.c +7 -0
  204. data/third_party/cares/cares/ares_private.h +19 -11
  205. data/third_party/cares/cares/ares_process.c +27 -2
  206. data/third_party/cares/cares/ares_rules.h +1 -1
  207. data/third_party/cares/cares/ares_search.c +7 -0
  208. data/third_party/cares/cares/ares_send.c +6 -0
  209. data/third_party/cares/cares/ares_strsplit.c +174 -0
  210. data/third_party/cares/cares/ares_strsplit.h +43 -0
  211. data/third_party/cares/cares/ares_version.h +4 -4
  212. data/third_party/cares/cares/config-win32.h +1 -1
  213. data/third_party/cares/cares/inet_ntop.c +2 -3
  214. data/third_party/cares/config_darwin/ares_config.h +3 -0
  215. data/third_party/cares/config_freebsd/ares_config.h +3 -0
  216. data/third_party/cares/config_linux/ares_config.h +3 -0
  217. data/third_party/cares/config_openbsd/ares_config.h +3 -0
  218. metadata +39 -37
  219. data/src/core/ext/filters/client_channel/request_routing.cc +0 -946
  220. data/src/core/ext/filters/client_channel/request_routing.h +0 -181
  221. data/src/core/lib/gprpp/atomic_with_atm.h +0 -57
  222. data/src/core/lib/gprpp/atomic_with_std.h +0 -35
  223. data/src/core/lib/iomgr/wakeup_fd_cv.cc +0 -107
  224. data/src/core/lib/iomgr/wakeup_fd_cv.h +0 -69
@@ -32,7 +32,7 @@
32
32
  /* Interfaces related to MD */
33
33
 
34
34
  grpc_message_compression_algorithm
35
- grpc_message_compression_algorithm_from_slice(grpc_slice str) {
35
+ grpc_message_compression_algorithm_from_slice(const grpc_slice& str) {
36
36
  if (grpc_slice_eq(str, GRPC_MDSTR_IDENTITY))
37
37
  return GRPC_MESSAGE_COMPRESS_NONE;
38
38
  if (grpc_slice_eq(str, GRPC_MDSTR_DEFLATE))
@@ -42,7 +42,7 @@ grpc_message_compression_algorithm_from_slice(grpc_slice str) {
42
42
  }
43
43
 
44
44
  grpc_stream_compression_algorithm grpc_stream_compression_algorithm_from_slice(
45
- grpc_slice str) {
45
+ const grpc_slice& str) {
46
46
  if (grpc_slice_eq(str, GRPC_MDSTR_IDENTITY)) return GRPC_STREAM_COMPRESS_NONE;
47
47
  if (grpc_slice_eq(str, GRPC_MDSTR_GZIP)) return GRPC_STREAM_COMPRESS_GZIP;
48
48
  return GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT;
@@ -60,7 +60,7 @@ static bool gzip_flate(grpc_stream_compression_context_gzip* ctx,
60
60
  if (r < 0 && r != Z_BUF_ERROR) {
61
61
  gpr_log(GPR_ERROR, "zlib error (%d)", r);
62
62
  grpc_slice_unref_internal(slice_out);
63
-
63
+ grpc_slice_unref_internal(slice);
64
64
  return false;
65
65
  } else if (r == Z_STREAM_END && ctx->flate == inflate) {
66
66
  eoc = true;
@@ -53,7 +53,8 @@ void grpc_tracer_enable_flag(grpc_core::TraceFlag* flag);
53
53
  class TraceFlag {
54
54
  public:
55
55
  TraceFlag(bool default_enabled, const char* name);
56
- // This needs to be trivially destructible as it is used as global variable.
56
+ // TraceFlag needs to be trivially destructible since it is used as global
57
+ // variable.
57
58
  ~TraceFlag() = default;
58
59
 
59
60
  const char* name() const { return name_; }
@@ -25,7 +25,6 @@
25
25
  #include <string.h>
26
26
  #include <unistd.h>
27
27
 
28
- #include <grpc/support/alloc.h>
29
28
  #include <grpc/support/cpu.h>
30
29
  #include <grpc/support/log.h>
31
30
  #include <grpc/support/sync.h>
@@ -52,7 +51,7 @@ unsigned gpr_cpu_num_cores(void) {
52
51
 
53
52
  static void delete_thread_id(void* value) {
54
53
  if (value) {
55
- gpr_free(value);
54
+ free(value);
56
55
  }
57
56
  }
58
57
 
@@ -71,7 +70,10 @@ unsigned gpr_cpu_current_cpu(void) {
71
70
  unsigned int* thread_id =
72
71
  static_cast<unsigned int*>(pthread_getspecific(thread_id_key));
73
72
  if (thread_id == nullptr) {
74
- thread_id = static_cast<unsigned int*>(gpr_malloc(sizeof(unsigned int)));
73
+ // Note we cannot use gpr_malloc here because this allocation can happen in
74
+ // a main thread and will only be free'd when the main thread exits, which
75
+ // will cause our internal memory counters to believe it is a leak.
76
+ thread_id = static_cast<unsigned int*>(malloc(sizeof(unsigned int)));
75
77
  pthread_setspecific(thread_id_key, thread_id);
76
78
  }
77
79
 
@@ -18,6 +18,8 @@
18
18
 
19
19
  #include <grpc/support/port_platform.h>
20
20
 
21
+ #include <grpc/support/alloc.h>
22
+
21
23
  #ifdef GPR_POSIX_SYNC
22
24
 
23
25
  #include <errno.h>
@@ -72,27 +74,53 @@ gpr_atm gpr_counter_atm_add = 0;
72
74
  #endif
73
75
 
74
76
  void gpr_mu_init(gpr_mu* mu) {
77
+ #ifdef GRPC_ASAN_ENABLED
78
+ GPR_ASSERT(pthread_mutex_init(&mu->mutex, nullptr) == 0);
79
+ mu->leak_checker = static_cast<int*>(malloc(sizeof(*mu->leak_checker)));
80
+ GPR_ASSERT(mu->leak_checker != nullptr);
81
+ #else
75
82
  GPR_ASSERT(pthread_mutex_init(mu, nullptr) == 0);
83
+ #endif
76
84
  }
77
85
 
78
- void gpr_mu_destroy(gpr_mu* mu) { GPR_ASSERT(pthread_mutex_destroy(mu) == 0); }
86
+ void gpr_mu_destroy(gpr_mu* mu) {
87
+ #ifdef GRPC_ASAN_ENABLED
88
+ GPR_ASSERT(pthread_mutex_destroy(&mu->mutex) == 0);
89
+ free(mu->leak_checker);
90
+ #else
91
+ GPR_ASSERT(pthread_mutex_destroy(mu) == 0);
92
+ #endif
93
+ }
79
94
 
80
95
  void gpr_mu_lock(gpr_mu* mu) {
81
96
  #ifdef GPR_LOW_LEVEL_COUNTERS
82
97
  GPR_ATM_INC_COUNTER(gpr_mu_locks);
83
98
  #endif
84
99
  GPR_TIMER_SCOPE("gpr_mu_lock", 0);
100
+ #ifdef GRPC_ASAN_ENABLED
101
+ GPR_ASSERT(pthread_mutex_lock(&mu->mutex) == 0);
102
+ #else
85
103
  GPR_ASSERT(pthread_mutex_lock(mu) == 0);
104
+ #endif
86
105
  }
87
106
 
88
107
  void gpr_mu_unlock(gpr_mu* mu) {
89
108
  GPR_TIMER_SCOPE("gpr_mu_unlock", 0);
109
+ #ifdef GRPC_ASAN_ENABLED
110
+ GPR_ASSERT(pthread_mutex_unlock(&mu->mutex) == 0);
111
+ #else
90
112
  GPR_ASSERT(pthread_mutex_unlock(mu) == 0);
113
+ #endif
91
114
  }
92
115
 
93
116
  int gpr_mu_trylock(gpr_mu* mu) {
94
117
  GPR_TIMER_SCOPE("gpr_mu_trylock", 0);
95
- int err = pthread_mutex_trylock(mu);
118
+ int err = 0;
119
+ #ifdef GRPC_ASAN_ENABLED
120
+ err = pthread_mutex_trylock(&mu->mutex);
121
+ #else
122
+ err = pthread_mutex_trylock(mu);
123
+ #endif
96
124
  GPR_ASSERT(err == 0 || err == EBUSY);
97
125
  return err == 0;
98
126
  }
@@ -105,10 +133,24 @@ void gpr_cv_init(gpr_cv* cv) {
105
133
  #if GPR_LINUX
106
134
  GPR_ASSERT(pthread_condattr_setclock(&attr, CLOCK_MONOTONIC) == 0);
107
135
  #endif // GPR_LINUX
136
+
137
+ #ifdef GRPC_ASAN_ENABLED
138
+ GPR_ASSERT(pthread_cond_init(&cv->cond_var, &attr) == 0);
139
+ cv->leak_checker = static_cast<int*>(malloc(sizeof(*cv->leak_checker)));
140
+ GPR_ASSERT(cv->leak_checker != nullptr);
141
+ #else
108
142
  GPR_ASSERT(pthread_cond_init(cv, &attr) == 0);
143
+ #endif
109
144
  }
110
145
 
111
- void gpr_cv_destroy(gpr_cv* cv) { GPR_ASSERT(pthread_cond_destroy(cv) == 0); }
146
+ void gpr_cv_destroy(gpr_cv* cv) {
147
+ #ifdef GRPC_ASAN_ENABLED
148
+ GPR_ASSERT(pthread_cond_destroy(&cv->cond_var) == 0);
149
+ free(cv->leak_checker);
150
+ #else
151
+ GPR_ASSERT(pthread_cond_destroy(cv) == 0);
152
+ #endif
153
+ }
112
154
 
113
155
  // For debug of the timer manager crash only.
114
156
  // TODO (mxyan): remove after bug is fixed.
@@ -169,7 +211,11 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) {
169
211
  #endif
170
212
  if (gpr_time_cmp(abs_deadline, gpr_inf_future(abs_deadline.clock_type)) ==
171
213
  0) {
214
+ #ifdef GRPC_ASAN_ENABLED
215
+ err = pthread_cond_wait(&cv->cond_var, &mu->mutex);
216
+ #else
172
217
  err = pthread_cond_wait(cv, mu);
218
+ #endif
173
219
  } else {
174
220
  struct timespec abs_deadline_ts;
175
221
  #if GPR_LINUX
@@ -181,7 +227,12 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) {
181
227
  #endif // GPR_LINUX
182
228
  abs_deadline_ts.tv_sec = static_cast<time_t>(abs_deadline.tv_sec);
183
229
  abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec;
230
+ #ifdef GRPC_ASAN_ENABLED
231
+ err = pthread_cond_timedwait(&cv->cond_var, &mu->mutex, &abs_deadline_ts);
232
+ #else
184
233
  err = pthread_cond_timedwait(cv, mu, &abs_deadline_ts);
234
+ #endif
235
+
185
236
  #ifdef GRPC_DEBUG_TIMER_MANAGER
186
237
  // For debug of the timer manager crash only.
187
238
  // TODO (mxyan): remove after bug is fixed.
@@ -226,10 +277,20 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) {
226
277
  return err == ETIMEDOUT;
227
278
  }
228
279
 
229
- void gpr_cv_signal(gpr_cv* cv) { GPR_ASSERT(pthread_cond_signal(cv) == 0); }
280
+ void gpr_cv_signal(gpr_cv* cv) {
281
+ #ifdef GRPC_ASAN_ENABLED
282
+ GPR_ASSERT(pthread_cond_signal(&cv->cond_var) == 0);
283
+ #else
284
+ GPR_ASSERT(pthread_cond_signal(cv) == 0);
285
+ #endif
286
+ }
230
287
 
231
288
  void gpr_cv_broadcast(gpr_cv* cv) {
289
+ #ifdef GRPC_ASAN_ENABLED
290
+ GPR_ASSERT(pthread_cond_broadcast(&cv->cond_var) == 0);
291
+ #else
232
292
  GPR_ASSERT(pthread_cond_broadcast(cv) == 0);
293
+ #endif
233
294
  }
234
295
 
235
296
  /*----------------------------------------*/
@@ -21,10 +21,80 @@
21
21
 
22
22
  #include <grpc/support/port_platform.h>
23
23
 
24
- #ifdef GPR_HAS_CXX11_ATOMIC
25
- #include "src/core/lib/gprpp/atomic_with_std.h"
26
- #else
27
- #include "src/core/lib/gprpp/atomic_with_atm.h"
28
- #endif
24
+ #include <atomic>
25
+
26
+ #include <grpc/support/atm.h>
27
+
28
+ namespace grpc_core {
29
+
30
+ enum class MemoryOrder {
31
+ RELAXED = std::memory_order_relaxed,
32
+ CONSUME = std::memory_order_consume,
33
+ ACQUIRE = std::memory_order_acquire,
34
+ RELEASE = std::memory_order_release,
35
+ ACQ_REL = std::memory_order_acq_rel,
36
+ SEQ_CST = std::memory_order_seq_cst
37
+ };
38
+
39
+ template <typename T>
40
+ class Atomic {
41
+ public:
42
+ explicit Atomic(T val = T()) : storage_(val) {}
43
+
44
+ T Load(MemoryOrder order) const {
45
+ return storage_.load(static_cast<std::memory_order>(order));
46
+ }
47
+
48
+ void Store(T val, MemoryOrder order) {
49
+ storage_.store(val, static_cast<std::memory_order>(order));
50
+ }
51
+
52
+ bool CompareExchangeWeak(T* expected, T desired, MemoryOrder success,
53
+ MemoryOrder failure) {
54
+ return GPR_ATM_INC_CAS_THEN(storage_.compare_exchange_weak(
55
+ *expected, desired, static_cast<std::memory_order>(success),
56
+ static_cast<std::memory_order>(failure)));
57
+ }
58
+
59
+ bool CompareExchangeStrong(T* expected, T desired, MemoryOrder success,
60
+ MemoryOrder failure) {
61
+ return GPR_ATM_INC_CAS_THEN(storage_.compare_exchange_strong(
62
+ *expected, desired, static_cast<std::memory_order>(success),
63
+ static_cast<std::memory_order>(failure)));
64
+ }
65
+
66
+ template <typename Arg>
67
+ T FetchAdd(Arg arg, MemoryOrder order = MemoryOrder::SEQ_CST) {
68
+ return GPR_ATM_INC_ADD_THEN(storage_.fetch_add(
69
+ static_cast<Arg>(arg), static_cast<std::memory_order>(order)));
70
+ }
71
+
72
+ template <typename Arg>
73
+ T FetchSub(Arg arg, MemoryOrder order = MemoryOrder::SEQ_CST) {
74
+ return GPR_ATM_INC_ADD_THEN(storage_.fetch_sub(
75
+ static_cast<Arg>(arg), static_cast<std::memory_order>(order)));
76
+ }
77
+
78
+ // Atomically increment a counter only if the counter value is not zero.
79
+ // Returns true if increment took place; false if counter is zero.
80
+ bool IncrementIfNonzero(MemoryOrder load_order = MemoryOrder::ACQUIRE) {
81
+ T count = storage_.load(static_cast<std::memory_order>(load_order));
82
+ do {
83
+ // If zero, we are done (without an increment). If not, we must do a CAS
84
+ // to maintain the contract: do not increment the counter if it is already
85
+ // zero
86
+ if (count == 0) {
87
+ return false;
88
+ }
89
+ } while (!CompareExchangeWeak(&count, count + 1, MemoryOrder::ACQ_REL,
90
+ load_order));
91
+ return true;
92
+ }
93
+
94
+ private:
95
+ std::atomic<T> storage_;
96
+ };
97
+
98
+ } // namespace grpc_core
29
99
 
30
100
  #endif /* GRPC_CORE_LIB_GPRPP_ATOMIC_H */
@@ -160,8 +160,6 @@ void Fork::GlobalInit() {
160
160
  if (!override_enabled_) {
161
161
  #ifdef GRPC_ENABLE_FORK_SUPPORT
162
162
  support_enabled_ = true;
163
- #else
164
- support_enabled_ = false;
165
163
  #endif
166
164
  bool env_var_set = false;
167
165
  char* env = gpr_getenv("GRPC_ENABLE_FORK_SUPPORT");
@@ -94,8 +94,9 @@ class InternallyRefCounted : public Orphanable {
94
94
  // Note: RefCount tracing is only enabled on debug builds, even when a
95
95
  // TraceFlag is used.
96
96
  template <typename TraceFlagT = TraceFlag>
97
- explicit InternallyRefCounted(TraceFlagT* trace_flag = nullptr)
98
- : refs_(1, trace_flag) {}
97
+ explicit InternallyRefCounted(TraceFlagT* trace_flag = nullptr,
98
+ intptr_t initial_refcount = 1)
99
+ : refs_(initial_refcount, trace_flag) {}
99
100
  virtual ~InternallyRefCounted() = default;
100
101
 
101
102
  RefCountedPtr<Child> Ref() GRPC_MUST_USE_RESULT {
@@ -31,6 +31,7 @@
31
31
 
32
32
  #include "src/core/lib/debug/trace.h"
33
33
  #include "src/core/lib/gprpp/abstract.h"
34
+ #include "src/core/lib/gprpp/atomic.h"
34
35
  #include "src/core/lib/gprpp/debug_location.h"
35
36
  #include "src/core/lib/gprpp/memory.h"
36
37
  #include "src/core/lib/gprpp/ref_counted_ptr.h"
@@ -88,9 +89,7 @@ class RefCount {
88
89
  }
89
90
 
90
91
  // Increases the ref-count by `n`.
91
- void Ref(Value n = 1) {
92
- GPR_ATM_INC_ADD_THEN(value_.fetch_add(n, std::memory_order_relaxed));
93
- }
92
+ void Ref(Value n = 1) { value_.FetchAdd(n, MemoryOrder::RELAXED); }
94
93
  void Ref(const DebugLocation& location, const char* reason, Value n = 1) {
95
94
  #ifndef NDEBUG
96
95
  if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) {
@@ -106,8 +105,7 @@ class RefCount {
106
105
  // Similar to Ref() with an assert on the ref-count being non-zero.
107
106
  void RefNonZero() {
108
107
  #ifndef NDEBUG
109
- const Value prior =
110
- GPR_ATM_INC_ADD_THEN(value_.fetch_add(1, std::memory_order_relaxed));
108
+ const Value prior = value_.FetchAdd(1, MemoryOrder::RELAXED);
111
109
  assert(prior > 0);
112
110
  #else
113
111
  Ref();
@@ -127,8 +125,7 @@ class RefCount {
127
125
 
128
126
  // Decrements the ref-count and returns true if the ref-count reaches 0.
129
127
  bool Unref() {
130
- const Value prior =
131
- GPR_ATM_INC_ADD_THEN(value_.fetch_sub(1, std::memory_order_acq_rel));
128
+ const Value prior = value_.FetchSub(1, MemoryOrder::ACQ_REL);
132
129
  GPR_DEBUG_ASSERT(prior > 0);
133
130
  return prior == 1;
134
131
  }
@@ -145,12 +142,12 @@ class RefCount {
145
142
  }
146
143
 
147
144
  private:
148
- Value get() const { return value_.load(std::memory_order_relaxed); }
145
+ Value get() const { return value_.Load(MemoryOrder::RELAXED); }
149
146
 
150
147
  #ifndef NDEBUG
151
148
  TraceFlag* trace_flag_;
152
149
  #endif
153
- std::atomic<Value> value_;
150
+ Atomic<Value> value_;
154
151
  };
155
152
 
156
153
  // A base class for reference-counted objects.
@@ -221,8 +218,9 @@ class RefCounted : public Impl {
221
218
  // Note: RefCount tracing is only enabled on debug builds, even when a
222
219
  // TraceFlag is used.
223
220
  template <typename TraceFlagT = TraceFlag>
224
- explicit RefCounted(TraceFlagT* trace_flag = nullptr)
225
- : refs_(1, trace_flag) {}
221
+ explicit RefCounted(TraceFlagT* trace_flag = nullptr,
222
+ intptr_t initial_refcount = 1)
223
+ : refs_(initial_refcount, trace_flag) {}
226
224
 
227
225
  // Note: Depending on the Impl used, this dtor can be implicitly virtual.
228
226
  ~RefCounted() = default;
@@ -47,6 +47,27 @@ class ThreadInternalsInterface {
47
47
 
48
48
  class Thread {
49
49
  public:
50
+ class Options {
51
+ public:
52
+ Options() : joinable_(true), tracked_(true) {}
53
+ /// Set whether the thread is joinable or detached.
54
+ Options& set_joinable(bool joinable) {
55
+ joinable_ = joinable;
56
+ return *this;
57
+ }
58
+ bool joinable() const { return joinable_; }
59
+
60
+ /// Set whether the thread is tracked for fork support.
61
+ Options& set_tracked(bool tracked) {
62
+ tracked_ = tracked;
63
+ return *this;
64
+ }
65
+ bool tracked() const { return tracked_; }
66
+
67
+ private:
68
+ bool joinable_;
69
+ bool tracked_;
70
+ };
50
71
  /// Default constructor only to allow use in structs that lack constructors
51
72
  /// Does not produce a validly-constructed thread; must later
52
73
  /// use placement new to construct a real thread. Does not init mu_ and cv_
@@ -57,14 +78,17 @@ class Thread {
57
78
  /// with argument \a arg once it is started.
58
79
  /// The optional \a success argument indicates whether the thread
59
80
  /// is successfully created.
81
+ /// The optional \a options can be used to set the thread detachable.
60
82
  Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg,
61
- bool* success = nullptr);
83
+ bool* success = nullptr, const Options& options = Options());
62
84
 
63
85
  /// Move constructor for thread. After this is called, the other thread
64
86
  /// no longer represents a living thread object
65
- Thread(Thread&& other) : state_(other.state_), impl_(other.impl_) {
87
+ Thread(Thread&& other)
88
+ : state_(other.state_), impl_(other.impl_), options_(other.options_) {
66
89
  other.state_ = MOVED;
67
90
  other.impl_ = nullptr;
91
+ other.options_ = Options();
68
92
  }
69
93
 
70
94
  /// Move assignment operator for thread. After this is called, the other
@@ -79,27 +103,37 @@ class Thread {
79
103
  // assert it for the time being.
80
104
  state_ = other.state_;
81
105
  impl_ = other.impl_;
106
+ options_ = other.options_;
82
107
  other.state_ = MOVED;
83
108
  other.impl_ = nullptr;
109
+ other.options_ = Options();
84
110
  }
85
111
  return *this;
86
112
  }
87
113
 
88
114
  /// The destructor is strictly optional; either the thread never came to life
89
- /// and the constructor itself killed it or it has already been joined and
90
- /// the Join function kills it. The destructor shouldn't have to do anything.
91
- ~Thread() { GPR_ASSERT(impl_ == nullptr); }
115
+ /// and the constructor itself killed it, or it has already been joined and
116
+ /// the Join function kills it, or it was detached (non-joinable) and it has
117
+ /// run to completion and is now killing itself. The destructor shouldn't have
118
+ /// to do anything.
119
+ ~Thread() { GPR_ASSERT(!options_.joinable() || impl_ == nullptr); }
92
120
 
93
121
  void Start() {
94
122
  if (impl_ != nullptr) {
95
123
  GPR_ASSERT(state_ == ALIVE);
96
124
  state_ = STARTED;
97
125
  impl_->Start();
126
+ // If the Thread is not joinable, then the impl_ will cause the deletion
127
+ // of this Thread object when the thread function completes. Since no
128
+ // other operation is allowed to a detached thread after Start, there is
129
+ // no need to change the value of the impl_ or state_ . The next operation
130
+ // on this object will be the deletion, which will trigger the destructor.
98
131
  } else {
99
132
  GPR_ASSERT(state_ == FAILED);
100
133
  }
101
- };
134
+ }
102
135
 
136
+ // It is only legal to call Join if the Thread is created as joinable.
103
137
  void Join() {
104
138
  if (impl_ != nullptr) {
105
139
  impl_->Join();
@@ -109,7 +143,7 @@ class Thread {
109
143
  } else {
110
144
  GPR_ASSERT(state_ == FAILED);
111
145
  }
112
- };
146
+ }
113
147
 
114
148
  private:
115
149
  Thread(const Thread&) = delete;
@@ -125,6 +159,7 @@ class Thread {
125
159
  enum ThreadState { FAKE, ALIVE, STARTED, DONE, FAILED, MOVED };
126
160
  ThreadState state_;
127
161
  internal::ThreadInternalsInterface* impl_;
162
+ Options options_;
128
163
  };
129
164
 
130
165
  } // namespace grpc_core