Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libtorrent for openSUSE:Factory 
checked in at 2025-12-03 14:13:35
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libtorrent (Old)
 and      /work/SRC/openSUSE:Factory/.libtorrent.new.14147 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libtorrent"

Wed Dec  3 14:13:35 2025 rev:26 rq:1320950 version:0.16.5

Changes:
--------
--- /work/SRC/openSUSE:Factory/libtorrent/libtorrent.changes    2025-11-25 
16:58:58.509407230 +0100
+++ /work/SRC/openSUSE:Factory/.libtorrent.new.14147/libtorrent.changes 
2025-12-03 14:15:03.284964974 +0100
@@ -1,0 +2,7 @@
+Wed Dec  3 08:54:32 UTC 2025 - Jan Engelhardt <[email protected]>
+
+- Update to release 0.16.5
+  * Fixes 100% CPU usage bug in *BSD kqueue event handler and UDNS
+    resolver.
+
+-------------------------------------------------------------------

Old:
----
  libtorrent-0.16.4.tar.gz

New:
----
  libtorrent-0.16.5.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libtorrent.spec ++++++
--- /var/tmp/diff_new_pack.AFdaoL/_old  2025-12-03 14:15:05.433055620 +0100
+++ /var/tmp/diff_new_pack.AFdaoL/_new  2025-12-03 14:15:05.453056464 +0100
@@ -16,9 +16,9 @@
 #
 
 
-%define lname  libtorrent34
+%define lname  libtorrent35
 Name:           libtorrent
-Version:        0.16.4
+Version:        0.16.5
 Release:        0
 Summary:        A BitTorrent library written in C++
 License:        SUSE-GPL-2.0+-with-openssl-exception

++++++ _scmsync.obsinfo ++++++
--- /var/tmp/diff_new_pack.AFdaoL/_old  2025-12-03 14:15:05.737068449 +0100
+++ /var/tmp/diff_new_pack.AFdaoL/_new  2025-12-03 14:15:05.773069968 +0100
@@ -1,5 +1,5 @@
-mtime: 1764077112
-commit: d3164130ef3fe344555fa0844bd25687f91b69ccd3b4ad054e3487e4becd159e
+mtime: 1764752201
+commit: 994a38c7ddd491b1ef7906eedf9419b7f1e842e940708f20791fa05da5a20a0d
 url: https://src.opensuse.org/jengelh/libtorrent
 revision: master
 

++++++ build.specials.obscpio ++++++

++++++ build.specials.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.gitignore new/.gitignore
--- old/.gitignore      1970-01-01 01:00:00.000000000 +0100
+++ new/.gitignore      2025-12-03 09:56:51.000000000 +0100
@@ -0,0 +1 @@
+.osc

++++++ libtorrent-0.16.4.tar.gz -> libtorrent-0.16.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libtorrent-0.16.4/configure 
new/libtorrent-0.16.5/configure
--- old/libtorrent-0.16.4/configure     2025-11-25 11:12:27.000000000 +0100
+++ new/libtorrent-0.16.5/configure     2025-12-02 18:15:57.000000000 +0100
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.72 for libtorrent 0.16.4.
+# Generated by GNU Autoconf 2.72 for libtorrent 0.16.5.
 #
 # Report bugs to <[email protected]>.
 #
@@ -614,8 +614,8 @@
 # Identity of this package.
 PACKAGE_NAME='libtorrent'
 PACKAGE_TARNAME='libtorrent'
-PACKAGE_VERSION='0.16.4'
-PACKAGE_STRING='libtorrent 0.16.4'
+PACKAGE_VERSION='0.16.5'
+PACKAGE_STRING='libtorrent 0.16.5'
 PACKAGE_BUGREPORT='[email protected]'
 PACKAGE_URL=''
 
@@ -1416,7 +1416,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-'configure' configures libtorrent 0.16.4 to adapt to many kinds of systems.
+'configure' configures libtorrent 0.16.5 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1487,7 +1487,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of libtorrent 0.16.4:";;
+     short | recursive ) echo "Configuration of libtorrent 0.16.5:";;
    esac
   cat <<\_ACEOF
 
@@ -1649,7 +1649,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-libtorrent configure 0.16.4
+libtorrent configure 0.16.5
 generated by GNU Autoconf 2.72
 
 Copyright (C) 2023 Free Software Foundation, Inc.
@@ -2367,7 +2367,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by libtorrent $as_me 0.16.4, which was
+It was created by libtorrent $as_me 0.16.5, which was
 generated by GNU Autoconf 2.72.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -4060,7 +4060,7 @@
 
 # Define the identity of the package.
  PACKAGE='libtorrent'
- VERSION='0.16.4'
+ VERSION='0.16.5'
 
 
 printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
@@ -13704,13 +13704,13 @@
 
 
 
-printf "%s\n" "#define PEER_NAME \"-lt1004-\"" >>confdefs.h
+printf "%s\n" "#define PEER_NAME \"-lt1005-\"" >>confdefs.h
 
 
-printf "%s\n" "#define PEER_VERSION \"lt\\x10\\x04\"" >>confdefs.h
+printf "%s\n" "#define PEER_VERSION \"lt\\x10\\x05\"" >>confdefs.h
 
 
-LIBTORRENT_CURRENT=34
+LIBTORRENT_CURRENT=35
 LIBTORRENT_REVISION=0
 LIBTORRENT_AGE=0
 
@@ -23877,7 +23877,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by libtorrent $as_me 0.16.4, which was
+This file was extended by libtorrent $as_me 0.16.5, which was
 generated by GNU Autoconf 2.72.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -23945,7 +23945,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-libtorrent config.status 0.16.4
+libtorrent config.status 0.16.5
 configured by $0, generated by GNU Autoconf 2.72,
   with options \\"\$ac_cs_config\\"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libtorrent-0.16.4/configure.ac 
new/libtorrent-0.16.5/configure.ac
--- old/libtorrent-0.16.4/configure.ac  2025-11-25 11:12:15.000000000 +0100
+++ new/libtorrent-0.16.5/configure.ac  2025-12-02 18:15:46.000000000 +0100
@@ -1,4 +1,4 @@
-AC_INIT([[libtorrent]],[[0.16.4]],[[[email protected]]])
+AC_INIT([[libtorrent]],[[0.16.5]],[[[email protected]]])
 
 AC_CONFIG_HEADERS([config.h])
 AC_CONFIG_MACRO_DIRS([scripts])
@@ -6,10 +6,10 @@
 
 LT_INIT([[disable-static]])
 
-AC_DEFINE([[PEER_NAME]], [["-lt1004-"]], [[Identifier that is part of the 
default peer id.]])
-AC_DEFINE([[PEER_VERSION]], [["lt\x10\x04"]], [[4 byte client and version 
identifier for DHT.]])
+AC_DEFINE([[PEER_NAME]], [["-lt1005-"]], [[Identifier that is part of the 
default peer id.]])
+AC_DEFINE([[PEER_VERSION]], [["lt\x10\x05"]], [[4 byte client and version 
identifier for DHT.]])
 
-LIBTORRENT_CURRENT=34
+LIBTORRENT_CURRENT=35
 LIBTORRENT_REVISION=0
 LIBTORRENT_AGE=0
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libtorrent-0.16.4/src/net/udns_resolver.cc 
new/libtorrent-0.16.5/src/net/udns_resolver.cc
--- old/libtorrent-0.16.4/src/net/udns_resolver.cc      2025-11-25 
11:12:15.000000000 +0100
+++ new/libtorrent-0.16.5/src/net/udns_resolver.cc      2025-12-02 
18:15:46.000000000 +0100
@@ -20,6 +20,36 @@
 
 namespace torrent {
 
+struct UdnsQuery {
+  // TODO: We already use deleted.
+  ~UdnsQuery() { parent = nullptr; }
+
+  void*             requester{};
+  std::string       hostname;
+  int               family{};
+
+  UdnsResolver::resolver_callback callback;
+
+  // TODO: Verify canceled and deleted atomicity.
+
+  UdnsResolver*     parent{};
+  bool              canceled{};
+  bool              deleted{};
+  ::dns_query*      a4_query{};
+  ::dns_query*      a6_query{};
+
+  sin_shared_ptr    result_sin;
+  sin6_shared_ptr   result_sin6;
+  int               error_sin{0};
+  int               error_sin6{0};
+};
+
+class UdnsResolverInternal {
+public:
+  static void a4_callback_wrapper(::dns_ctx *ctx, ::dns_rr_a4 *result, void 
*data);
+  static void a6_callback_wrapper(::dns_ctx *ctx, ::dns_rr_a6 *result, void 
*data);
+};
+
 bool UdnsResolver::m_initialized = false;
 
 static int
@@ -98,7 +128,7 @@
 UdnsResolver::resolve(void* requester, const std::string& hostname, int 
family, resolver_callback&& callback) {
   assert(std::this_thread::get_id() == m_thread->thread_id());
 
-  auto query = std::make_unique<Query>();
+  auto query = std::make_unique<UdnsQuery>();
 
   query->requester = requester;
   query->hostname = hostname;
@@ -110,7 +140,7 @@
     return;
 
   if (family == AF_INET || family == AF_UNSPEC) {
-    query->a4_query = ::dns_submit_a4(m_ctx, hostname.c_str(), 0, 
a4_callback_wrapper, query.get());
+    query->a4_query = ::dns_submit_a4(m_ctx, hostname.c_str(), 0, 
UdnsResolverInternal::a4_callback_wrapper, query.get());
 
     if (query->a4_query == nullptr) {
       LT_LOG("malformed A query : requester:%p name:%s", requester, 
hostname.c_str());
@@ -124,17 +154,18 @@
       // query internally so we can call the callback later with a failure 
code.
       query->error_sin = EAI_NONAME;
 
-      process_timeouts();
-
-      auto lock = std::scoped_lock(m_mutex);
-      m_malformed_queries.emplace(requester, std::move(query));
+      {
+        auto lock = std::lock_guard(m_mutex);
+        m_malformed_queries_unsafe.emplace(requester, std::move(query));
+      }
 
+      process_timeouts();
       return;
     }
   }
 
   if (family == AF_INET6 || family == AF_UNSPEC) {
-    query->a6_query = ::dns_submit_a6(m_ctx, hostname.c_str(), 0, 
a6_callback_wrapper, query.get());
+    query->a6_query = ::dns_submit_a6(m_ctx, hostname.c_str(), 0, 
UdnsResolverInternal::a6_callback_wrapper, query.get());
 
     // It should be impossible for dns_submit_a6 to fail if dns_submit_a4
     // succeeded, but just in case, make it a hard failure.
@@ -151,25 +182,28 @@
 
       query->error_sin = EAI_NONAME;
 
-      process_timeouts();
-
-      auto lock = std::scoped_lock(m_mutex);
-      m_malformed_queries.emplace(requester, std::move(query));
+      {
+        auto lock = std::lock_guard(m_mutex);
+        m_malformed_queries_unsafe.emplace(requester, std::move(query));
+      }
 
+      process_timeouts();
       return;
     }
   }
 
   LT_LOG("resolving : requester:%p name:%s family:%d", requester, 
hostname.c_str(), family);
 
-  process_timeouts();
+  {
+    auto lock = std::lock_guard(m_mutex);
+    m_queries_unsafe.emplace(requester, std::move(query));
+  }
 
-  auto lock = std::scoped_lock(m_mutex);
-  m_queries.emplace(requester, std::move(query));
+  process_timeouts();
 }
 
 bool
-UdnsResolver::try_resolve_numeric(std::unique_ptr<Query>& query) {
+UdnsResolver::try_resolve_numeric(std::unique_ptr<UdnsQuery>& query) {
   assert(std::this_thread::get_id() == m_thread->thread_id());
 
   addrinfo hints{};
@@ -204,30 +238,34 @@
   if (query->family != AF_UNSPEC && query->family != result->ai_family)
     throw internal_error("getaddrinfo returned address with unexpected 
family");
 
-  auto requester = query->requester;
-
-  auto lock = std::scoped_lock(m_mutex);
-  auto itr = m_queries.emplace(requester, std::move(query));
+  {
+    auto lock = std::lock_guard(m_mutex);
+    process_final_result_unsafe(std::move(query));
+  }
 
-  process_result(itr);
   return true;
 }
 
 void
 UdnsResolver::cancel(void* requester) {
-  auto lock = std::scoped_lock(m_mutex);
+  auto lock = std::lock_guard(m_mutex);
 
-  auto range = m_queries.equal_range(requester);
-  unsigned int query_count = std::distance(range.first, range.second);
+  auto cancel_fn = [](std::pair<query_map::iterator, query_map::iterator> 
range) {
+      unsigned int count = 0;
 
-  for (auto itr = range.first; itr != range.second; ++itr)
-    itr->second->canceled = true;
+      for (auto itr = range.first; itr != range.second; ++itr) {
+        if (itr->second->canceled)
+          continue;
 
-  range = m_malformed_queries.equal_range(requester);
-  unsigned int malformed_count = std::distance(range.first, range.second);
+        itr->second->canceled = true;
+        ++count;
+      }
+
+      return count;
+    };
 
-  for (auto itr = range.first; itr != range.second; ++itr)
-    itr->second->canceled = true;
+  unsigned int query_count     = 
cancel_fn(m_queries_unsafe.equal_range(requester));
+  unsigned int malformed_count = 
cancel_fn(m_malformed_queries_unsafe.equal_range(requester));
 
   LT_LOG("canceled : requester:%p queries:%d malformed:%d", requester, 
query_count, malformed_count);
 }
@@ -236,8 +274,9 @@
 UdnsResolver::flush() {
   assert(std::this_thread::get_id() == m_thread->thread_id());
 
-  auto lock = std::scoped_lock(m_mutex);
-  auto malformed_queries = std::move(m_malformed_queries);
+  // Keep lock to ensure cancel() calls do not return until after flushing is 
complete.
+  auto lock              = std::lock_guard(m_mutex);
+  auto malformed_queries = std::move(m_malformed_queries_unsafe);
 
   for (auto& query : malformed_queries) {
     if (query.second->canceled)
@@ -266,59 +305,27 @@
 
 void
 UdnsResolver::event_error() {
-  // TODO: Handle error.
-  process_timeouts();
-}
-
-std::unique_ptr<UdnsResolver::Query>
-UdnsResolver::erase_query(query_map::iterator itr) {
-  if (itr == m_queries.end())
-    throw internal_error("UdnsResolver::erase_query called with invalid 
iterator");
-
-  auto query = std::move(itr->second);
-  m_queries.erase(itr);
-
-  query->deleted = true;
-  return query;
+  throw internal_error("UdnsResolver::event_error() called");
 }
 
-
 UdnsResolver::query_map::iterator
-UdnsResolver::find_query(Query* query) {
-  auto range = m_queries.equal_range(query->requester);
+UdnsResolver::find_query_or_fail_unsafe(UdnsQuery* query) {
+  auto range = m_queries_unsafe.equal_range(query->requester);
 
   for (auto itr = range.first; itr != range.second; ++itr) {
     if (itr->second.get() == query)
       return itr;
   }
 
-  return m_queries.end();
-}
-
-UdnsResolver::query_map::iterator
-UdnsResolver::find_malformed_query(Query* query) {
-  auto range = m_malformed_queries.equal_range(query->requester);
-
-  for (auto itr = range.first; itr != range.second; ++itr) {
-    if (itr->second.get() == query)
-      return itr;
-  }
-
-  return m_malformed_queries.end();
+  throw internal_error("UdnsResolver::find_query_or_fail_unsafe() called with 
invalid query");
 }
 
+// Do not call recursively.
 void
 UdnsResolver::process_timeouts() {
   assert(std::this_thread::get_id() == m_thread->thread_id());
 
-  if (m_processing_timeouts)
-    return;
-
-  m_processing_timeouts = true;
   int timeout = ::dns_timeouts(m_ctx, -1, 0);
-  m_processing_timeouts = false;
-
-  // TODO: We shouldn't remove from error events.
 
   if (timeout == -1) {
     this_thread::poll()->remove_read(this);
@@ -342,21 +349,18 @@
 }
 
 void
-UdnsResolver::a4_callback_wrapper(struct ::dns_ctx *ctx, ::dns_rr_a4 *result, 
void *data) {
-  auto query = static_cast<UdnsResolver::Query*>(data);
-  auto lock  = std::scoped_lock(query->parent->m_mutex);
+UdnsResolverInternal::a4_callback_wrapper(::dns_ctx *ctx, ::dns_rr_a4 *result, 
void *data) {
+  auto query = static_cast<UdnsQuery*>(data);
+  auto lock  = std::lock_guard(query->parent->m_mutex);
 
   if (query->deleted) {
     LT_LOG("A records received, but query was deleted : requester:%p name:%s", 
query->requester, query->hostname.c_str());
     throw internal_error("UdnsResolver::a4_callback_wrapper called with 
deleted query");
   }
 
-  auto itr = 
query->parent->find_query(static_cast<UdnsResolver::Query*>(data));
-
-  if (itr == query->parent->m_queries.end())
-    throw internal_error("UdnsResolver::a4_callback_wrapper called with 
invalid query");
+  auto itr = query->parent->find_query_or_fail_unsafe(query);
 
-  // TODO: Verify...
+  // TODO: Do we need to release a4_query?
   query->a4_query = nullptr;
 
   if (result == nullptr || result->dnsa4_nrr == 0) {
@@ -365,33 +369,28 @@
     LT_LOG("no A records received : requester:%p name:%s error:'%s'",
            query->requester, query->hostname.c_str(), 
gai_strerror(query->error_sin));
 
-    process_result(itr);
-    return;
-  }
-
-  query->result_sin = sin_make();
-  query->result_sin->sin_addr = result->dnsa4_addr[0];
+  } else {
+    query->result_sin = sin_make();
+    query->result_sin->sin_addr = result->dnsa4_addr[0];
 
-  LT_LOG("A records received : requester:%p name:%s nrr:%d",
-         query->requester, query->hostname.c_str(), result->dnsa4_nrr);
+    LT_LOG("A records received : requester:%p name:%s nrr:%d",
+           query->requester, query->hostname.c_str(), result->dnsa4_nrr);
+  }
 
-  process_result(itr);
+  UdnsResolver::process_partial_result_unsafe(itr);
 }
 
 void
-UdnsResolver::a6_callback_wrapper(struct ::dns_ctx *ctx, ::dns_rr_a6 *result, 
void *data) {
-  auto query = static_cast<UdnsResolver::Query*>(data);
-  auto lock  = std::scoped_lock(query->parent->m_mutex);
+UdnsResolverInternal::a6_callback_wrapper(::dns_ctx *ctx, ::dns_rr_a6 *result, 
void *data) {
+  auto query = static_cast<UdnsQuery*>(data);
+  auto lock  = std::lock_guard(query->parent->m_mutex);
 
   if (query->deleted) {
     LT_LOG("AAAA records received, but query was deleted : requester:%p 
name:%s", query->requester, query->hostname.c_str());
     throw internal_error("UdnsResolver::a6_callback_wrapper called with 
deleted query");
   }
 
-  auto itr = query->parent->find_query(query);
-
-  if (itr == query->parent->m_queries.end())
-    throw internal_error("UdnsResolver::a6_callback_wrapper called with 
invalid query");
+  auto itr = query->parent->find_query_or_fail_unsafe(query);
 
   query->a6_query = nullptr;
 
@@ -401,30 +400,34 @@
     LT_LOG("no AAAA records received, calling back with error : requester:%p 
name:%s error:'%s'",
            query->requester, query->hostname.c_str(), 
gai_strerror(query->error_sin6));
 
-    process_result(itr);
-    return;
-  }
-
-  query->result_sin6 = sin6_make();
-  query->result_sin6->sin6_addr = result->dnsa6_addr[0];
+  } else {
+    query->result_sin6 = sin6_make();
+    query->result_sin6->sin6_addr = result->dnsa6_addr[0];
 
-  LT_LOG("AAAA records received : requester:%p name:%s nrr:%d",
-         query->requester, query->hostname.c_str(), result->dnsa6_nrr);
+    LT_LOG("AAAA records received : requester:%p name:%s nrr:%d",
+           query->requester, query->hostname.c_str(), result->dnsa6_nrr);
+  }
 
-  process_result(itr);
+  UdnsResolver::process_partial_result_unsafe(itr);
 }
 
 void
-UdnsResolver::process_result(query_map::iterator itr) {
-  itr->second->parent->process_timeouts();
-
+UdnsResolver::process_partial_result_unsafe(query_map::iterator itr) {
   if (itr->second->a4_query != nullptr || itr->second->a6_query != nullptr) {
     LT_LOG("processing results, waiting for other queries : requester:%p 
name:%s", itr->second->requester, itr->second->hostname.c_str());
     return;
   }
 
-  auto query = itr->second->parent->erase_query(itr);
+  auto query = std::move(itr->second);
+
+  query->deleted = true;
+  query->parent->m_queries_unsafe.erase(itr);
 
+  process_final_result_unsafe(std::move(query));
+}
+
+void
+UdnsResolver::process_final_result_unsafe(std::unique_ptr<UdnsQuery>&& query) {
   if (query->canceled) {
     LT_LOG("processing results, canceled : requester:%p name:%s", 
query->requester, query->hostname.c_str());
     return;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libtorrent-0.16.4/src/net/udns_resolver.h 
new/libtorrent-0.16.5/src/net/udns_resolver.h
--- old/libtorrent-0.16.4/src/net/udns_resolver.h       2025-11-25 
11:12:15.000000000 +0100
+++ new/libtorrent-0.16.5/src/net/udns_resolver.h       2025-12-02 
18:15:46.000000000 +0100
@@ -10,35 +10,17 @@
 #include "torrent/utils/scheduler.h"
 
 struct dns_ctx;
-struct dns_query;
-struct dns_rr_a4;
-struct dns_rr_a6;
 
 namespace torrent {
 
+struct UdnsQuery;
+class  UdnsResolverInternal;
+
 class UdnsResolver : public Event {
 public:
   using resolver_callback = std::function<void(sin_shared_ptr, 
sin6_shared_ptr, int)>;
 
-  struct Query {
-    void*             requester{};
-    std::string       hostname;
-    int               family{};
-    resolver_callback callback;
-
-    UdnsResolver*     parent{};
-    bool              canceled{};
-    bool              deleted{};
-    ::dns_query*      a4_query{};
-    ::dns_query*      a6_query{};
-
-    sin_shared_ptr    result_sin;
-    sin6_shared_ptr   result_sin6;
-    int               error_sin{0};
-    int               error_sin6{0};
-  };
-
-  using query_map = std::multimap<void*, std::unique_ptr<Query>>;
+  using query_map = std::multimap<void*, std::unique_ptr<UdnsQuery>>;
 
   UdnsResolver();
   ~UdnsResolver() override;
@@ -63,30 +45,30 @@
   void                event_error() override;
 
 protected:
-  std::unique_ptr<Query> erase_query(query_map::iterator itr);
-  query_map::iterator    find_query(Query* query);
-  query_map::iterator    find_malformed_query(Query* query);
+  friend class UdnsResolverInternal;
+
+  std::unique_ptr<UdnsQuery> erase_query(query_map::iterator itr);
+
+  query_map::iterator        find_query_or_fail_unsafe(UdnsQuery* query);
 
-  bool                try_resolve_numeric(std::unique_ptr<Query>& query);
+  bool                try_resolve_numeric(std::unique_ptr<UdnsQuery>& query);
 
   void                process_canceled();
   void                process_timeouts();
 
-  static void         a4_callback_wrapper(struct ::dns_ctx *ctx, ::dns_rr_a4 
*result, void *data);
-  static void         a6_callback_wrapper(struct ::dns_ctx *ctx, ::dns_rr_a6 
*result, void *data);
-  static void         process_result(query_map::iterator itr);
+  static void         process_partial_result_unsafe(query_map::iterator itr);
+  static void         process_final_result_unsafe(std::unique_ptr<UdnsQuery>&& 
query);
 
   static bool         m_initialized;
 
   utils::Thread*      m_thread{};
   ::dns_ctx*          m_ctx{};
 
-  bool                  m_processing_timeouts{};
   utils::SchedulerEntry m_task_timeout;
 
   std::mutex          m_mutex;
-  query_map           m_queries;
-  query_map           m_malformed_queries;
+  query_map           m_queries_unsafe;
+  query_map           m_malformed_queries_unsafe;
 };
 
 } // namespace torrent
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libtorrent-0.16.4/src/torrent/net/fd.cc 
new/libtorrent-0.16.5/src/torrent/net/fd.cc
--- old/libtorrent-0.16.4/src/torrent/net/fd.cc 2025-11-25 11:12:16.000000000 
+0100
+++ new/libtorrent-0.16.5/src/torrent/net/fd.cc 2025-12-02 18:15:46.000000000 
+0100
@@ -174,6 +174,7 @@
     return -1;
   }
 
+  LT_LOG_FD("fd_accept() succeeded");
   return connection_fd;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libtorrent-0.16.4/src/torrent/net/poll_kqueue.cc 
new/libtorrent-0.16.5/src/torrent/net/poll_kqueue.cc
--- old/libtorrent-0.16.4/src/torrent/net/poll_kqueue.cc        2025-11-25 
11:12:16.000000000 +0100
+++ new/libtorrent-0.16.5/src/torrent/net/poll_kqueue.cc        2025-12-02 
18:15:46.000000000 +0100
@@ -19,6 +19,9 @@
 
 // TODO: Optimize table memory size, and add a reference to Event for direct 
lookup.
 
+#define LT_LOG(log_fmt, ...)                                        \
+  lt_log_print(LOG_CONNECTION_FD, "kqueue: " log_fmt, __VA_ARGS__);
+
 #define LT_LOG_EVENT(log_fmt, ...)                                      \
   lt_log_print(LOG_CONNECTION_FD, "kqueue->%i : %s : " log_fmt, 
event->file_descriptor(), event->type_name(), __VA_ARGS__);
 
@@ -40,6 +43,7 @@
   inline uint32_t     event_mask_any(int fd);
   inline void         set_event_mask(Event* e, uint32_t m);
 
+  void                flush();
   void                modify(torrent::Event* event, unsigned short op, short 
mask);
 
   int                 m_fd;
@@ -93,16 +97,25 @@
 }
 
 void
+PollInternal::flush() {
+  if (m_changed_events == 0)
+    return;
+
+  LT_LOG("flushing events : changed:%u", m_changed_events);
+
+  if (::kevent(m_fd, m_changes.get(), m_changed_events, nullptr, 0, nullptr) 
== -1)
+    throw internal_error("PollInternal::flush() error: " + 
std::string(std::strerror(errno)));
+
+  m_changed_events = 0;
+}
+
+void
 PollInternal::modify(Event* event, unsigned short op, short mask) {
   LT_LOG_EVENT("modify event : op:%hx mask:%hx changed:%u", op, mask, 
m_changed_events);
 
   // Flush the changed filters to the kernel if the buffer is full.
-  if (m_changed_events == m_max_events) {
-    if (::kevent(m_fd, m_changes.get(), m_changed_events, nullptr, 0, nullptr) 
== -1)
-      throw internal_error("PollInternal::modify() error: " + 
std::string(std::strerror(errno)));
-
-    m_changed_events = 0;
-  }
+  if (m_changed_events == m_max_events)
+    flush();
 
   struct kevent* itr = m_changes.get() + (m_changed_events++);
 
@@ -197,7 +210,7 @@
     auto ev_itr = m_internal->m_table.begin() + itr->ident;
 
     if (ev_itr->second == nullptr) {
-      LT_LOG_DEBUG_IDENT("event is null, skipping : flags:%hx filter:%hx", 
itr->flags, itr->filter);
+      LT_LOG_DEBUG_IDENT("event is null, skipping : flags:%hx fflag:%hx 
filter:%hx", itr->flags, itr->fflags, itr->filter);
       continue;
     }
 
@@ -259,21 +272,7 @@
 
   m_internal->m_table[event->file_descriptor()] = 
PollInternal::Table::value_type();
 
-  // No need to touch m_events as we unset the read/write/error flags in 
m_internal->m_events using
-  // remove_read/write/error.
-  auto last_itr = std::remove_if(m_internal->m_changes.get(),
-                                 m_internal->m_changes.get() + 
m_internal->m_changed_events,
-                                 [event](const struct kevent& ke) { return 
ke.udata == event; });
-
-  m_internal->m_changed_events = last_itr - m_internal->m_changes.get();
-
-  // Clear the event list just in case we open a new socket with the
-  // same fd while in the middle of calling Poll::perform.
-  //
-  // Removed.
-  //
-  // Shouldn't be needed as we unset the read/write/error flags in 
m_internal->m_events using
-  // remove_read/write/error.
+  m_internal->flush();
 }
 
 bool
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libtorrent-0.16.4/src/torrent/utils/log.cc 
new/libtorrent-0.16.5/src/torrent/utils/log.cc
--- old/libtorrent-0.16.4/src/torrent/utils/log.cc      2025-11-25 
11:12:16.000000000 +0100
+++ new/libtorrent-0.16.5/src/torrent/utils/log.cc      2025-12-02 
18:15:46.000000000 +0100
@@ -308,6 +308,8 @@
   // Remove from all groups, then modify all outputs.
 }
 
+// TODO: Add lock for file writes.
+
 static void
 log_file_write(const std::shared_ptr<std::ofstream>& outfile, const char* 
data, size_t length, int group) {
   // Add group name, data, etc as flags.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libtorrent-0.16.4/src/tracker/tracker_list.cc 
new/libtorrent-0.16.5/src/tracker/tracker_list.cc
--- old/libtorrent-0.16.4/src/tracker/tracker_list.cc   2025-11-25 
11:12:16.000000000 +0100
+++ new/libtorrent-0.16.5/src/tracker/tracker_list.cc   2025-12-02 
18:15:47.000000000 +0100
@@ -269,7 +269,7 @@
 // TODO: Use proper flags for insert options.
 void
 TrackerList::insert_url(unsigned int group, const std::string& url, bool 
extra_tracker) {
-  TrackerWorker* worker;
+  TrackerWorker* worker{};
 
   int flags = tracker::TrackerState::flag_enabled;
 
@@ -277,6 +277,7 @@
     flags |= tracker::TrackerState::flag_extra_tracker;
 
   TrackerInfo tracker_info;
+
   tracker_info.info_hash = m_info->hash();
   tracker_info.obfuscated_hash = m_info->hash_obfuscated();
   tracker_info.local_id = m_info->local_id();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libtorrent-0.16.4/src/tracker/tracker_list.h 
new/libtorrent-0.16.5/src/tracker/tracker_list.h
--- old/libtorrent-0.16.4/src/tracker/tracker_list.h    2025-11-25 
11:12:16.000000000 +0100
+++ new/libtorrent-0.16.5/src/tracker/tracker_list.h    2025-12-02 
18:15:47.000000000 +0100
@@ -123,7 +123,7 @@
   TrackerList& operator=(const TrackerList&) = delete;
 
   DownloadInfo*       m_info{};
-  int                 m_state;
+  int                 m_state{};
 
   // TODO: Key should be part of download static info.
   uint32_t            m_key{0};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libtorrent-0.16.4/src/tracker/tracker_worker.h 
new/libtorrent-0.16.5/src/tracker/tracker_worker.h
--- old/libtorrent-0.16.4/src/tracker/tracker_worker.h  2025-11-25 
11:12:16.000000000 +0100
+++ new/libtorrent-0.16.5/src/tracker/tracker_worker.h  2025-12-02 
18:15:47.000000000 +0100
@@ -103,7 +103,7 @@
 
   TrackerInfo           m_info;
 
-  tracker::TrackerState m_state;
+  tracker::TrackerState m_state{};
   std::string           m_tracker_id;
   uint32_t              m_group{0};
 };

Reply via email to