static void initialize(CephContext *cct) {
#ifdef WITH_LTTNG
cct->lookup_or_create_singleton_object<TypedSingleton<traits>>(
- traits.library, cct);
+ traits.library, false, cct);
#endif
}
_crypto_aes = CryptoHandler::create(CEPH_CRYPTO_AES);
_crypto_random.reset(new CryptoRandom());
- lookup_or_create_singleton_object<MempoolObs>("mempool_obs", this);
+ lookup_or_create_singleton_object<MempoolObs>("mempool_obs", false, this);
}
CephContext::~CephContext()
return NULL;
}
}
+
+void CephContext::notify_pre_fork()
+{
+ {
+ std::lock_guard<ceph::spinlock> lg(_fork_watchers_lock);
+ for (auto &&t : _fork_watchers) {
+ t->handle_pre_fork();
+ }
+ }
+ {
+ // note: we don't hold a lock here, but we assume we are idle at
+ // fork time, which happens during process init and startup.
+ auto i = associated_objs.begin();
+ while (i != associated_objs.end()) {
+ if (associated_objs_drop_on_fork.count(i->first.first)) {
+ i = associated_objs.erase(i);
+ } else {
+ ++i;
+ }
+ }
+ associated_objs_drop_on_fork.clear();
+ }
+}
+
+void CephContext::notify_post_fork()
+{
+ ceph::spin_unlock(&_fork_watchers_lock);
+ for (auto &&t : _fork_watchers)
+ t->handle_post_fork();
+}
template<typename T, typename... Args>
T& lookup_or_create_singleton_object(std::string_view name,
+ bool drop_on_fork,
Args&&... args) {
static_assert(sizeof(T) <= largest_singleton,
"Please increase largest singleton.");
auto i = associated_objs.find(std::make_pair(name, type));
if (i == associated_objs.cend()) {
+ if (drop_on_fork) {
+ associated_objs_drop_on_fork.insert(std::string(name));
+ }
i = associated_objs.emplace_hint(
i,
std::piecewise_construct,
_fork_watchers.push_back(w);
}
- void notify_pre_fork() {
- std::lock_guard<ceph::spinlock> lg(_fork_watchers_lock);
- for (auto &&t : _fork_watchers)
- t->handle_pre_fork();
- }
-
- void notify_post_fork() {
- ceph::spin_unlock(&_fork_watchers_lock);
- for (auto &&t : _fork_watchers)
- t->handle_post_fork();
- }
+ void notify_pre_fork();
+ void notify_post_fork();
private:
std::map<std::pair<std::string, std::type_index>,
ceph::immobile_any<largest_singleton>,
associated_objs_cmp> associated_objs;
+ std::set<std::string> associated_objs_drop_on_fork;
ceph::spinlock _fork_watchers_lock;
std::vector<ForkWatcher*> _fork_watchers;
ContextWQ **op_work_queue) {
auto thread_pool_singleton =
&cct->lookup_or_create_singleton_object<ThreadPoolSingleton>(
- "librbd::thread_pool", cct);
+ "librbd::thread_pool", false, cct);
*thread_pool = thread_pool_singleton;
*op_work_queue = thread_pool_singleton->op_work_queue;
}
Mutex **timer_lock) {
auto safe_timer_singleton =
&cct->lookup_or_create_singleton_object<SafeTimerSingleton>(
- "librbd::journal::safe_timer", cct);
+ "librbd::journal::safe_timer", false, cct);
*timer = safe_timer_singleton;
*timer_lock = &safe_timer_singleton->lock;
}
return;
}
auto& thread_pool = m_cct->lookup_or_create_singleton_object<
- ThreadPoolSingleton>("librbd::ImageUpdateWatchers::thread_pool", m_cct);
+ ThreadPoolSingleton>("librbd::ImageUpdateWatchers::thread_pool",
+ false, m_cct);
m_work_queue = new ContextWQ("librbd::ImageUpdateWatchers::op_work_queue",
m_cct->_conf->get_val<int64_t>("rbd_op_thread_timeout"),
&thread_pool);
auto thread_pool_singleton =
&cct->lookup_or_create_singleton_object<ThreadPoolSingleton>(
- "librbd::journal::thread_pool", cct);
+ "librbd::journal::thread_pool", false, cct);
m_work_queue = new ContextWQ("librbd::journal::work_queue",
cct->_conf->get_val<int64_t>("rbd_op_thread_timeout"),
thread_pool_singleton);
TaskFinisher(CephContext &cct) : m_cct(cct) {
auto& singleton =
cct.lookup_or_create_singleton_object<TaskFinisherSingleton>(
- "librbd::TaskFinisher::m_safe_timer", &cct);
+ "librbd::TaskFinisher::m_safe_timer", false, &cct);
m_lock = &singleton.m_lock;
m_safe_timer = singleton.m_safe_timer;
m_finisher = singleton.m_finisher;
transport_type = "dpdk";
auto single = &cct->lookup_or_create_singleton_object<StackSingleton>(
- "AsyncMessenger::NetworkStack::" + transport_type, cct);
+ "AsyncMessenger::NetworkStack::" + transport_type, true, cct);
single->ready(transport_type);
stack = single->stack.get();
stack->start();
if (!global_centers) {
global_centers = &cct->lookup_or_create_singleton_object<
EventCenter::AssociatedCenters>(
- "AsyncMessenger::EventCenter::global_center::" + type);
+ "AsyncMessenger::EventCenter::global_center::" + type, true);
assert(global_centers);
global_centers->centers[idx] = this;
if (driver->need_wakeup()) {
{
m_threads =
&(cct->lookup_or_create_singleton_object<Threads<librbd::ImageCtx>>(
- "rbd_mirror::threads", cct));
+ "rbd_mirror::threads", false, cct));
m_service_daemon.reset(new ServiceDaemon<>(m_cct, m_local, m_threads));
}