]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rgw: refact by encapsulating io_context_pool to enforce lazy initialization
authorswjtu-zhanglei <1091517373@qq.com>
Mon, 22 Dec 2025 14:52:58 +0000 (14:52 +0000)
committerswjtu-zhanglei <1091517373@qq.com>
Tue, 23 Dec 2025 05:07:20 +0000 (05:07 +0000)
Introduce a private nested IOContextPoolHolder class in AppMain to
wrap the std::optional<io_context_pool>. This ensures that all access
to the pool—both inside and outside the class—must go through a
getter that guarantees initialization, preventing accidental direct
use of the uninitialized optional.

This eliminates the risk of undefined behavior from dereferencing an
empty optional and enforces a single, safe access pattern.

Signed-off-by: swjtu-zhanglei <1091517373@qq.com>
src/rgw/rgw_appmain.cc
src/rgw/rgw_main.h

index 66f21fec27218ebaaa811e2be521f46a13356b7b..72c216565e31864612d165509f0122e154b1e42b 100644 (file)
@@ -92,9 +92,7 @@ namespace {
 
 OpsLogFile* rgw::AppMain::ops_log_file;
 
-rgw::AppMain::AppMain(const DoutPrefixProvider* dpp) : dpp(dpp)
-{
-}
+rgw::AppMain::AppMain(const DoutPrefixProvider* dpp) : dpp(dpp), context_pool_holder(dpp) {}
 rgw::AppMain::~AppMain() = default;
 
 void rgw::AppMain::init_frontends1(bool nfs) 
@@ -200,17 +198,6 @@ void rgw::AppMain::init_numa()
   }
 } /* init_numa */
 
-void rgw::AppMain::need_context_pool() {
-  if (!context_pool) {
-    context_pool.emplace(
-      dpp->get_cct()->_conf->rgw_thread_pool_size,
-      [] {
-       // request warnings on synchronous librados calls in this thread
-       is_asio_thread = true;
-      });
-  }
-}
-
 int rgw::AppMain::init_storage()
 {
   auto config_store_type = g_conf().get_val<std::string>("rgw_config_store");
@@ -246,21 +233,20 @@ int rgw::AppMain::init_storage()
     (g_conf()->rgw_run_sync_thread &&
       ((!nfs) || (nfs && g_conf()->rgw_nfs_run_sync_thread)));
 
-  need_context_pool();
   DriverManager::Config cfg = DriverManager::get_config(false, g_ceph_context);
   env.driver = DriverManager::get_storage(dpp, dpp->get_cct(),
           cfg,
-         *context_pool,
-         site,
+          context_pool_holder.get(),
+          site,
           run_gc,
           run_lc,
-         run_restore,
+          run_restore,
           run_quota,
           run_sync,
           g_conf().get_val<bool>("rgw_dynamic_resharding"),
-         true, // run notification thread
-         true, // run bucket-logging thread
-         true, null_yield, env.cfgstore,
+          true, // run notification thread
+          true, // run bucket-logging thread
+          true, null_yield, env.cfgstore,
           g_conf()->rgw_cache_enabled);
   if (!env.driver) {
     return -EIO;
@@ -479,8 +465,7 @@ int rgw::AppMain::init_frontends2(RGWLib* rgwlib)
       fe = new RGWLoadGenFrontend(env, config);
     }
     else if (framework == "beast") {
-      need_context_pool();
-      fe = new RGWAsioFrontend(env, config, *sched_ctx, *context_pool);
+      fe = new RGWAsioFrontend(env, config, *sched_ctx, context_pool_holder.get());
     }
     else if (framework == "rgw-nfs") {
       fe = new RGWLibFrontend(env, config);
@@ -549,9 +534,8 @@ int rgw::AppMain::init_frontends2(RGWLib* rgwlib)
     if (dedup_background) {
       rgw_pauser->add_pauser(dedup_background.get());
     }
-      need_context_pool();
       reloader = std::make_unique<RGWRealmReloader>(
-          env, *implicit_tenant_context, service_map_meta, rgw_pauser.get(), *context_pool);
+          env, *implicit_tenant_context, service_map_meta, rgw_pauser.get(), context_pool_holder.get());
       realm_watcher->add_watcher(RGWRealmNotify::Reload, *reloader);
     }
   }
@@ -657,7 +641,7 @@ void rgw::AppMain::shutdown(std::function<void(void)> finalize_async_signals)
   env.driver->shutdown();
   // Do this before closing storage so requests don't try to call into
   // closed storage.
-  context_pool->finish();
+  context_pool_holder.get().finish();
 
   cfgstore.reset(); // deletes
   DriverManager::close_storage(env.driver);
@@ -684,3 +668,12 @@ void rgw::AppMain::shutdown(std::function<void(void)> finalize_async_signals)
   rgw_perf_stop(g_ceph_context);
   ratelimiter.reset(); // deletes--ensure this happens before we destruct
 } /* AppMain::shutdown */
+
+ceph::async::io_context_pool& rgw::AppMain::IOContextPoolHolder::get() {
+  if (!pool_) {
+    pool_.emplace(
+        dpp_->get_cct()->_conf->rgw_thread_pool_size,
+        [] { is_asio_thread = true; });
+  }
+  return *pool_;
+}
index ae151711d57ca35773abdaacfd92cf49901a498b..95eb92509b1664813de74868e137a7eb3ac51fa2 100644 (file)
@@ -94,8 +94,21 @@ class AppMain {
   SiteConfig site;
   const DoutPrefixProvider* dpp;
   RGWProcessEnv env;
-  void need_context_pool();
-  std::optional<ceph::async::io_context_pool> context_pool;
+
+  class IOContextPoolHolder {
+  private:
+    std::optional<ceph::async::io_context_pool> pool_;
+    const DoutPrefixProvider* dpp_;
+
+  public:
+    explicit IOContextPoolHolder(const DoutPrefixProvider* dpp) : dpp_(dpp) {};
+    IOContextPoolHolder(const IOContextPoolHolder&) = delete;
+    IOContextPoolHolder& operator=(const IOContextPoolHolder&) = delete;
+
+    ceph::async::io_context_pool& get();
+  };
+
+  IOContextPoolHolder context_pool_holder;
 public:
   AppMain(const DoutPrefixProvider* dpp);
   ~AppMain();