public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/curl] rawhide: add multi_wakeup_internal for threaded resolving
@ 2026-08-06 13:55 Jan Macku
  0 siblings, 0 replies; only message in thread
From: Jan Macku @ 2026-08-06 13:55 UTC (permalink / raw)
  To: git-commits

            A new commit has been pushed.

            Repo   : rpms/curl
            Branch : rawhide
            Commit : 2c2712eef598ef945ea87a70cbc1d09fdd62c25e
            Author : Jan Macku <jamacku@redhat.com>
            Date   : 2026-08-06T14:10:42+02:00
            Stats  : +350/-1 in 2 file(s)
            URL    : https://src.fedoraproject.org/rpms/curl/c/2c2712eef598ef945ea87a70cbc1d09fdd62c25e?branch=rawhide

            Log:
            add multi_wakeup_internal for threaded resolving

Resolves: #2509107

---
diff --git a/0001-curl-8.21.0-lib-add-multi_wakeup_internal.patch b/0001-curl-8.21.0-lib-add-multi_wakeup_internal.patch
new file mode 100644
index 0000000..a3fa19f
--- /dev/null
+++ b/0001-curl-8.21.0-lib-add-multi_wakeup_internal.patch
@@ -0,0 +1,343 @@
+From 57811ff4ebbc490dd58c2477f5cc3604eb79368e Mon Sep 17 00:00:00 2001
+From: Stefan Eissing <stefan@eissing.org>
+Date: Wed, 8 Jul 2026 10:34:51 +0200
+Subject: [PATCH] lib: add multi_wakeup_internal
+
+For threaded resolving, added an additional socket/eventfd pair to the
+multi handle for notifications from threads. The original "double use"
+of the standard wakeup pair did lead to regressions for apps.
+
+The API definition of curl_multi_poll/wait/wakeup is pretty tight
+regarding what effects what and adding notifications on top of that
+broke what apps perceived to be the contract.
+
+Fixes #22272
+Reported-by: Sergei Zimmerman
+Closes #22274
+
+(cherry picked from commit 009fd378e8f01c97ebe67a14a41a06d56430f3df)
+---
+ lib/asyn-thrdd.c           |  8 +++---
+ lib/multi.c                | 36 ++++++++++++++++++++++----
+ lib/multihandle.h          | 13 +++++++++-
+ lib/multiif.h              |  4 +++
+ tests/data/Makefile.am     |  2 +-
+ tests/data/test2414        | 30 +++++++++++++++++++++
+ tests/libtest/Makefile.inc |  2 +-
+ tests/libtest/lib2414.c    | 53 ++++++++++++++++++++++++++++++++++++++
+ 8 files changed, 136 insertions(+), 12 deletions(-)
+ create mode 100644 tests/data/test2414
+ create mode 100644 tests/libtest/lib2414.c
+
+diff --git a/lib/asyn-thrdd.c b/lib/asyn-thrdd.c
+index aeadec11a4..90f91ff998 100644
+--- a/lib/asyn-thrdd.c
++++ b/lib/asyn-thrdd.c
+@@ -407,7 +407,7 @@ static void async_thrdd_item_process(void *arg)
+ 
+ #endif /* HAVE_GETADDRINFO */
+ 
+-#ifdef ENABLE_WAKEUP
++#ifdef ENABLE_INTERNAL_WAKEUP
+ static void async_thrdd_event(const struct curl_thrdq *tqueue,
+                               Curl_thrdq_event ev,
+                               void *user_data)
+@@ -416,7 +416,7 @@ static void async_thrdd_event(const struct curl_thrdq *tqueue,
+   (void)tqueue;
+   switch(ev) {
+   case CURL_THRDQ_EV_ITEM_DONE:
+-    (void)curl_multi_wakeup(multi);
++    Curl_multi_wakeup_internal(multi);
+     break;
+   default:
+     break;
+@@ -663,7 +663,7 @@ CURLcode Curl_async_pollset(struct Curl_easy *data,
+ #endif
+ 
+   if(!async->done) {
+-#ifndef ENABLE_WAKEUP
++#ifndef ENABLE_INTERNAL_WAKEUP
+     timediff_t stutter_ms, elapsed_ms;
+     elapsed_ms = curlx_ptimediff_ms(Curl_pgrs_now(data), &async->start);
+     if(elapsed_ms < 3)
+@@ -706,7 +706,7 @@ CURLcode Curl_async_take_result(struct Curl_easy *data,
+   if(thrdd->rr.channel)
+     (void)Curl_ares_perform(thrdd->rr.channel, 0);
+ #endif
+-#ifndef ENABLE_WAKEUP
++#ifndef ENABLE_INTERNAL_WAKEUP
+   Curl_async_thrdd_multi_process(data->multi);
+ #endif
+ 
+diff --git a/lib/multi.c b/lib/multi.c
+index d6ae111d8e..1ae679565e 100644
+--- a/lib/multi.c
++++ b/lib/multi.c
+@@ -268,6 +268,10 @@ struct Curl_multi *Curl_multi_handle(uint32_t xfer_table_size,
+   multi->wakeup_pair[0] = CURL_SOCKET_BAD;
+   multi->wakeup_pair[1] = CURL_SOCKET_BAD;
+ #endif
++#ifdef ENABLE_INTERNAL_WAKEUP
++  multi->wakeup_internal[0] = CURL_SOCKET_BAD;
++  multi->wakeup_internal[1] = CURL_SOCKET_BAD;
++#endif
+ 
+   if(Curl_mntfy_resize(multi) ||
+      Curl_uint32_bset_resize(&multi->process, xfer_table_size) ||
+@@ -315,6 +319,10 @@ struct Curl_multi *Curl_multi_handle(uint32_t xfer_table_size,
+   if(Curl_wakeup_init(multi->wakeup_pair, TRUE) < 0)
+     goto error;
+ #endif
++#ifdef ENABLE_INTERNAL_WAKEUP
++  if(Curl_wakeup_init(multi->wakeup_internal, TRUE) < 0)
++    goto error;
++#endif
+ 
+   if(Curl_probeipv6(multi))
+     goto error;
+@@ -360,6 +368,9 @@ error:
+ #ifdef ENABLE_WAKEUP
+   Curl_wakeup_destroy(multi->wakeup_pair);
+ #endif
++#ifdef ENABLE_INTERNAL_WAKEUP
++  Curl_wakeup_destroy(multi->wakeup_internal);
++#endif
+ 
+   curlx_free(multi);
+   return NULL;
+@@ -395,7 +406,7 @@ bool Curl_is_connecting(struct Curl_easy *data)
+ 
+ static CURLMcode multi_assess_wakeup(struct Curl_multi *multi)
+ {
+-#ifdef ENABLE_WAKEUP
++#ifdef ENABLE_INTERNAL_WAKEUP
+   if(multi->socket_cb)
+     return Curl_multi_ev_assess_xfer(multi, multi->admin);
+ #else
+@@ -1149,14 +1160,14 @@ CURLMcode Curl_multi_pollset(struct Curl_easy *data,
+   CURLcode result = CURLE_OK;
+ 
+   Curl_pollset_reset(ps);
+-#ifdef ENABLE_WAKEUP
++#ifdef ENABLE_INTERNAL_WAKEUP
+   /* The admin handle always listens on the wakeup socket when there
+    * are transfers alive. */
+   if(data->multi && (data == data->multi->admin) &&
+      data->multi->xfers_really_alive) {
+     CURL_TRC_M(data, "adding wakeup, %u xfers really alive",
+                data->multi->xfers_really_alive);
+-    result = Curl_pollset_add_in(data, ps, data->multi->wakeup_pair[0]);
++    result = Curl_pollset_add_in(data, ps, data->multi->wakeup_internal[0]);
+   }
+ #endif
+   /* If the transfer has no connection, this is fine. Happens when
+@@ -1714,6 +1725,18 @@ CURLMcode curl_multi_wakeup(CURLM *m)
+   return mresult;
+ }
+ 
++#ifdef ENABLE_INTERNAL_WAKEUP
++void Curl_multi_wakeup_internal(struct Curl_multi *multi)
++{
++  /* This is expected to be invocable from another thread which
++   * does NOT outlive the multi handle. Check for sanity. */
++  if(GOOD_MULTI_HANDLE(multi))
++    Curl_wakeup_signal(multi->wakeup_internal);
++  else
++    DEBUGASSERT(0);
++}
++#endif
++
+ /*
+  * multi_ischanged() is called
+  *
+@@ -2740,10 +2763,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
+   Curl_uint32_bset_remove(&multi->dirty, data->mid);
+ 
+   if(data == multi->admin) {
+-#ifdef ENABLE_WAKEUP
++#ifdef ENABLE_INTERNAL_WAKEUP
+     /* Consume any pending wakeup signals before processing.
+      * This is necessary for event based processing. See #21547 */
+-    (void)Curl_wakeup_consume(multi->wakeup_pair, TRUE);
++    (void)Curl_wakeup_consume(multi->wakeup_internal, TRUE);
+ #endif
+ #ifdef USE_RESOLV_THREADED
+     Curl_async_thrdd_multi_process(multi);
+@@ -3051,6 +3074,9 @@ CURLMcode curl_multi_cleanup(CURLM *m)
+ #ifdef ENABLE_WAKEUP
+   Curl_wakeup_destroy(multi->wakeup_pair);
+ #endif
++#ifdef ENABLE_INTERNAL_WAKEUP
++  Curl_wakeup_destroy(multi->wakeup_internal);
++#endif
+ 
+     multi_xfer_bufs_free(multi);
+     Curl_mntfy_cleanup(multi);
+diff --git a/lib/multihandle.h b/lib/multihandle.h
+index 19dd2ffcdf..e9bbfaea90 100644
+--- a/lib/multihandle.h
++++ b/lib/multihandle.h
+@@ -73,6 +73,11 @@ typedef enum {
+ #if !defined(CURL_DISABLE_SOCKETPAIR) && !defined(USE_WINSOCK)
+ #define ENABLE_WAKEUP
+ #endif
++#if !defined(CURL_DISABLE_SOCKETPAIR) && \
++    defined(USE_RESOLV_THREADED) && \
++    !defined(USE_WINSOCK)
++#define ENABLE_INTERNAL_WAKEUP
++#endif
+ 
+ /* value for MAXIMUM CONCURRENT STREAMS upper limit */
+ #define INITIAL_MAX_CONCURRENT_STREAMS ((1U << 31) - 1)
+@@ -168,7 +173,13 @@ struct Curl_multi {
+ #ifdef ENABLE_WAKEUP
+   curl_socket_t wakeup_pair[2]; /* eventfd()/pipe()/socketpair() used for
+                                    wakeup 0 is used for read, 1 is used
+-                                   for write */
++                                   for write. Used by curl_multi_wakeup() */
++#endif
++#ifdef ENABLE_INTERNAL_WAKEUP
++  curl_socket_t wakeup_internal[2]; /* eventfd()/pipe()/socketpair() used for
++                                   wakeup 0 is used for read, 1 is used
++                                   for write. Used for internal wakeups,
++                                   e.g. threaded resolver. */
+ #endif
+   unsigned int max_concurrent_streams;
+   unsigned int maxconnects; /* if >0, a fixed limit of the maximum number of
+diff --git a/lib/multiif.h b/lib/multiif.h
+index 039db269e0..920bf0e917 100644
+--- a/lib/multiif.h
++++ b/lib/multiif.h
+@@ -164,4 +164,8 @@ void Curl_multi_clear_dirty(struct Curl_easy *data);
+ 
+ void Curl_multi_set_now(struct Curl_multi *multi);
+ 
++#ifdef ENABLE_INTERNAL_WAKEUP
++void Curl_multi_wakeup_internal(struct Curl_multi *multi);
++#endif
++
+ #endif /* HEADER_CURL_MULTIIF_H */
+diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
+index 9fb1720f7c..69bfdc9134 100644
+--- a/tests/data/Makefile.am
++++ b/tests/data/Makefile.am
+@@ -263,7 +263,7 @@ test2300 test2301 test2302 test2303 test2304 test2306 test2307 test2308 \
+ test2309 test2310 test2311 \
+ \
+ test2400 test2401 test2402 test2403 test2404 test2405 test2406 test2407 \
+-test2408 test2409 test2410 test2411 test2412 test2413 \
++test2408 test2409 test2410 test2411 test2412 test2413 test2414 \
+ \
+ test2500 test2501 test2502 test2503 test2504 test2505 test2506 \
+ \
+diff --git a/tests/data/test2414 b/tests/data/test2414
+new file mode 100644
+index 0000000000..197beffe8f
+--- /dev/null
++++ b/tests/data/test2414
+@@ -0,0 +1,30 @@
++<?xml version="1.0" encoding="US-ASCII"?>
++<testcase>
++<info>
++<keywords>
++multi
++wakeup
++</keywords>
++</info>
++
++# Client-side
++<client>
++<features>
++wakeup
++</features>
++<server>
++</server>
++<tool>
++lib%TESTNUMBER
++</tool>
++<name>
++wakeup, perform and poll needs to exit
++</name>
++<command>
++</command>
++</client>
++
++# Verify data after the test has been "shot"
++<verify>
++</verify>
++</testcase>
+diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc
+index bec648542b..8d97421f4e 100644
+--- a/tests/libtest/Makefile.inc
++++ b/tests/libtest/Makefile.inc
+@@ -115,7 +115,7 @@ TESTS_C = \
+   lib2023.c lib2032.c lib2082.c \
+   lib2301.c lib2302.c lib2304.c           lib2306.c lib2308.c lib2309.c \
+   lib2402.c           lib2404.c lib2405.c \
+-  lib2412.c \
++  lib2412.c           lib2414.c \
+   lib2502.c lib2504.c lib2505.c lib2506.c \
+   lib2700.c \
+   lib3010.c lib3025.c lib3026.c lib3027.c lib3033.c lib3034.c \
+diff --git a/tests/libtest/lib2414.c b/tests/libtest/lib2414.c
+new file mode 100644
+index 0000000000..e04dff3de7
+--- /dev/null
++++ b/tests/libtest/lib2414.c
+@@ -0,0 +1,53 @@
++/***************************************************************************
++ *                                  _   _ ____  _
++ *  Project                     ___| | | |  _ \| |
++ *                             / __| | | | |_) | |
++ *                            | (__| |_| |  _ <| |___
++ *                             \___|\___/|_| \_\_____|
++ *
++ * Copyright (C) Dmitry Karpov <dkarpov1970@gmail.com>
++ *
++ * This software is licensed as described in the file COPYING, which
++ * you should have received as part of this distribution. The terms
++ * are also available at https://curl.se/docs/copyright.html.
++ *
++ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
++ * copies of the Software, and permit persons to whom the Software is
++ * furnished to do so, under the terms of the COPYING file.
++ *
++ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
++ * KIND, either express or implied.
++ *
++ * SPDX-License-Identifier: curl
++ *
++ ***************************************************************************/
++
++#include "first.h"
++#include "testtrace.h"
++
++static CURLcode test_lib2414(const char *URL)
++{
++  CURLM *multi = NULL;
++  CURLcode result = CURLE_OK;
++  int running;
++
++  (void)URL;
++  global_init(CURL_GLOBAL_ALL);
++
++  multi = curl_multi_init();
++  if(!multi) {
++    curl_mfprintf(stderr, "curl_multi_init() failed\n");
++    result = TEST_ERR_MAJOR_BAD;
++    goto test_cleanup;
++  }
++
++  curl_multi_wakeup(multi);
++  curl_multi_perform(multi, &running);
++  curl_multi_poll(multi, NULL, 0, INT_MAX, NULL);
++
++test_cleanup:
++  if(multi)
++    curl_multi_cleanup(multi);
++  curl_global_cleanup();
++  return result;
++}
+-- 
+2.55.0
+

diff --git a/curl.spec b/curl.spec
index 249ef18..f30c790 100644
--- a/curl.spec
+++ b/curl.spec
@@ -13,7 +13,7 @@
 Summary: A utility for getting files from remote servers (FTP, HTTP, and others)
 Name: curl
 Version: 8.21.0
-Release: 4%{?dist}
+Release: 5%{?dist}
 License: curl
 Source0: https://curl.se/download/%{name}-%{version_no_tilde}.tar.xz
 Source1: https://curl.se/download/%{name}-%{version_no_tilde}.tar.xz.asc
@@ -22,6 +22,9 @@ Source1: https://curl.se/download/%{name}-%{version_no_tilde}.tar.xz.asc
 # which points to the GPG key as of April 7th 2016 of https://daniel.haxx.se/mykey.asc
 Source2: mykey.asc
 
+# add multi_wakeup_internal for threaded resolving (#2509107)
+Patch001: 0001-curl-8.21.0-lib-add-multi_wakeup_internal.patch
+
 # patch making libcurl multilib ready
 Patch101: 0101-curl-7.32.0-multilib.patch
 
@@ -474,6 +477,9 @@ rm -f ${RPM_BUILD_ROOT}%{_mandir}/man1/wcurl.1*
 %{_libdir}/libcurl.so.4.[0-9].[0-9].minimal
 
 %changelog
+* Thu Aug 06 2026 Jan Macku <jamacku@redhat.com> - 8.21.0-5
+- add multi_wakeup_internal for threaded resolving (#2509107)
+
 * Tue Jul 21 2026 Owen Zimmerman <owen@fyralabs.com> - 8.21.0-4
 - Enable zstd in full config
 

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-08-06 13:55 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-06 13:55 [rpms/curl] rawhide: add multi_wakeup_internal for threaded resolving Jan Macku

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox