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
@@ -33,6 +33,8 @@ class ThreadState;
33
33
 
34
34
  class Fork {
35
35
  public:
36
+ typedef void (*child_postfork_func)(void);
37
+
36
38
  static void GlobalInit();
37
39
  static void GlobalShutdown();
38
40
 
@@ -46,6 +48,12 @@ class Fork {
46
48
  // Decrement the count of active ExecCtxs
47
49
  static void DecExecCtxCount();
48
50
 
51
+ // Provide a function that will be invoked in the child's postfork handler to
52
+ // reset the polling engine's internal state.
53
+ static void SetResetChildPollingEngineFunc(
54
+ child_postfork_func reset_child_polling_engine);
55
+ static child_postfork_func GetResetChildPollingEngineFunc();
56
+
49
57
  // Check if there is a single active ExecCtx
50
58
  // (the one used to invoke this function). If there are more,
51
59
  // return false. Otherwise, return true and block creation of
@@ -68,10 +76,11 @@ class Fork {
68
76
  static void Enable(bool enable);
69
77
 
70
78
  private:
71
- static internal::ExecCtxState* execCtxState_;
72
- static internal::ThreadState* threadState_;
73
- static bool supportEnabled_;
74
- static bool overrideEnabled_;
79
+ static internal::ExecCtxState* exec_ctx_state_;
80
+ static internal::ThreadState* thread_state_;
81
+ static bool support_enabled_;
82
+ static bool override_enabled_;
83
+ static child_postfork_func reset_child_polling_engine_;
75
84
  };
76
85
 
77
86
  } // namespace grpc_core
@@ -0,0 +1,42 @@
1
+ /*
2
+ *
3
+ * Copyright 2018 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_CORE_LIB_GPRPP_MUTEX_LOCK_H
20
+ #define GRPC_CORE_LIB_GPRPP_MUTEX_LOCK_H
21
+
22
+ #include <grpc/support/port_platform.h>
23
+
24
+ #include <grpc/support/sync.h>
25
+
26
+ namespace grpc_core {
27
+
28
+ class MutexLock {
29
+ public:
30
+ explicit MutexLock(gpr_mu* mu) : mu_(mu) { gpr_mu_lock(mu); }
31
+ ~MutexLock() { gpr_mu_unlock(mu_); }
32
+
33
+ MutexLock(const MutexLock&) = delete;
34
+ MutexLock& operator=(const MutexLock&) = delete;
35
+
36
+ private:
37
+ gpr_mu* const mu_;
38
+ };
39
+
40
+ } // namespace grpc_core
41
+
42
+ #endif /* GRPC_CORE_LIB_GPRPP_MUTEX_LOCK_H */
@@ -86,7 +86,8 @@ class InternallyRefCounted : public Orphanable {
86
86
  GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
87
87
 
88
88
  // Allow RefCountedPtr<> to access Unref() and IncrementRefCount().
89
- friend class RefCountedPtr<Child>;
89
+ template <typename T>
90
+ friend class RefCountedPtr;
90
91
 
91
92
  InternallyRefCounted() { gpr_ref_init(&refs_, 1); }
92
93
  virtual ~InternallyRefCounted() {}
@@ -129,7 +130,8 @@ class InternallyRefCountedWithTracing : public Orphanable {
129
130
  GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
130
131
 
131
132
  // Allow RefCountedPtr<> to access Unref() and IncrementRefCount().
132
- friend class RefCountedPtr<Child>;
133
+ template <typename T>
134
+ friend class RefCountedPtr;
133
135
 
134
136
  InternallyRefCountedWithTracing()
135
137
  : InternallyRefCountedWithTracing(static_cast<TraceFlag*>(nullptr)) {}
@@ -73,7 +73,8 @@ class RefCounted {
73
73
 
74
74
  private:
75
75
  // Allow RefCountedPtr<> to access IncrementRefCount().
76
- friend class RefCountedPtr<Child>;
76
+ template <typename T>
77
+ friend class RefCountedPtr;
77
78
 
78
79
  void IncrementRefCount() { gpr_ref(&refs_); }
79
80
 
@@ -152,7 +153,8 @@ class RefCountedWithTracing {
152
153
 
153
154
  private:
154
155
  // Allow RefCountedPtr<> to access IncrementRefCount().
155
- friend class RefCountedPtr<Child>;
156
+ template <typename T>
157
+ friend class RefCountedPtr;
156
158
 
157
159
  void IncrementRefCount() { gpr_ref(&refs_); }
158
160
 
@@ -36,25 +36,49 @@ class RefCountedPtr {
36
36
  RefCountedPtr(std::nullptr_t) {}
37
37
 
38
38
  // If value is non-null, we take ownership of a ref to it.
39
- explicit RefCountedPtr(T* value) { value_ = value; }
39
+ template <typename Y>
40
+ explicit RefCountedPtr(Y* value) {
41
+ value_ = value;
42
+ }
40
43
 
41
- // Move support.
44
+ // Move ctors.
42
45
  RefCountedPtr(RefCountedPtr&& other) {
43
46
  value_ = other.value_;
44
47
  other.value_ = nullptr;
45
48
  }
49
+ template <typename Y>
50
+ RefCountedPtr(RefCountedPtr<Y>&& other) {
51
+ value_ = other.value_;
52
+ other.value_ = nullptr;
53
+ }
54
+
55
+ // Move assignment.
46
56
  RefCountedPtr& operator=(RefCountedPtr&& other) {
47
57
  if (value_ != nullptr) value_->Unref();
48
58
  value_ = other.value_;
49
59
  other.value_ = nullptr;
50
60
  return *this;
51
61
  }
62
+ template <typename Y>
63
+ RefCountedPtr& operator=(RefCountedPtr<Y>&& other) {
64
+ if (value_ != nullptr) value_->Unref();
65
+ value_ = other.value_;
66
+ other.value_ = nullptr;
67
+ return *this;
68
+ }
52
69
 
53
- // Copy support.
70
+ // Copy ctors.
54
71
  RefCountedPtr(const RefCountedPtr& other) {
55
72
  if (other.value_ != nullptr) other.value_->IncrementRefCount();
56
73
  value_ = other.value_;
57
74
  }
75
+ template <typename Y>
76
+ RefCountedPtr(const RefCountedPtr<Y>& other) {
77
+ if (other.value_ != nullptr) other.value_->IncrementRefCount();
78
+ value_ = other.value_;
79
+ }
80
+
81
+ // Copy assignment.
58
82
  RefCountedPtr& operator=(const RefCountedPtr& other) {
59
83
  // Note: Order of reffing and unreffing is important here in case value_
60
84
  // and other.value_ are the same object.
@@ -63,17 +87,32 @@ class RefCountedPtr {
63
87
  value_ = other.value_;
64
88
  return *this;
65
89
  }
90
+ template <typename Y>
91
+ RefCountedPtr& operator=(const RefCountedPtr<Y>& other) {
92
+ // Note: Order of reffing and unreffing is important here in case value_
93
+ // and other.value_ are the same object.
94
+ if (other.value_ != nullptr) other.value_->IncrementRefCount();
95
+ if (value_ != nullptr) value_->Unref();
96
+ value_ = other.value_;
97
+ return *this;
98
+ }
66
99
 
67
100
  ~RefCountedPtr() {
68
101
  if (value_ != nullptr) value_->Unref();
69
102
  }
70
103
 
71
104
  // If value is non-null, we take ownership of a ref to it.
72
- void reset(T* value = nullptr) {
105
+ template <typename Y>
106
+ void reset(Y* value) {
73
107
  if (value_ != nullptr) value_->Unref();
74
108
  value_ = value;
75
109
  }
76
110
 
111
+ void reset() {
112
+ if (value_ != nullptr) value_->Unref();
113
+ value_ = nullptr;
114
+ }
115
+
77
116
  // TODO(roth): This method exists solely as a transition mechanism to allow
78
117
  // us to pass a ref to idiomatic C code that does not use RefCountedPtr<>.
79
118
  // Once all of our code has been converted to idiomatic C++, this
@@ -89,16 +128,34 @@ class RefCountedPtr {
89
128
  T& operator*() const { return *value_; }
90
129
  T* operator->() const { return value_; }
91
130
 
92
- bool operator==(const RefCountedPtr& other) const {
131
+ template <typename Y>
132
+ bool operator==(const RefCountedPtr<Y>& other) const {
93
133
  return value_ == other.value_;
94
134
  }
95
- bool operator==(const T* other) const { return value_ == other; }
96
- bool operator!=(const RefCountedPtr& other) const {
135
+
136
+ template <typename Y>
137
+ bool operator==(const Y* other) const {
138
+ return value_ == other;
139
+ }
140
+
141
+ bool operator==(std::nullptr_t) const { return value_ == nullptr; }
142
+
143
+ template <typename Y>
144
+ bool operator!=(const RefCountedPtr<Y>& other) const {
97
145
  return value_ != other.value_;
98
146
  }
99
- bool operator!=(const T* other) const { return value_ != other; }
147
+
148
+ template <typename Y>
149
+ bool operator!=(const Y* other) const {
150
+ return value_ != other;
151
+ }
152
+
153
+ bool operator!=(std::nullptr_t) const { return value_ != nullptr; }
100
154
 
101
155
  private:
156
+ template <typename Y>
157
+ friend class RefCountedPtr;
158
+
102
159
  T* value_ = nullptr;
103
160
  };
104
161
 
@@ -107,11 +164,6 @@ inline RefCountedPtr<T> MakeRefCounted(Args&&... args) {
107
164
  return RefCountedPtr<T>(New<T>(std::forward<Args>(args)...));
108
165
  }
109
166
 
110
- template <typename Parent, typename Child, typename... Args>
111
- inline RefCountedPtr<Parent> MakePolymorphicRefCounted(Args&&... args) {
112
- return RefCountedPtr<Parent>(New<Child>(std::forward<Args>(args)...));
113
- }
114
-
115
167
  } // namespace grpc_core
116
168
 
117
169
  #endif /* GRPC_CORE_LIB_GPRPP_REF_COUNTED_PTR_H */
@@ -102,7 +102,10 @@ void grpc_call_combiner_stop(grpc_call_combiner* call_combiner,
102
102
  /// If \a closure is NULL, then no closure will be invoked on
103
103
  /// cancellation; this effectively unregisters the previously set closure.
104
104
  /// However, most filters will not need to explicitly unregister their
105
- /// callbacks, as this is done automatically when the call is destroyed.
105
+ /// callbacks, as this is done automatically when the call is destroyed. Filters
106
+ /// that schedule the cancellation closure on ExecCtx do not need to take a ref
107
+ /// on the call stack to guarantee closure liveness. This is done by explicitly
108
+ /// flushing ExecCtx after the unregistration during call destruction.
106
109
  void grpc_call_combiner_set_notify_on_cancel(grpc_call_combiner* call_combiner,
107
110
  grpc_closure* closure);
108
111
 
@@ -131,6 +131,13 @@ static void epoll_set_shutdown() {
131
131
  * Fd Declarations
132
132
  */
133
133
 
134
+ /* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */
135
+ struct grpc_fork_fd_list {
136
+ grpc_fd* fd;
137
+ grpc_fd* next;
138
+ grpc_fd* prev;
139
+ };
140
+
134
141
  struct grpc_fd {
135
142
  int fd;
136
143
 
@@ -140,11 +147,10 @@ struct grpc_fd {
140
147
 
141
148
  struct grpc_fd* freelist_next;
142
149
 
143
- /* The pollset that last noticed that the fd is readable. The actual type
144
- * stored in this is (grpc_pollset *) */
145
- gpr_atm read_notifier_pollset;
146
-
147
150
  grpc_iomgr_object iomgr_object;
151
+
152
+ /* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */
153
+ grpc_fork_fd_list* fork_fd_list;
148
154
  };
149
155
 
150
156
  static void fd_global_init(void);
@@ -260,6 +266,10 @@ static bool append_error(grpc_error** composite, grpc_error* error,
260
266
  static grpc_fd* fd_freelist = nullptr;
261
267
  static gpr_mu fd_freelist_mu;
262
268
 
269
+ /* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */
270
+ static grpc_fd* fork_fd_list_head = nullptr;
271
+ static gpr_mu fork_fd_list_mu;
272
+
263
273
  static void fd_global_init(void) { gpr_mu_init(&fd_freelist_mu); }
264
274
 
265
275
  static void fd_global_shutdown(void) {
@@ -273,6 +283,38 @@ static void fd_global_shutdown(void) {
273
283
  gpr_mu_destroy(&fd_freelist_mu);
274
284
  }
275
285
 
286
+ static void fork_fd_list_add_grpc_fd(grpc_fd* fd) {
287
+ if (grpc_core::Fork::Enabled()) {
288
+ gpr_mu_lock(&fork_fd_list_mu);
289
+ fd->fork_fd_list =
290
+ static_cast<grpc_fork_fd_list*>(gpr_malloc(sizeof(grpc_fork_fd_list)));
291
+ fd->fork_fd_list->next = fork_fd_list_head;
292
+ fd->fork_fd_list->prev = nullptr;
293
+ if (fork_fd_list_head != nullptr) {
294
+ fork_fd_list_head->fork_fd_list->prev = fd;
295
+ }
296
+ fork_fd_list_head = fd;
297
+ gpr_mu_unlock(&fork_fd_list_mu);
298
+ }
299
+ }
300
+
301
+ static void fork_fd_list_remove_grpc_fd(grpc_fd* fd) {
302
+ if (grpc_core::Fork::Enabled()) {
303
+ gpr_mu_lock(&fork_fd_list_mu);
304
+ if (fork_fd_list_head == fd) {
305
+ fork_fd_list_head = fd->fork_fd_list->next;
306
+ }
307
+ if (fd->fork_fd_list->prev != nullptr) {
308
+ fd->fork_fd_list->prev->fork_fd_list->next = fd->fork_fd_list->next;
309
+ }
310
+ if (fd->fork_fd_list->next != nullptr) {
311
+ fd->fork_fd_list->next->fork_fd_list->prev = fd->fork_fd_list->prev;
312
+ }
313
+ gpr_free(fd->fork_fd_list);
314
+ gpr_mu_unlock(&fork_fd_list_mu);
315
+ }
316
+ }
317
+
276
318
  static grpc_fd* fd_create(int fd, const char* name, bool track_err) {
277
319
  grpc_fd* new_fd = nullptr;
278
320
 
@@ -293,13 +335,13 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) {
293
335
  new_fd->read_closure->InitEvent();
294
336
  new_fd->write_closure->InitEvent();
295
337
  new_fd->error_closure->InitEvent();
296
- gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
297
338
 
298
339
  new_fd->freelist_next = nullptr;
299
340
 
300
341
  char* fd_name;
301
342
  gpr_asprintf(&fd_name, "%s fd=%d", name, fd);
302
343
  grpc_iomgr_register_object(&new_fd->iomgr_object, fd_name);
344
+ fork_fd_list_add_grpc_fd(new_fd);
303
345
  #ifndef NDEBUG
304
346
  if (grpc_trace_fd_refcount.enabled()) {
305
347
  gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, new_fd, fd_name);
@@ -366,6 +408,7 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
366
408
  GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_REF(error));
367
409
 
368
410
  grpc_iomgr_unregister_object(&fd->iomgr_object);
411
+ fork_fd_list_remove_grpc_fd(fd);
369
412
  fd->read_closure->DestroyEvent();
370
413
  fd->write_closure->DestroyEvent();
371
414
  fd->error_closure->DestroyEvent();
@@ -376,11 +419,6 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
376
419
  gpr_mu_unlock(&fd_freelist_mu);
377
420
  }
378
421
 
379
- static grpc_pollset* fd_get_read_notifier_pollset(grpc_fd* fd) {
380
- gpr_atm notifier = gpr_atm_acq_load(&fd->read_notifier_pollset);
381
- return (grpc_pollset*)notifier;
382
- }
383
-
384
422
  static bool fd_is_shutdown(grpc_fd* fd) {
385
423
  return fd->read_closure->IsShutdown();
386
424
  }
@@ -397,11 +435,7 @@ static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) {
397
435
  fd->error_closure->NotifyOn(closure);
398
436
  }
399
437
 
400
- static void fd_become_readable(grpc_fd* fd, grpc_pollset* notifier) {
401
- fd->read_closure->SetReady();
402
- /* Use release store to match with acquire load in fd_get_read_notifier */
403
- gpr_atm_rel_store(&fd->read_notifier_pollset, (gpr_atm)notifier);
404
- }
438
+ static void fd_become_readable(grpc_fd* fd) { fd->read_closure->SetReady(); }
405
439
 
406
440
  static void fd_become_writable(grpc_fd* fd) { fd->write_closure->SetReady(); }
407
441
 
@@ -642,7 +676,7 @@ static grpc_error* process_epoll_events(grpc_pollset* pollset) {
642
676
  }
643
677
 
644
678
  if (read_ev || cancel || err_fallback) {
645
- fd_become_readable(fd, pollset);
679
+ fd_become_readable(fd);
646
680
  }
647
681
 
648
682
  if (write_ev || cancel || err_fallback) {
@@ -1204,6 +1238,10 @@ static void shutdown_engine(void) {
1204
1238
  fd_global_shutdown();
1205
1239
  pollset_global_shutdown();
1206
1240
  epoll_set_shutdown();
1241
+ if (grpc_core::Fork::Enabled()) {
1242
+ gpr_mu_destroy(&fork_fd_list_mu);
1243
+ grpc_core::Fork::SetResetChildPollingEngineFunc(nullptr);
1244
+ }
1207
1245
  }
1208
1246
 
1209
1247
  static const grpc_event_engine_vtable vtable = {
@@ -1217,8 +1255,10 @@ static const grpc_event_engine_vtable vtable = {
1217
1255
  fd_notify_on_read,
1218
1256
  fd_notify_on_write,
1219
1257
  fd_notify_on_error,
1258
+ fd_become_readable,
1259
+ fd_become_writable,
1260
+ fd_has_errors,
1220
1261
  fd_is_shutdown,
1221
- fd_get_read_notifier_pollset,
1222
1262
 
1223
1263
  pollset_init,
1224
1264
  pollset_shutdown,
@@ -1239,6 +1279,21 @@ static const grpc_event_engine_vtable vtable = {
1239
1279
  shutdown_engine,
1240
1280
  };
1241
1281
 
1282
+ /* Called by the child process's post-fork handler to close open fds, including
1283
+ * the global epoll fd. This allows gRPC to shutdown in the child process
1284
+ * without interfering with connections or RPCs ongoing in the parent. */
1285
+ static void reset_event_manager_on_fork() {
1286
+ gpr_mu_lock(&fork_fd_list_mu);
1287
+ while (fork_fd_list_head != nullptr) {
1288
+ close(fork_fd_list_head->fd);
1289
+ fork_fd_list_head->fd = -1;
1290
+ fork_fd_list_head = fork_fd_list_head->fork_fd_list->next;
1291
+ }
1292
+ gpr_mu_unlock(&fork_fd_list_mu);
1293
+ shutdown_engine();
1294
+ grpc_init_epoll1_linux(true);
1295
+ }
1296
+
1242
1297
  /* It is possible that GLIBC has epoll but the underlying kernel doesn't.
1243
1298
  * Create epoll_fd (epoll_set_init() takes care of that) to make sure epoll
1244
1299
  * support is available */
@@ -1260,6 +1315,11 @@ const grpc_event_engine_vtable* grpc_init_epoll1_linux(bool explicit_request) {
1260
1315
  return nullptr;
1261
1316
  }
1262
1317
 
1318
+ if (grpc_core::Fork::Enabled()) {
1319
+ gpr_mu_init(&fork_fd_list_mu);
1320
+ grpc_core::Fork::SetResetChildPollingEngineFunc(
1321
+ reset_event_manager_on_fork);
1322
+ }
1263
1323
  return &vtable;
1264
1324
  }
1265
1325