• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #ifndef GRPC_SRC_CORE_LIB_EVENT_ENGINE_FORKABLE_H
15 #define GRPC_SRC_CORE_LIB_EVENT_ENGINE_FORKABLE_H
16 
17 #include <grpc/support/port_platform.h>
18 
19 #include <memory>
20 #include <vector>
21 
22 #include <grpc/support/log.h>
23 
24 #include "src/core/lib/debug/trace.h"
25 
26 namespace grpc_event_engine {
27 namespace experimental {
28 
29 extern grpc_core::TraceFlag grpc_trace_fork;
30 
31 #define GRPC_FORK_TRACE_LOG(format, ...)                 \
32   do {                                                   \
33     if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_fork)) {      \
34       gpr_log(GPR_DEBUG, "[fork] " format, __VA_ARGS__); \
35     }                                                    \
36   } while (0)
37 
38 #define GRPC_FORK_TRACE_LOG_STRING(format) GRPC_FORK_TRACE_LOG("%s", format)
39 
40 // An interface to be implemented by EventEngines that wish to have managed fork
41 // support. The child class must guarantee that those methods are thread-safe.
42 class Forkable {
43  public:
44   virtual ~Forkable() = default;
45   virtual void PrepareFork() = 0;
46   virtual void PostforkParent() = 0;
47   virtual void PostforkChild() = 0;
48 };
49 
50 // ObjectGroupForkHandler is meant to be used as a static object in each
51 // translation unit where Forkables are created and registered with the
52 // ObjectGroupForkHandler. It essentially provides storage for Forkables'
53 // instances (as a vector of weak pointers) and helper methods that are meant to
54 // be invoked inside the fork handlers (see pthread_atfork(3)). The idea is to
55 // have different Forkables (e.g. PosixEventPoller) to store their instances
56 // (e.g. a PosixEventPoller object) in a single place separated from other
57 // Forkables (a sharded approach). Forkables need to register their pthread fork
58 // handlers and manage the relative ordering themselves. This object is
59 // thread-unsafe.
60 class ObjectGroupForkHandler {
61  public:
62   // Registers a Forkable with this ObjectGroupForkHandler, the Forkable must be
63   // created as a shared pointer.
64   void RegisterForkable(std::shared_ptr<Forkable> forkable,
65                         GRPC_UNUSED void (*prepare)(void),
66                         GRPC_UNUSED void (*parent)(void),
67                         GRPC_UNUSED void (*child)(void));
68 
69   void Prefork();
70   void PostforkParent();
71   void PostforkChild();
72 
73  private:
74   GRPC_UNUSED bool registered_ = false;
75   bool is_forking_ = false;
76   std::vector<std::weak_ptr<Forkable> > forkables_;
77 };
78 
79 }  // namespace experimental
80 }  // namespace grpc_event_engine
81 
82 #endif  // GRPC_SRC_CORE_LIB_EVENT_ENGINE_FORKABLE_H
83