gnurl_multi_wait(3)

πŸ“¦ version 7.72.0, in nixos 26.05, nixpkgs unstable

πŸ’… gnurl_multi_wait(3) β€” like, the whole libgnurl manual vibe ✨

okay bestie, buckle up πŸŽ€ this is the page for gnurl_multi_wait(3) out of the libgnurl Manual, and it's genuinely one of those functions that looks scary and is actually just "wait for something to happen, but politely." let's go πŸ’–


✨ NAME ✨

curl_multi_wait β€” polls on all the easy handles chillin' inside a multi handle 🫢

(the name says curl_multi_wait but the page is filed under gnurl_multi_wait, iykyk, that's just how it's labeled here πŸ’€)


🌸 SYNOPSIS 🌸

#include <gnurl/curl.h>

CURLMcode curl_multi_wait(CURLM *multi_handle,
                          struct curl_waitfd extra_fds[],
                          unsigned int extra_nfds,
                          int timeout_ms,
                          int *numfds);

look at that signature. five args. main character energy fr fr πŸ‘‘


πŸ¦‹ DESCRIPTION πŸ¦‹

so curl_multi_wait(3) polls all the file descriptors that the curl easy handles inside your given multi handle set are using. it literally just sits there and waits πŸ’…

it will block until either:

  • activity is detected on at least one of the handles, or
  • timeout_ms has passed 😴

okay but here's the cute part β€” if the multi handle has a pending internal timeout that expires sooner than timeout_ms, then that shorter time gets used instead, so timeout accuracy is reasonably kept. she's considerate like that πŸŽ€

your calling application is totally allowed to pass extra curl_waitfd structures β€” they're basically poll(2)'s pollfd structure's cousin β€” so they get waited on in the same call 🫢

on completion, if numfds is non-NULL, it gets populated with the total number of file descriptors on which interesting events occurred. and that number can include both libcurl internal descriptors and the ones you provided in extra_fds. equal opportunity counting ✨

⚠️ heads up: if no extra file descriptors are provided and libcurl has no file descriptor to offer to wait for, this function will return immediately. no waiting, no blocking, just ✨gone✨. (try curl_multi_poll(3) instead if you'd rather avoid this behavior πŸ™ˆ)

and yes β€” this function is encouraged to be used instead of select(3) when you're using the multi interface. why? because it lets applications more easily circumvent that classic common problem with 1024 maximum file descriptors. we love a function that solves a real problem πŸ’œ


🌈 curl_waitfd 🌈

the little struct herself:

struct curl_waitfd {
  curl_socket_t fd;
  short events;
  short revents;
};

adorable. iconic. three fields. no notes πŸŽ€

now the bit flags that go in events:

  • CURL_WAIT_POLLIN β€” bit flag for curl_waitfd.events saying the socket should poll on read events, like new data received πŸ“₯
  • CURL_WAIT_POLLPRI β€” bit flag for curl_waitfd.events saying the socket should poll on high priority read events, like out of band data πŸ”₯
  • CURL_WAIT_POLLOUT β€” bit flag for curl_waitfd.events saying the socket should poll on write events, like the socket being clear to write without blocking πŸ“€

πŸ”₯ EXAMPLE πŸ”₯

here's the whole example, copied exactly because you know I don't play with your code blocks πŸ’–:

CURL *easy_handle;
CURLM *multi_handle;

/* add the individual easy handle */
curl_multi_add_handle(multi_handle, easy_handle);

do {
  CURLMcode mc;
  int numfds;

  mc = curl_multi_perform(multi_handle, &still_running);

  if(mc == CURLM_OK ) {
    /* wait for activity, timeout or "nothing" */
    mc = curl_multi_wait(multi_handle, NULL, 0, 1000, &numfds);
  }

  if(mc != CURLM_OK) {
    fprintf(stderr, "curl_multi failed, code %d.\n", mc);
    break;
  }

  /* 'numfds' being zero means either a timeout or no file descriptors to
     wait for. Try timeout on first occurrence, then assume no file
     descriptors and no file descriptors to wait for means wait for 100
     milliseconds. */

  if(!numfds) {
    repeats++; /* count number of repeated zero numfds */
    if(repeats > 1) {
      WAITMS(100); /* sleep 100 milliseconds */
    }
  }
  else
    repeats = 0;

} while(still_running);

curl_multi_remove_handle(multi_handle, easy_handle);

πŸ’€ RETURN VALUE πŸ’€

returns a CURLMcode type β€” that's the general libcurl multi interface error code, bestie. see libcurl-errors(3) for the full lore πŸ“–


⭐ AVAILABILITY ⭐

this function was added in libcurl 7.28.0. vintage. retro. still slaying πŸ’…


πŸ‘‘ SEE ALSO πŸ‘‘

curl_multi_fdset(3), curl_multi_perform(3),curl_multi_poll(3) ,

(yes those last two are smooshed together in the original and there's a stray comma β€” I am not fixing it, I'm preserving her exactly as she is 🫢)


aaaand that's the whole page!! 🌸 you did so good getting to the bottom, honestly 🧚

libcurl 7.28.0 Β· 12 Jul 2012 β€” the source and version and that date, right here in the cutest little sign-off I could manage πŸ’– byeee βœ¨πŸŽ€

πŸ“¦ where this page comes from