curl_multi_perform(3)
π curl_multi_perform β the "go do the thing, but don't you dare block" function
okay bestie, so this page lives in the Library Functions Manual, and it's literally about curl_multi_perform, which is the girl that actually does the work. let me explain π«Ά
β¨ NAME β¨
curl_multi_perform β run all transfers until it would block πββοΈπ¨
π SYNOPSIS π
#include <curl/curl.h>
CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles);
πΈ DESCRIPTION πΈ
so here's the vibe: this function performs transfers on all the handles you've added that need attention, and it does it in a non-blocking fashion. no sitting around waiting, no blocking your whole program, none of that. those easy handles? you already added them to the multi handle earlier with curl_multi_add_handle(3). if you didn't, girl, what are you doing π
When your application has figured out that there's data available for the multi_handle, or a timeout has elapsed, that's your cue β call this function to read/write whatever there is to read or write right now, etc. etc. and curl_multi_perform(3) returns as soon as the reads/writes are done. she's fast, she's efficient, she doesn't linger π
and here's the iconic part: this function does not require that there actually is any data available for reading, or that data can be written. you can call it just in case. no cap. it also stores the number of handles that are still transferring data in the second argument's integer-pointer.
If the amount of running_handles changed from the previous call (or is less than the amount of easy handles you've added to the multi handle), you know there's one or more transfers less "running". π‘ then you can call curl_multi_info_read(3) to get info about each individual completed transfer, and that returned info includes CURLcode and more. and heads up π«Ά β if an added handle fails quickly, it may never be counted as a running_handle at all. in that case you could use curl_multi_info_read(3) to track the actual status of the added handles.
When running_handles is set to zero (0) on the return of this function, there is no longer any transfers in progress. done. finished. periodt. β¨
β οΈ okay this part is serious, listen to me: when this function returns error, the state of all transfers are uncertain and they cannot be continued. do not call curl_multi_perform(3) again on the same multi handle after an error has been returned β unless you first remove all the handles and add new ones. that's the rule, bestie π
π¦ PROTOCOLS π¦
This functionality affects all supported protocols π β yes, all of them, she's versatile.
β EXAMPLE β
int main(void)
{
int still_running;
CURLM *multi = curl_multi_init();
CURL *curl = curl_easy_init();
if(curl) {
curl_multi_add_handle(multi, curl);
do {
CURLMcode mresult = curl_multi_perform(multi, &still_running);
if(!mresult && still_running)
/* wait for activity, timeout or "nothing" */
mresult = curl_multi_poll(multi, NULL, 0, 1000, NULL);
if(mresult) {
fprintf(stderr, "curl_multi_poll() failed, code %d.\n", (int)mresult);
break;
}
} while(still_running); /* if there are still transfers, loop */
}
}
π AVAILABILITY π
Added in curl 7.9.6 β a vintage icon, honestly π
π₯ RETURN VALUE π₯
This function returns a CURLMcode indicating success or error.
CURLM_OK (0) means everything was OK π β non-zero means an error occurred, see libcurl-errors(3).
and ngl, this one's important: this function returns errors regarding the whole multi stack. problems on individual transfers may have occurred even when this function returns CURLM_OK. so use curl_multi_info_read(3) to figure out how individual transfers did, okay? don't blame the group chat for one person's drama π
π TYPICAL USAGE π
Most applications use curl_multi_poll(3) to make libcurl wait for activity on any of the ongoing transfers. and as soon as one or more file descriptor has activity, or the function times out, the application calls curl_multi_perform(3). that's the whole loop, that's the cycle, that's the main character energy right there π
β¨
π SEE ALSO π
curl_multi_add_handle(3)curl_multi_cleanup(3)curl_multi_fdset(3)curl_multi_info_read(3)curl_multi_init(3)curl_multi_wait(3)libcurl-errors(3)
mwah π that's the page! brought to you by libcurl, dated 2026-10-12 β go forth and perform, bestie π§ββοΈβ
π¦ where this page comes from
- fedora 44: libcurl-devel 8.18.0-14.fc44 Β· curl
- fedora 44: libcurl-devel 8.18.0-14.fc44 Β· curl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms