From: Dave Watson Date: Fri, 1 Dec 2017 15:09:43 +0000 (-0800) Subject: Move threadlocal_detail::Atfork to its own file X-Git-Tag: v2017.12.04.00~7 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=commitdiff_plain;h=f089f1fde3ef52161c6630e8b0e78004af6161ae Move threadlocal_detail::Atfork to its own file Summary: As title Reviewed By: yfeldblum Differential Revision: D6440723 fbshipit-source-id: 3168d7bb616ae0ff3fe42f7584c5a255c4953875 --- diff --git a/folly/Makefile.am b/folly/Makefile.am index a1c508bc..be999f3c 100644 --- a/folly/Makefile.am +++ b/folly/Makefile.am @@ -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 \ diff --git a/folly/detail/AtFork.cpp b/folly/detail/AtFork.cpp new file mode 100644 index 00000000..e33b5792 --- /dev/null +++ b/folly/detail/AtFork.cpp @@ -0,0 +1,101 @@ +/* + * 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 + +#include +#include + +#include + +namespace folly { + +namespace detail { + +namespace { + +struct AtForkTask { + folly::Function prepare; + folly::Function parent; + folly::Function 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 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 prepare, + folly::Function parent, + folly::Function child) { + std::lock_guard lg(AtForkList::instance().tasksLock); + AtForkList::instance().tasks.push_back( + {std::move(prepare), std::move(parent), std::move(child)}); +} + +} // namespace detail +} // namespace folly diff --git a/folly/detail/AtFork.h b/folly/detail/AtFork.h new file mode 100644 index 00000000..c714dd84 --- /dev/null +++ b/folly/detail/AtFork.h @@ -0,0 +1,34 @@ +/* + * 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 + +namespace folly { + +namespace detail { + +struct AtFork { + static void init(); + static void registerHandler( + folly::Function prepare, + folly::Function parent, + folly::Function child); + static void unregisterHandler(); +}; + +} // namespace detail +} // namespace folly diff --git a/folly/detail/ThreadLocalDetail.cpp b/folly/detail/ThreadLocalDetail.cpp index 4d652451..667aaa98 100644 --- a/folly/detail/ThreadLocalDetail.cpp +++ b/folly/detail/ThreadLocalDetail.cpp @@ -247,78 +247,6 @@ void StaticMetaBase::reserve(EntryID* id) { free(reallocated); } -namespace { - -struct AtForkTask { - folly::Function prepare; - folly::Function parent; - folly::Function 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 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 prepare, - folly::Function parent, - folly::Function child) { - std::lock_guard 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_; diff --git a/folly/detail/ThreadLocalDetail.h b/folly/detail/ThreadLocalDetail.h index 2f6f10e8..ecf4e67d 100644 --- a/folly/detail/ThreadLocalDetail.h +++ b/folly/detail/ThreadLocalDetail.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -292,12 +293,6 @@ struct StaticMetaBase { ElementWrapper& getElement(EntryID* ent); - static void initAtFork(); - static void registerAtFork( - folly::Function prepare, - folly::Function parent, - folly::Function child); - uint32_t nextId_; std::vector freeIds_; std::mutex lock_; @@ -321,7 +316,7 @@ struct StaticMeta : StaticMetaBase { : StaticMetaBase( &StaticMeta::getThreadEntrySlow, std::is_same::value) { - registerAtFork( + detail::AtFork::registerHandler( /*prepare*/ &StaticMeta::preFork, /*parent*/ &StaticMeta::onForkParent, /*child*/ &StaticMeta::onForkChild);