Buy commercial curl support. We
help you work out your issues, debug your libcurl applications, use the API,
port to new platforms, add new features and more. With a team lead by the
curl founder Daniel himself.
Re: transactions stall after March 6 commit to improve wakeup and wait code in multi
- Contemporary messages sorted: [ by date ] [ by thread ] [ by subject ] [ by author ] [ by messages with attachments ]
From: Bryan Henderson via curl-library <curl-library_at_lists.haxx.se>
Date: 16 Jun 2026 14:48:35 +0000
> >> Any chance you can for example modify an existing example source code to
> >> reproduce this behavior? Then we would have a good reproducer to work with!
>
> I'll see what I can do.
This might be easier than I thought to reproduce.
I use an easy handle with no options set whatsoever, not even a URL.
Apparently, this is legal and just means performing the transaction is a
no-op. At least that's what Curl did before that March commit.
But following the commit, if I add that handle to a multi manager,
'curl_multi_fdset' says there is a file descriptor which I have to wait for to
become ready before that transaction can proceed, and that file descriptor
never becomes ready.
I don't know where to find a published example of using curl_multi_fdset to
use as a reproducer, but I made a very simple one that must look a lot like
any such example. Code is below.
When I run this against old libcurl, it prints, "There are no file descriptors
to wait for" and exits. With new libcurl, it prints, "libcurl supplied a file
descriptor [...] waiting now ..." and then hangs.
-------------------------------------------------------------------------------
#include <assert.h>
#include <stdio.h>
#include <sys/select.h>
#include <curl/curl.h>
#include <curl/easy.h>
#include <curl/multi.h>
int
main(int , const char ** ) {
CURLMcode rc;
printf("Hello world.\n");
CURL * const curlSessionP = curl_easy_init();
assert(curlSessionP);
CURLM * const curlMultiP = curl_multi_init();
assert(curlMultiP);
rc = curl_multi_add_handle(curlMultiP, curlSessionP);
assert(rc == CURLM_OK);
fd_set readFdSet, writeFdSet, exceptFdSet;
int maxFd;
rc = curl_multi_fdset(curlMultiP,
&readFdSet, &writeFdSet, &exceptFdSet,
&maxFd);
assert(rc == CURLM_OK);
if (maxFd == -1)
// With libcurl 8.19, this is the case.
fprintf(stderr, "There are no file descriptors to wait for\n");
else {
fprintf(stderr, "libcurl supplied a file descriptor to "
"wait for (maxFd=%u). Waiting now ...\n", maxFd);
pselect(maxFd + 1, &readFdSet, &writeFdSet, &exceptFdSet,
NULL /* timeout */, NULL /* signal mask */);
// Problem: This 'pselect never completes
fprintf(stderr, "A file descriptor is ready.\n");
}
return 0;
}
-------------------------------------------------------------------------------
Date: 16 Jun 2026 14:48:35 +0000
> >> Any chance you can for example modify an existing example source code to
> >> reproduce this behavior? Then we would have a good reproducer to work with!
>
> I'll see what I can do.
This might be easier than I thought to reproduce.
I use an easy handle with no options set whatsoever, not even a URL.
Apparently, this is legal and just means performing the transaction is a
no-op. At least that's what Curl did before that March commit.
But following the commit, if I add that handle to a multi manager,
'curl_multi_fdset' says there is a file descriptor which I have to wait for to
become ready before that transaction can proceed, and that file descriptor
never becomes ready.
I don't know where to find a published example of using curl_multi_fdset to
use as a reproducer, but I made a very simple one that must look a lot like
any such example. Code is below.
When I run this against old libcurl, it prints, "There are no file descriptors
to wait for" and exits. With new libcurl, it prints, "libcurl supplied a file
descriptor [...] waiting now ..." and then hangs.
-------------------------------------------------------------------------------
#include <assert.h>
#include <stdio.h>
#include <sys/select.h>
#include <curl/curl.h>
#include <curl/easy.h>
#include <curl/multi.h>
int
main(int , const char ** ) {
CURLMcode rc;
printf("Hello world.\n");
CURL * const curlSessionP = curl_easy_init();
assert(curlSessionP);
CURLM * const curlMultiP = curl_multi_init();
assert(curlMultiP);
rc = curl_multi_add_handle(curlMultiP, curlSessionP);
assert(rc == CURLM_OK);
fd_set readFdSet, writeFdSet, exceptFdSet;
int maxFd;
rc = curl_multi_fdset(curlMultiP,
&readFdSet, &writeFdSet, &exceptFdSet,
&maxFd);
assert(rc == CURLM_OK);
if (maxFd == -1)
// With libcurl 8.19, this is the case.
fprintf(stderr, "There are no file descriptors to wait for\n");
else {
fprintf(stderr, "libcurl supplied a file descriptor to "
"wait for (maxFd=%u). Waiting now ...\n", maxFd);
pselect(maxFd + 1, &readFdSet, &writeFdSet, &exceptFdSet,
NULL /* timeout */, NULL /* signal mask */);
// Problem: This 'pselect never completes
fprintf(stderr, "A file descriptor is ready.\n");
}
return 0;
}
-------------------------------------------------------------------------------
-- Bryan Henderson Omak, Washington -- Unsubscribe: https://lists.haxx.se/mailman/listinfo/curl-library Etiquette: https://curl.se/mail/etiquette.htmlReceived on 2026-06-16