ezelkow1 commented on code in PR #12998:
URL: https://github.com/apache/trafficserver/pull/12998#discussion_r2962698742


##########
src/iocore/net/SSLConfig.cc:
##########
@@ -49,6 +49,7 @@
 #include <array>
 #include <cstring>
 #include <cmath>
+#include <thread>
 #include <unordered_map>

Review Comment:
   will add



##########
src/iocore/net/SSLUtils.cc:
##########
@@ -1735,10 +1745,69 @@ SSLMultiCertConfigLoader::load(SSLCertLookup *lookup)
   }
 
   swoc::Errata errata(ERRATA_NOTE);
-  int          item_num = 0;
 
-  for (const auto &item : parse_result.value) {
+  int num_threads = params->configLoadConcurrency;
+  if (num_threads == 0 || firstLoad) {
+    num_threads = std::thread::hardware_concurrency();
+  }
+  if (num_threads < 1) {
+    num_threads = 1;
+  }
+  num_threads = std::min(num_threads, 
static_cast<int>(parse_result.value.size()));
+
+  if (num_threads > 1 && parse_result.value.size() > 1) {
+    std::size_t bucket_size = parse_result.value.size() / num_threads;
+    std::size_t remainder   = parse_result.value.size() % num_threads;
+    auto        current     = parse_result.value.cbegin();
+
+    std::vector<std::thread> threads;
+    Note("(%s) loading %zu certs with %d threads", this->_debug_tag(), 
parse_result.value.size(), num_threads);
+
+    for (int t = 0; t < num_threads; ++t) {
+      std::size_t this_bucket = bucket_size + (static_cast<std::size_t>(t) < 
remainder ? 1 : 0);
+      auto        end         = current + this_bucket;
+      threads.emplace_back(&SSLMultiCertConfigLoader::_load_items, this, 
lookup, current, end, std::ref(errata));
+      current = end;
+    }
+
+    for (auto &th : threads) {
+      th.join();
+    }
+
+    Note("(%s) loaded %zu certs in %d threads", this->_debug_tag(), 
parse_result.value.size(), num_threads);
+  } else {
+    _load_items(lookup, parse_result.value.cbegin(), 
parse_result.value.cend(), errata);
+    Note("(%s) loaded %zu certs (single-threaded)", this->_debug_tag(), 
parse_result.value.size());
+  }
+
+  // We *must* have a default context even if it can't possibly work. The 
default context is used to
+  // bootstrap the SSL handshake so that we can subsequently do the SNI lookup 
to switch to the real
+  // context.
+  if (lookup->ssl_default == nullptr) {
+    shared_SSLMultiCertConfigParams sslMultiCertSettings(new 
SSLMultiCertConfigParams);
+    sslMultiCertSettings->addr = ats_strdup("*");
+    if (!this->_store_ssl_ctx(lookup, sslMultiCertSettings)) {
+      errata.note(ERRATA_ERROR, "failed set default context");
+    }
+  }
+
+  return errata;
+}
+
+void
+SSLMultiCertConfigLoader::_load_items(SSLCertLookup *lookup, 
config::SSLMultiCertConfig::const_iterator begin,
+                                      
config::SSLMultiCertConfig::const_iterator end, swoc::Errata &errata)
+{
+  // Each thread needs its own elevated privileges since POSIX capabilities 
are per-thread
+  uint32_t elevate_setting = 0;
+  elevate_setting          = 
RecGetRecordInt("proxy.config.ssl.cert.load_elevated").value_or(0);
+  ElevateAccess elevate_access(elevate_setting ? ElevateAccess::FILE_PRIVILEGE 
: 0);
+
+  int item_num = 0;
+  for (auto it = begin; it != end; ++it) {
     item_num++;
+    const auto &item = *it;

Review Comment:
   will add



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to