proxygen
AtFork.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <folly/detail/AtFork.h>
18 
19 #include <list>
20 #include <mutex>
21 
22 #include <folly/lang/Exception.h>
24 
25 namespace folly {
26 
27 namespace detail {
28 
29 namespace {
30 
31 struct AtForkTask {
32  void* object;
36 };
37 
38 class AtForkList {
39  public:
40  static AtForkList& instance() {
41  static auto instance = new AtForkList();
42  return *instance;
43  }
44 
45  static void prepare() noexcept {
46  instance().tasksLock.lock();
47  while (true) {
48  auto& tasks = instance().tasks;
49  auto task = tasks.rbegin();
50  for (; task != tasks.rend(); ++task) {
51  if (!task->prepare()) {
52  break;
53  }
54  }
55  if (task == tasks.rend()) {
56  return;
57  }
58  for (auto untask = tasks.rbegin(); untask != task; ++untask) {
59  untask->parent();
60  }
61  }
62  }
63 
64  static void parent() noexcept {
65  auto& tasks = instance().tasks;
66  for (auto& task : tasks) {
67  task.parent();
68  }
69  instance().tasksLock.unlock();
70  }
71 
72  static void child() noexcept {
73  auto& tasks = instance().tasks;
74  for (auto& task : tasks) {
75  task.child();
76  }
77  instance().tasksLock.unlock();
78  }
79 
81  std::list<AtForkTask> tasks;
82 
83  private:
84  AtForkList() {
85 #if FOLLY_HAVE_PTHREAD_ATFORK
86  int ret = pthread_atfork(
88  if (ret != 0) {
89  throw_exception<std::system_error>(
90  ret, std::generic_category(), "pthread_atfork failed");
91  }
92 #elif !__ANDROID__ && !defined(_MSC_VER)
93 // pthread_atfork is not part of the Android NDK at least as of n9d. If
94 // something is trying to call native fork() directly at all with Android's
95 // process management model, this is probably the least of the problems.
96 //
97 // But otherwise, this is a problem.
98 #warning pthread_atfork unavailable
99 #endif
100  }
101 };
102 } // namespace
103 
104 void AtFork::init() {
105  AtForkList::instance();
106 }
107 
109  void* object,
110  folly::Function<bool()> prepare,
111  folly::Function<void()> parent,
112  folly::Function<void()> child) {
113  std::lock_guard<std::mutex> lg(AtForkList::instance().tasksLock);
114  AtForkList::instance().tasks.push_back(
116 }
117 
118 void AtFork::unregisterHandler(void* object) {
119  auto& list = AtForkList::instance();
120  std::lock_guard<std::mutex> lg(list.tasksLock);
121  for (auto it = list.tasks.begin(); it != list.tasks.end(); ++it) {
122  if (it->object == object) {
123  list.tasks.erase(it);
124  return;
125  }
126  }
127 }
128 
129 } // namespace detail
130 } // namespace folly
void * object
Definition: AtFork.cpp:32
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::list< AtForkTask > tasks
Definition: AtFork.cpp:81
static void init()
Definition: AtFork.cpp:104
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
requires E e noexcept(noexcept(s.error(std::move(e))))
std::mutex tasksLock
Definition: AtFork.cpp:80
Encoder::MutableCompressedList list
std::mutex mutex
folly::Function< bool()> prepare
Definition: AtFork.cpp:33
folly::Function< void()> child
Definition: AtFork.cpp:35
static void unregisterHandler(void *object)
Definition: AtFork.cpp:118
static void registerHandler(void *object, folly::Function< bool()> prepare, folly::Function< void()> parent, folly::Function< void()> child)
Definition: AtFork.cpp:108
folly::Function< void()> parent
Definition: AtFork.cpp:34