grpc 1.14.2 → 1.15.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 (113) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +307 -12
  3. data/etc/roots.pem +40 -163
  4. data/include/grpc/grpc.h +49 -0
  5. data/include/grpc/grpc_security.h +0 -6
  6. data/include/grpc/grpc_security_constants.h +6 -0
  7. data/include/grpc/impl/codegen/grpc_types.h +17 -2
  8. data/include/grpc/impl/codegen/port_platform.h +41 -4
  9. data/include/grpc/support/sync.h +0 -16
  10. data/src/{cpp → core}/ext/filters/census/grpc_context.cc +0 -0
  11. data/src/core/ext/filters/client_channel/client_channel.cc +40 -11
  12. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +11 -9
  13. data/src/core/ext/filters/client_channel/client_channel_channelz.h +4 -2
  14. data/src/core/ext/filters/client_channel/lb_policy.h +14 -11
  15. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +67 -90
  16. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +108 -91
  17. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +79 -25
  18. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +40 -0
  19. data/src/core/ext/filters/client_channel/resolver.h +8 -0
  20. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +11 -3
  21. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +13 -10
  22. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +18 -4
  23. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +13 -5
  24. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +537 -0
  25. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +6 -5
  26. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +11 -0
  27. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc +29 -0
  28. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +29 -0
  29. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +9 -0
  30. data/src/core/ext/filters/client_channel/subchannel.cc +21 -8
  31. data/src/core/ext/filters/client_channel/subchannel.h +7 -0
  32. data/src/core/ext/filters/http/client_authority_filter.cc +1 -1
  33. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +24 -0
  34. data/src/core/ext/transport/chttp2/transport/flow_control.cc +10 -7
  35. data/src/core/lib/channel/channel_stack.h +1 -1
  36. data/src/core/lib/channel/channel_trace.cc +1 -1
  37. data/src/core/lib/channel/channel_trace.h +1 -1
  38. data/src/core/lib/channel/channelz.cc +37 -27
  39. data/src/core/lib/channel/channelz.h +13 -4
  40. data/src/core/lib/channel/channelz_registry.cc +89 -4
  41. data/src/core/lib/channel/channelz_registry.h +56 -39
  42. data/src/core/lib/gpr/arena.cc +33 -40
  43. data/src/core/lib/gprpp/fork.cc +41 -33
  44. data/src/core/lib/gprpp/fork.h +13 -4
  45. data/src/core/lib/gprpp/mutex_lock.h +42 -0
  46. data/src/core/lib/gprpp/orphanable.h +4 -2
  47. data/src/core/lib/gprpp/ref_counted.h +4 -2
  48. data/src/core/lib/gprpp/ref_counted_ptr.h +65 -13
  49. data/src/core/lib/iomgr/call_combiner.h +4 -1
  50. data/src/core/lib/iomgr/ev_epoll1_linux.cc +77 -17
  51. data/src/core/lib/iomgr/ev_epollex_linux.cc +8 -26
  52. data/src/core/lib/iomgr/ev_epollsig_linux.cc +10 -28
  53. data/src/core/lib/iomgr/ev_poll_posix.cc +144 -35
  54. data/src/core/lib/iomgr/ev_posix.cc +58 -9
  55. data/src/core/lib/iomgr/ev_posix.h +22 -8
  56. data/src/core/lib/iomgr/exec_ctx.cc +6 -0
  57. data/src/core/lib/iomgr/exec_ctx.h +2 -0
  58. data/src/core/lib/iomgr/executor.cc +148 -72
  59. data/src/core/lib/iomgr/executor.h +39 -6
  60. data/src/core/lib/iomgr/fork_posix.cc +12 -1
  61. data/src/core/lib/iomgr/iocp_windows.cc +9 -4
  62. data/src/core/lib/iomgr/lockfree_event.cc +5 -1
  63. data/src/core/lib/iomgr/port.h +15 -2
  64. data/src/core/lib/iomgr/resolve_address_posix.cc +3 -2
  65. data/src/core/lib/iomgr/resolve_address_windows.cc +3 -2
  66. data/src/core/lib/iomgr/resource_quota.cc +78 -0
  67. data/src/core/lib/iomgr/resource_quota.h +16 -0
  68. data/src/core/lib/iomgr/socket_mutator.cc +1 -1
  69. data/src/core/lib/iomgr/socket_mutator.h +1 -1
  70. data/src/core/lib/iomgr/socket_windows.cc +33 -0
  71. data/src/core/lib/iomgr/socket_windows.h +6 -0
  72. data/src/core/lib/iomgr/tcp_windows.cc +2 -2
  73. data/src/core/lib/iomgr/tcp_windows.h +2 -0
  74. data/src/core/lib/iomgr/timer.h +3 -2
  75. data/src/core/lib/json/json.cc +2 -1
  76. data/src/core/lib/security/credentials/jwt/json_token.h +2 -0
  77. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +2 -0
  78. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +1 -1
  79. data/src/core/lib/security/security_connector/load_system_roots.h +29 -0
  80. data/src/core/lib/security/security_connector/load_system_roots_fallback.cc +32 -0
  81. data/src/core/lib/security/security_connector/load_system_roots_linux.cc +165 -0
  82. data/src/core/lib/security/security_connector/load_system_roots_linux.h +44 -0
  83. data/src/core/lib/security/security_connector/security_connector.cc +23 -4
  84. data/src/core/lib/security/transport/client_auth_filter.cc +0 -4
  85. data/src/core/lib/security/transport/server_auth_filter.cc +0 -2
  86. data/src/core/lib/surface/call.cc +7 -3
  87. data/src/core/lib/surface/channel.cc +18 -2
  88. data/src/core/lib/surface/completion_queue.cc +152 -15
  89. data/src/core/lib/surface/completion_queue.h +20 -1
  90. data/src/core/lib/surface/completion_queue_factory.cc +13 -4
  91. data/src/core/lib/surface/init.cc +2 -2
  92. data/src/core/lib/surface/init.h +0 -1
  93. data/src/core/lib/surface/version.cc +2 -2
  94. data/src/core/lib/transport/service_config.cc +2 -2
  95. data/src/core/lib/transport/service_config.h +3 -3
  96. data/src/core/lib/transport/transport.h +2 -0
  97. data/src/core/tsi/alts/crypt/aes_gcm.cc +2 -0
  98. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +8 -0
  99. data/src/core/tsi/grpc_shadow_boringssl.h +3006 -0
  100. data/src/core/tsi/ssl/session_cache/ssl_session.h +2 -0
  101. data/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +5 -5
  102. data/src/core/tsi/ssl/session_cache/ssl_session_cache.h +2 -0
  103. data/src/core/tsi/ssl_transport_security.cc +5 -3
  104. data/src/core/tsi/ssl_types.h +2 -0
  105. data/src/ruby/ext/grpc/extconf.rb +1 -26
  106. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +12 -0
  107. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +18 -0
  108. data/src/ruby/lib/grpc/version.rb +1 -1
  109. data/src/ruby/spec/generic/client_stub_spec.rb +3 -3
  110. data/third_party/address_sorting/address_sorting.c +7 -2
  111. data/third_party/address_sorting/address_sorting_windows.c +43 -3
  112. data/third_party/address_sorting/include/address_sorting/address_sorting.h +3 -0
  113. metadata +40 -31
@@ -46,6 +46,7 @@
46
46
  #include "src/core/lib/gpr/tls.h"
47
47
  #include "src/core/lib/gpr/useful.h"
48
48
  #include "src/core/lib/gprpp/manual_constructor.h"
49
+ #include "src/core/lib/gprpp/mutex_lock.h"
49
50
  #include "src/core/lib/iomgr/block_annotate.h"
50
51
  #include "src/core/lib/iomgr/iomgr_internal.h"
51
52
  #include "src/core/lib/iomgr/is_epollexclusive_available.h"
@@ -135,7 +136,7 @@ struct pollable {
135
136
  // underlying epoll set (i.e whenever fd_orphan() is called).
136
137
  //
137
138
  // Implementing (2) above (i.e removing fds from cache on fd_orphan) adds a
138
- // lot of complexity since an fd can be present in multiple pollalbles. So our
139
+ // lot of complexity since an fd can be present in multiple pollables. So our
139
140
  // implementation ONLY DOES (1) and NOT (2).
140
141
  //
141
142
  // The cache_fd.salt variable helps here to maintain correctness (it serves as
@@ -220,10 +221,6 @@ struct grpc_fd {
220
221
  struct grpc_fd* freelist_next;
221
222
  grpc_closure* on_done_closure;
222
223
 
223
- // The pollset that last noticed that the fd is readable. The actual type
224
- // stored in this is (grpc_pollset *)
225
- gpr_atm read_notifier_pollset;
226
-
227
224
  grpc_iomgr_object iomgr_object;
228
225
 
229
226
  // Do we need to track EPOLLERR events separately?
@@ -353,7 +350,6 @@ static void invalidate_fd(grpc_fd* fd) {
353
350
  memset(&fd->pollable_mu, -1, sizeof(fd->pollable_mu));
354
351
  fd->pollable_obj = nullptr;
355
352
  fd->on_done_closure = nullptr;
356
- gpr_atm_no_barrier_store(&fd->read_notifier_pollset, 0);
357
353
  memset(&fd->iomgr_object, -1, sizeof(fd->iomgr_object));
358
354
  fd->track_err = false;
359
355
  }
@@ -445,7 +441,6 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) {
445
441
  new_fd->error_closure->InitEvent();
446
442
  new_fd->freelist_next = nullptr;
447
443
  new_fd->on_done_closure = nullptr;
448
- gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
449
444
 
450
445
  char* fd_name;
451
446
  gpr_asprintf(&fd_name, "%s fd=%d", name, fd);
@@ -514,11 +509,6 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
514
509
  UNREF_BY(fd, 2, reason); /* Drop the reference */
515
510
  }
516
511
 
517
- static grpc_pollset* fd_get_read_notifier_pollset(grpc_fd* fd) {
518
- gpr_atm notifier = gpr_atm_acq_load(&fd->read_notifier_pollset);
519
- return (grpc_pollset*)notifier;
520
- }
521
-
522
512
  static bool fd_is_shutdown(grpc_fd* fd) {
523
513
  return fd->read_closure->IsShutdown();
524
514
  }
@@ -746,7 +736,7 @@ static void pollset_maybe_finish_shutdown(grpc_pollset* pollset) {
746
736
  static grpc_error* kick_one_worker(grpc_pollset_worker* specific_worker) {
747
737
  GPR_TIMER_SCOPE("kick_one_worker", 0);
748
738
  pollable* p = specific_worker->pollable_obj;
749
- grpc_core::mu_guard lock(&p->mu);
739
+ grpc_core::MutexLock lock(&p->mu);
750
740
  GPR_ASSERT(specific_worker != nullptr);
751
741
  if (specific_worker->kicked) {
752
742
  if (grpc_polling_trace.enabled()) {
@@ -875,17 +865,7 @@ static int poll_deadline_to_millis_timeout(grpc_millis millis) {
875
865
  return static_cast<int>(delta);
876
866
  }
877
867
 
878
- static void fd_become_readable(grpc_fd* fd, grpc_pollset* notifier) {
879
- fd->read_closure->SetReady();
880
-
881
- /* Note, it is possible that fd_become_readable might be called twice with
882
- different 'notifier's when an fd becomes readable and it is in two epoll
883
- sets (This can happen briefly during polling island merges). In such cases
884
- it does not really matter which notifer is set as the read_notifier_pollset
885
- (They would both point to the same polling island anyway) */
886
- /* Use release store to match with acquire load in fd_get_read_notifier */
887
- gpr_atm_rel_store(&fd->read_notifier_pollset, (gpr_atm)notifier);
888
- }
868
+ static void fd_become_readable(grpc_fd* fd) { fd->read_closure->SetReady(); }
889
869
 
890
870
  static void fd_become_writable(grpc_fd* fd) { fd->write_closure->SetReady(); }
891
871
 
@@ -983,7 +963,7 @@ static grpc_error* pollable_process_events(grpc_pollset* pollset,
983
963
  fd_has_errors(fd);
984
964
  }
985
965
  if (read_ev || cancel || err_fallback) {
986
- fd_become_readable(fd, pollset);
966
+ fd_become_readable(fd);
987
967
  }
988
968
  if (write_ev || cancel || err_fallback) {
989
969
  fd_become_writable(fd);
@@ -1636,8 +1616,10 @@ static const grpc_event_engine_vtable vtable = {
1636
1616
  fd_notify_on_read,
1637
1617
  fd_notify_on_write,
1638
1618
  fd_notify_on_error,
1619
+ fd_become_readable,
1620
+ fd_become_writable,
1621
+ fd_has_errors,
1639
1622
  fd_is_shutdown,
1640
- fd_get_read_notifier_pollset,
1641
1623
 
1642
1624
  pollset_init,
1643
1625
  pollset_shutdown,
@@ -137,10 +137,6 @@ struct grpc_fd {
137
137
  struct grpc_fd* freelist_next;
138
138
  grpc_closure* on_done_closure;
139
139
 
140
- /* The pollset that last noticed that the fd is readable. The actual type
141
- * stored in this is (grpc_pollset *) */
142
- gpr_atm read_notifier_pollset;
143
-
144
140
  grpc_iomgr_object iomgr_object;
145
141
 
146
142
  /* Do we need to track EPOLLERR events separately? */
@@ -845,7 +841,6 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) {
845
841
  new_fd->write_closure->InitEvent();
846
842
  new_fd->error_closure->InitEvent();
847
843
  new_fd->track_err = track_err;
848
- gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
849
844
 
850
845
  new_fd->freelist_next = nullptr;
851
846
  new_fd->on_done_closure = nullptr;
@@ -927,11 +922,6 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
927
922
  GRPC_ERROR_UNREF(error);
928
923
  }
929
924
 
930
- static grpc_pollset* fd_get_read_notifier_pollset(grpc_fd* fd) {
931
- gpr_atm notifier = gpr_atm_acq_load(&fd->read_notifier_pollset);
932
- return (grpc_pollset*)notifier;
933
- }
934
-
935
925
  static bool fd_is_shutdown(grpc_fd* fd) {
936
926
  return fd->read_closure->IsShutdown();
937
927
  }
@@ -958,6 +948,12 @@ static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) {
958
948
  fd->error_closure->NotifyOn(closure);
959
949
  }
960
950
 
951
+ static void fd_become_readable(grpc_fd* fd) { fd->read_closure->SetReady(); }
952
+
953
+ static void fd_become_writable(grpc_fd* fd) { fd->write_closure->SetReady(); }
954
+
955
+ static void fd_has_errors(grpc_fd* fd) { fd->error_closure->SetReady(); }
956
+
961
957
  /*******************************************************************************
962
958
  * Pollset Definitions
963
959
  */
@@ -1115,22 +1111,6 @@ static int poll_deadline_to_millis_timeout(grpc_millis millis) {
1115
1111
  return static_cast<int>(delta);
1116
1112
  }
1117
1113
 
1118
- static void fd_become_readable(grpc_fd* fd, grpc_pollset* notifier) {
1119
- fd->read_closure->SetReady();
1120
-
1121
- /* Note, it is possible that fd_become_readable might be called twice with
1122
- different 'notifier's when an fd becomes readable and it is in two epoll
1123
- sets (This can happen briefly during polling island merges). In such cases
1124
- it does not really matter which notifer is set as the read_notifier_pollset
1125
- (They would both point to the same polling island anyway) */
1126
- /* Use release store to match with acquire load in fd_get_read_notifier */
1127
- gpr_atm_rel_store(&fd->read_notifier_pollset, (gpr_atm)notifier);
1128
- }
1129
-
1130
- static void fd_become_writable(grpc_fd* fd) { fd->write_closure->SetReady(); }
1131
-
1132
- static void fd_has_errors(grpc_fd* fd) { fd->error_closure->SetReady(); }
1133
-
1134
1114
  static void pollset_release_polling_island(grpc_pollset* ps,
1135
1115
  const char* reason) {
1136
1116
  if (ps->po.pi != nullptr) {
@@ -1283,7 +1263,7 @@ static void pollset_work_and_unlock(grpc_pollset* pollset,
1283
1263
  fd_has_errors(fd);
1284
1264
  }
1285
1265
  if (read_ev || cancel || err_fallback) {
1286
- fd_become_readable(fd, pollset);
1266
+ fd_become_readable(fd);
1287
1267
  }
1288
1268
  if (write_ev || cancel || err_fallback) {
1289
1269
  fd_become_writable(fd);
@@ -1667,8 +1647,10 @@ static const grpc_event_engine_vtable vtable = {
1667
1647
  fd_notify_on_read,
1668
1648
  fd_notify_on_write,
1669
1649
  fd_notify_on_error,
1650
+ fd_become_readable,
1651
+ fd_become_writable,
1652
+ fd_has_errors,
1670
1653
  fd_is_shutdown,
1671
- fd_get_read_notifier_pollset,
1672
1654
 
1673
1655
  pollset_init,
1674
1656
  pollset_shutdown,
@@ -60,6 +60,19 @@ typedef struct grpc_fd_watcher {
60
60
  grpc_fd* fd;
61
61
  } grpc_fd_watcher;
62
62
 
63
+ typedef struct grpc_cached_wakeup_fd grpc_cached_wakeup_fd;
64
+
65
+ /* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */
66
+ struct grpc_fork_fd_list {
67
+ /* Only one of fd or cached_wakeup_fd will be set. The unused field will be
68
+ set to nullptr. */
69
+ grpc_fd* fd;
70
+ grpc_cached_wakeup_fd* cached_wakeup_fd;
71
+
72
+ grpc_fork_fd_list* next;
73
+ grpc_fork_fd_list* prev;
74
+ };
75
+
63
76
  struct grpc_fd {
64
77
  int fd;
65
78
  /* refst format:
@@ -109,10 +122,17 @@ struct grpc_fd {
109
122
 
110
123
  grpc_iomgr_object iomgr_object;
111
124
 
112
- /* The pollset that last noticed and notified that the fd is readable */
113
- grpc_pollset* read_notifier_pollset;
125
+ /* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */
126
+ grpc_fork_fd_list* fork_fd_list;
114
127
  };
115
128
 
129
+ /* True when GRPC_ENABLE_FORK_SUPPORT=1. We do not support fork with poll-cv */
130
+ static bool track_fds_for_fork = false;
131
+
132
+ /* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */
133
+ static grpc_fork_fd_list* fork_fd_list_head = nullptr;
134
+ static gpr_mu fork_fd_list_mu;
135
+
116
136
  /* Begin polling on an fd.
117
137
  Registers that the given pollset is interested in this fd - so that if read
118
138
  or writability interest changes, the pollset can be kicked to pick up that
@@ -131,8 +151,7 @@ static uint32_t fd_begin_poll(grpc_fd* fd, grpc_pollset* pollset,
131
151
  MUST NOT be called with a pollset lock taken
132
152
  if got_read or got_write are 1, also does the become_{readable,writable} as
133
153
  appropriate. */
134
- static void fd_end_poll(grpc_fd_watcher* rec, int got_read, int got_write,
135
- grpc_pollset* read_notifier_pollset);
154
+ static void fd_end_poll(grpc_fd_watcher* rec, int got_read, int got_write);
136
155
 
137
156
  /* Return 1 if this fd is orphaned, 0 otherwise */
138
157
  static bool fd_is_orphaned(grpc_fd* fd);
@@ -160,6 +179,9 @@ static void fd_unref(grpc_fd* fd);
160
179
  typedef struct grpc_cached_wakeup_fd {
161
180
  grpc_wakeup_fd fd;
162
181
  struct grpc_cached_wakeup_fd* next;
182
+
183
+ /* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */
184
+ grpc_fork_fd_list* fork_fd_list;
163
185
  } grpc_cached_wakeup_fd;
164
186
 
165
187
  struct grpc_pollset_worker {
@@ -285,9 +307,61 @@ poll_hash_table poll_cache;
285
307
  grpc_cv_fd_table g_cvfds;
286
308
 
287
309
  /*******************************************************************************
288
- * fd_posix.c
310
+ * functions to track opened fds. No-ops unless track_fds_for_fork is true.
289
311
  */
290
312
 
313
+ static void fork_fd_list_remove_node(grpc_fork_fd_list* node) {
314
+ if (track_fds_for_fork) {
315
+ gpr_mu_lock(&fork_fd_list_mu);
316
+ if (fork_fd_list_head == node) {
317
+ fork_fd_list_head = node->next;
318
+ }
319
+ if (node->prev != nullptr) {
320
+ node->prev->next = node->next;
321
+ }
322
+ if (node->next != nullptr) {
323
+ node->next->prev = node->prev;
324
+ }
325
+ gpr_free(node);
326
+ gpr_mu_unlock(&fork_fd_list_mu);
327
+ }
328
+ }
329
+
330
+ static void fork_fd_list_add_node(grpc_fork_fd_list* node) {
331
+ gpr_mu_lock(&fork_fd_list_mu);
332
+ node->next = fork_fd_list_head;
333
+ node->prev = nullptr;
334
+ if (fork_fd_list_head != nullptr) {
335
+ fork_fd_list_head->prev = node;
336
+ }
337
+ fork_fd_list_head = node;
338
+ gpr_mu_unlock(&fork_fd_list_mu);
339
+ }
340
+
341
+ static void fork_fd_list_add_grpc_fd(grpc_fd* fd) {
342
+ if (track_fds_for_fork) {
343
+ fd->fork_fd_list =
344
+ static_cast<grpc_fork_fd_list*>(gpr_malloc(sizeof(grpc_fork_fd_list)));
345
+ fd->fork_fd_list->fd = fd;
346
+ fd->fork_fd_list->cached_wakeup_fd = nullptr;
347
+ fork_fd_list_add_node(fd->fork_fd_list);
348
+ }
349
+ }
350
+
351
+ static void fork_fd_list_add_wakeup_fd(grpc_cached_wakeup_fd* fd) {
352
+ if (track_fds_for_fork) {
353
+ fd->fork_fd_list =
354
+ static_cast<grpc_fork_fd_list*>(gpr_malloc(sizeof(grpc_fork_fd_list)));
355
+ fd->fork_fd_list->cached_wakeup_fd = fd;
356
+ fd->fork_fd_list->fd = nullptr;
357
+ fork_fd_list_add_node(fd->fork_fd_list);
358
+ }
359
+ }
360
+
361
+ /*******************************************************************************
362
+ * fd_posix.c
363
+ */
364
+
291
365
  #ifndef NDEBUG
292
366
  #define REF_BY(fd, n, reason) ref_by(fd, n, reason, __FILE__, __LINE__)
293
367
  #define UNREF_BY(fd, n, reason) unref_by(fd, n, reason, __FILE__, __LINE__)
@@ -323,6 +397,7 @@ static void unref_by(grpc_fd* fd, int n) {
323
397
  if (old == n) {
324
398
  gpr_mu_destroy(&fd->mu);
325
399
  grpc_iomgr_unregister_object(&fd->iomgr_object);
400
+ fork_fd_list_remove_node(fd->fork_fd_list);
326
401
  if (fd->shutdown) GRPC_ERROR_UNREF(fd->shutdown_error);
327
402
  gpr_free(fd);
328
403
  } else {
@@ -346,12 +421,12 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) {
346
421
  r->closed = 0;
347
422
  r->released = 0;
348
423
  gpr_atm_no_barrier_store(&r->pollhup, 0);
349
- r->read_notifier_pollset = nullptr;
350
424
 
351
425
  char* name2;
352
426
  gpr_asprintf(&name2, "%s fd=%d", name, fd);
353
427
  grpc_iomgr_register_object(&r->iomgr_object, name2);
354
428
  gpr_free(name2);
429
+ fork_fd_list_add_grpc_fd(r);
355
430
  return r;
356
431
  }
357
432
 
@@ -359,17 +434,6 @@ static bool fd_is_orphaned(grpc_fd* fd) {
359
434
  return (gpr_atm_acq_load(&fd->refst) & 1) == 0;
360
435
  }
361
436
 
362
- /* Return the read-notifier pollset */
363
- static grpc_pollset* fd_get_read_notifier_pollset(grpc_fd* fd) {
364
- grpc_pollset* notifier = nullptr;
365
-
366
- gpr_mu_lock(&fd->mu);
367
- notifier = fd->read_notifier_pollset;
368
- gpr_mu_unlock(&fd->mu);
369
-
370
- return notifier;
371
- }
372
-
373
437
  static grpc_error* pollset_kick_locked(grpc_fd_watcher* watcher) {
374
438
  gpr_mu_lock(&watcher->pollset->mu);
375
439
  GPR_ASSERT(watcher->worker);
@@ -512,11 +576,6 @@ static int set_ready_locked(grpc_fd* fd, grpc_closure** st) {
512
576
  }
513
577
  }
514
578
 
515
- static void set_read_notifier_pollset_locked(
516
- grpc_fd* fd, grpc_pollset* read_notifier_pollset) {
517
- fd->read_notifier_pollset = read_notifier_pollset;
518
- }
519
-
520
579
  static void fd_shutdown(grpc_fd* fd, grpc_error* why) {
521
580
  gpr_mu_lock(&fd->mu);
522
581
  /* only shutdown once */
@@ -553,8 +612,28 @@ static void fd_notify_on_write(grpc_fd* fd, grpc_closure* closure) {
553
612
  }
554
613
 
555
614
  static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) {
556
- gpr_log(GPR_ERROR, "Polling engine does not support tracking errors.");
557
- abort();
615
+ if (grpc_polling_trace.enabled()) {
616
+ gpr_log(GPR_ERROR, "Polling engine does not support tracking errors.");
617
+ }
618
+ GRPC_CLOSURE_SCHED(closure, GRPC_ERROR_CANCELLED);
619
+ }
620
+
621
+ static void fd_set_readable(grpc_fd* fd) {
622
+ gpr_mu_lock(&fd->mu);
623
+ set_ready_locked(fd, &fd->read_closure);
624
+ gpr_mu_unlock(&fd->mu);
625
+ }
626
+
627
+ static void fd_set_writable(grpc_fd* fd) {
628
+ gpr_mu_lock(&fd->mu);
629
+ set_ready_locked(fd, &fd->write_closure);
630
+ gpr_mu_unlock(&fd->mu);
631
+ }
632
+
633
+ static void fd_set_error(grpc_fd* fd) {
634
+ if (grpc_polling_trace.enabled()) {
635
+ gpr_log(GPR_ERROR, "Polling engine does not support tracking errors.");
636
+ }
558
637
  }
559
638
 
560
639
  static uint32_t fd_begin_poll(grpc_fd* fd, grpc_pollset* pollset,
@@ -608,8 +687,7 @@ static uint32_t fd_begin_poll(grpc_fd* fd, grpc_pollset* pollset,
608
687
  return mask;
609
688
  }
610
689
 
611
- static void fd_end_poll(grpc_fd_watcher* watcher, int got_read, int got_write,
612
- grpc_pollset* read_notifier_pollset) {
690
+ static void fd_end_poll(grpc_fd_watcher* watcher, int got_read, int got_write) {
613
691
  int was_polling = 0;
614
692
  int kick = 0;
615
693
  grpc_fd* fd = watcher->fd;
@@ -645,9 +723,6 @@ static void fd_end_poll(grpc_fd_watcher* watcher, int got_read, int got_write,
645
723
  if (set_ready_locked(fd, &fd->read_closure)) {
646
724
  kick = 1;
647
725
  }
648
- if (read_notifier_pollset != nullptr) {
649
- set_read_notifier_pollset_locked(fd, read_notifier_pollset);
650
- }
651
726
  }
652
727
  if (got_write) {
653
728
  if (set_ready_locked(fd, &fd->write_closure)) {
@@ -827,6 +902,7 @@ static void pollset_destroy(grpc_pollset* pollset) {
827
902
  GPR_ASSERT(!pollset_has_workers(pollset));
828
903
  while (pollset->local_wakeup_cache) {
829
904
  grpc_cached_wakeup_fd* next = pollset->local_wakeup_cache->next;
905
+ fork_fd_list_remove_node(pollset->local_wakeup_cache->fork_fd_list);
830
906
  grpc_wakeup_fd_destroy(&pollset->local_wakeup_cache->fd);
831
907
  gpr_free(pollset->local_wakeup_cache);
832
908
  pollset->local_wakeup_cache = next;
@@ -900,6 +976,7 @@ static grpc_error* pollset_work(grpc_pollset* pollset,
900
976
  worker.wakeup_fd = static_cast<grpc_cached_wakeup_fd*>(
901
977
  gpr_malloc(sizeof(*worker.wakeup_fd)));
902
978
  error = grpc_wakeup_fd_init(&worker.wakeup_fd->fd);
979
+ fork_fd_list_add_wakeup_fd(worker.wakeup_fd);
903
980
  if (error != GRPC_ERROR_NONE) {
904
981
  GRPC_LOG_IF_ERROR("pollset_work", GRPC_ERROR_REF(error));
905
982
  return error;
@@ -997,16 +1074,16 @@ static grpc_error* pollset_work(grpc_pollset* pollset,
997
1074
 
998
1075
  for (i = 1; i < pfd_count; i++) {
999
1076
  if (watchers[i].fd == nullptr) {
1000
- fd_end_poll(&watchers[i], 0, 0, nullptr);
1077
+ fd_end_poll(&watchers[i], 0, 0);
1001
1078
  } else {
1002
1079
  // Wake up all the file descriptors, if we have an invalid one
1003
1080
  // we can identify it on the next pollset_work()
1004
- fd_end_poll(&watchers[i], 1, 1, pollset);
1081
+ fd_end_poll(&watchers[i], 1, 1);
1005
1082
  }
1006
1083
  }
1007
1084
  } else if (r == 0) {
1008
1085
  for (i = 1; i < pfd_count; i++) {
1009
- fd_end_poll(&watchers[i], 0, 0, nullptr);
1086
+ fd_end_poll(&watchers[i], 0, 0);
1010
1087
  }
1011
1088
  } else {
1012
1089
  if (pfds[0].revents & POLLIN_CHECK) {
@@ -1018,7 +1095,7 @@ static grpc_error* pollset_work(grpc_pollset* pollset,
1018
1095
  }
1019
1096
  for (i = 1; i < pfd_count; i++) {
1020
1097
  if (watchers[i].fd == nullptr) {
1021
- fd_end_poll(&watchers[i], 0, 0, nullptr);
1098
+ fd_end_poll(&watchers[i], 0, 0);
1022
1099
  } else {
1023
1100
  if (grpc_polling_trace.enabled()) {
1024
1101
  gpr_log(GPR_INFO, "%p got_event: %d r:%d w:%d [%d]", pollset,
@@ -1032,7 +1109,7 @@ static grpc_error* pollset_work(grpc_pollset* pollset,
1032
1109
  gpr_atm_no_barrier_store(&watchers[i].fd->pollhup, 1);
1033
1110
  }
1034
1111
  fd_end_poll(&watchers[i], pfds[i].revents & POLLIN_CHECK,
1035
- pfds[i].revents & POLLOUT_CHECK, pollset);
1112
+ pfds[i].revents & POLLOUT_CHECK);
1036
1113
  }
1037
1114
  }
1038
1115
  }
@@ -1710,6 +1787,10 @@ static void shutdown_engine(void) {
1710
1787
  if (grpc_cv_wakeup_fds_enabled()) {
1711
1788
  global_cv_fd_table_shutdown();
1712
1789
  }
1790
+ if (track_fds_for_fork) {
1791
+ gpr_mu_destroy(&fork_fd_list_mu);
1792
+ grpc_core::Fork::SetResetChildPollingEngineFunc(nullptr);
1793
+ }
1713
1794
  }
1714
1795
 
1715
1796
  static const grpc_event_engine_vtable vtable = {
@@ -1723,8 +1804,10 @@ static const grpc_event_engine_vtable vtable = {
1723
1804
  fd_notify_on_read,
1724
1805
  fd_notify_on_write,
1725
1806
  fd_notify_on_error,
1807
+ fd_set_readable,
1808
+ fd_set_writable,
1809
+ fd_set_error,
1726
1810
  fd_is_shutdown,
1727
- fd_get_read_notifier_pollset,
1728
1811
 
1729
1812
  pollset_init,
1730
1813
  pollset_shutdown,
@@ -1745,6 +1828,26 @@ static const grpc_event_engine_vtable vtable = {
1745
1828
  shutdown_engine,
1746
1829
  };
1747
1830
 
1831
+ /* Called by the child process's post-fork handler to close open fds, including
1832
+ * worker wakeup fds. This allows gRPC to shutdown in the child process without
1833
+ * interfering with connections or RPCs ongoing in the parent. */
1834
+ static void reset_event_manager_on_fork() {
1835
+ gpr_mu_lock(&fork_fd_list_mu);
1836
+ while (fork_fd_list_head != nullptr) {
1837
+ if (fork_fd_list_head->fd != nullptr) {
1838
+ close(fork_fd_list_head->fd->fd);
1839
+ fork_fd_list_head->fd->fd = -1;
1840
+ } else {
1841
+ close(fork_fd_list_head->cached_wakeup_fd->fd.read_fd);
1842
+ fork_fd_list_head->cached_wakeup_fd->fd.read_fd = -1;
1843
+ close(fork_fd_list_head->cached_wakeup_fd->fd.write_fd);
1844
+ fork_fd_list_head->cached_wakeup_fd->fd.write_fd = -1;
1845
+ }
1846
+ fork_fd_list_head = fork_fd_list_head->next;
1847
+ }
1848
+ gpr_mu_unlock(&fork_fd_list_mu);
1849
+ }
1850
+
1748
1851
  const grpc_event_engine_vtable* grpc_init_poll_posix(bool explicit_request) {
1749
1852
  if (!grpc_has_wakeup_fd()) {
1750
1853
  gpr_log(GPR_ERROR, "Skipping poll because of no wakeup fd.");
@@ -1753,6 +1856,12 @@ const grpc_event_engine_vtable* grpc_init_poll_posix(bool explicit_request) {
1753
1856
  if (!GRPC_LOG_IF_ERROR("pollset_global_init", pollset_global_init())) {
1754
1857
  return nullptr;
1755
1858
  }
1859
+ if (grpc_core::Fork::Enabled()) {
1860
+ track_fds_for_fork = true;
1861
+ gpr_mu_init(&fork_fd_list_mu);
1862
+ grpc_core::Fork::SetResetChildPollingEngineFunc(
1863
+ reset_event_manager_on_fork);
1864
+ }
1756
1865
  return &vtable;
1757
1866
  }
1758
1867