Commit f089f1fd authored by Dave Watson's avatar Dave Watson Committed by Facebook Github Bot

Move threadlocal_detail::Atfork to its own file

Summary: As title

Reviewed By: yfeldblum

Differential Revision: D6440723

fbshipit-source-id: 3168d7bb616ae0ff3fe42f7584c5a255c4953875
parent df9c2e3e
......@@ -66,6 +66,7 @@ nobase_follyinclude_HEADERS = \
container/Foreach-inl.h \
container/SparseByteSet.h \
ConstexprMath.h \
detail/AtFork.h \
detail/AtomicHashUtils.h \
detail/AtomicUnorderedMapUtils.h \
detail/BitIteratorDetail.h \
......@@ -505,6 +506,7 @@ libfolly_la_SOURCES = \
compression/Compression.cpp \
compression/Zlib.cpp \
concurrency/CacheLocality.cpp \
detail/AtFork.cpp \
detail/Futex.cpp \
detail/IPAddress.cpp \
detail/StaticSingletonManager.cpp \
......
/*
* Copyright 2017-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <folly/detail/AtFork.h>
#include <list>
#include <mutex>
#include <folly/Exception.h>
namespace folly {
namespace detail {
namespace {
struct AtForkTask {
folly::Function<void()> prepare;
folly::Function<void()> parent;
folly::Function<void()> child;
};
class AtForkList {
public:
static AtForkList& instance() {
static auto instance = new AtForkList();
return *instance;
}
static void prepare() noexcept {
instance().tasksLock.lock();
auto& tasks = instance().tasks;
for (auto task = tasks.rbegin(); task != tasks.rend(); ++task) {
task->prepare();
}
}
static void parent() noexcept {
auto& tasks = instance().tasks;
for (auto& task : tasks) {
task.parent();
}
instance().tasksLock.unlock();
}
static void child() noexcept {
auto& tasks = instance().tasks;
for (auto& task : tasks) {
task.child();
}
instance().tasksLock.unlock();
}
std::mutex tasksLock;
std::list<AtForkTask> tasks;
private:
AtForkList() {
#if FOLLY_HAVE_PTHREAD_ATFORK
int ret = pthread_atfork(
&AtForkList::prepare, &AtForkList::parent, &AtForkList::child);
checkPosixError(ret, "pthread_atfork failed");
#elif !__ANDROID__ && !defined(_MSC_VER)
// pthread_atfork is not part of the Android NDK at least as of n9d. If
// something is trying to call native fork() directly at all with Android's
// process management model, this is probably the least of the problems.
//
// But otherwise, this is a problem.
#warning pthread_atfork unavailable
#endif
}
};
} // namespace
void AtFork::init() {
AtForkList::instance();
}
void AtFork::registerHandler(
folly::Function<void()> prepare,
folly::Function<void()> parent,
folly::Function<void()> child) {
std::lock_guard<std::mutex> lg(AtForkList::instance().tasksLock);
AtForkList::instance().tasks.push_back(
{std::move(prepare), std::move(parent), std::move(child)});
}
} // namespace detail
} // namespace folly
/*
* Copyright 2017-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <folly/Function.h>
namespace folly {
namespace detail {
struct AtFork {
static void init();
static void registerHandler(
folly::Function<void()> prepare,
folly::Function<void()> parent,
folly::Function<void()> child);
static void unregisterHandler();
};
} // namespace detail
} // namespace folly
......@@ -247,78 +247,6 @@ void StaticMetaBase::reserve(EntryID* id) {
free(reallocated);
}
namespace {
struct AtForkTask {
folly::Function<void()> prepare;
folly::Function<void()> parent;
folly::Function<void()> child;
};
class AtForkList {
public:
static AtForkList& instance() {
static auto instance = new AtForkList();
return *instance;
}
static void prepare() noexcept {
instance().tasksLock.lock();
auto& tasks = instance().tasks;
for (auto task = tasks.rbegin(); task != tasks.rend(); ++task) {
task->prepare();
}
}
static void parent() noexcept {
auto& tasks = instance().tasks;
for (auto& task : tasks) {
task.parent();
}
instance().tasksLock.unlock();
}
static void child() noexcept {
auto& tasks = instance().tasks;
for (auto& task : tasks) {
task.child();
}
instance().tasksLock.unlock();
}
std::mutex tasksLock;
std::list<AtForkTask> tasks;
private:
AtForkList() {
#if FOLLY_HAVE_PTHREAD_ATFORK
int ret = pthread_atfork(
&AtForkList::prepare, &AtForkList::parent, &AtForkList::child);
checkPosixError(ret, "pthread_atfork failed");
#elif !__ANDROID__ && !defined(_MSC_VER)
// pthread_atfork is not part of the Android NDK at least as of n9d. If
// something is trying to call native fork() directly at all with Android's
// process management model, this is probably the least of the problems.
//
// But otherwise, this is a problem.
#warning pthread_atfork unavailable
#endif
}
};
} // namespace
void StaticMetaBase::initAtFork() {
AtForkList::instance();
}
void StaticMetaBase::registerAtFork(
folly::Function<void()> prepare,
folly::Function<void()> parent,
folly::Function<void()> child) {
std::lock_guard<std::mutex> lg(AtForkList::instance().tasksLock);
AtForkList::instance().tasks.push_back(
{std::move(prepare), std::move(parent), std::move(child)});
}
FOLLY_STATIC_CTOR_PRIORITY_MAX
PthreadKeyUnregister PthreadKeyUnregister::instance_;
......
......@@ -33,6 +33,7 @@
#include <folly/ScopeGuard.h>
#include <folly/SharedMutex.h>
#include <folly/container/Foreach.h>
#include <folly/detail/AtFork.h>
#include <folly/memory/Malloc.h>
#include <folly/portability/PThread.h>
......@@ -292,12 +293,6 @@ struct StaticMetaBase {
ElementWrapper& getElement(EntryID* ent);
static void initAtFork();
static void registerAtFork(
folly::Function<void()> prepare,
folly::Function<void()> parent,
folly::Function<void()> child);
uint32_t nextId_;
std::vector<uint32_t> freeIds_;
std::mutex lock_;
......@@ -321,7 +316,7 @@ struct StaticMeta : StaticMetaBase {
: StaticMetaBase(
&StaticMeta::getThreadEntrySlow,
std::is_same<AccessMode, AccessModeStrict>::value) {
registerAtFork(
detail::AtFork::registerHandler(
/*prepare*/ &StaticMeta::preFork,
/*parent*/ &StaticMeta::onForkParent,
/*child*/ &StaticMeta::onForkChild);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment