]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
docs/examples: use curl_multi_poll() in multi examples
authorDaniel Stenberg <daniel@haxx.se>
Tue, 6 Jul 2021 08:51:46 +0000 (10:51 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Wed, 7 Jul 2021 06:15:09 +0000 (08:15 +0200)
The API is soon two years old and deserves being shown as the primary
way to drive multi code as it makes it much easier to write code.

multi-poll: removed

multi-legacy: add to show how we did multi API use before
curl_multi_wait/poll.

Closes #7352

15 files changed:
docs/examples/Makefile.inc
docs/examples/http2-download.c
docs/examples/http2-serverpush.c
docs/examples/http2-upload.c
docs/examples/imap-multi.c
docs/examples/multi-app.c
docs/examples/multi-debugcallback.c
docs/examples/multi-double.c
docs/examples/multi-formadd.c
docs/examples/multi-legacy.c [new file with mode: 0644]
docs/examples/multi-poll.c [deleted file]
docs/examples/multi-post.c
docs/examples/multi-single.c
docs/examples/pop3-multi.c
docs/examples/smtp-multi.c

index 4ca12fe1c6ba0bb98637f078a614641f68ea4c95..028956f00b5b16ec11f50a07e74e1e6714a7316a 100644 (file)
@@ -74,7 +74,7 @@ check_PROGRAMS = \
   multi-debugcallback \
   multi-double \
   multi-formadd \
-  multi-poll \
+  multi-legacy \
   multi-post \
   multi-single \
   parseurl \
index 1d95b5ce47ba6d8563cf9becd766207ce84c4c82..6ba82f35b86ae2b6cb76f14219d4c1617716adbc 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -212,79 +212,16 @@ int main(int argc, char **argv)
 
   curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
 
-  /* we start some action by calling perform right away */
-  curl_multi_perform(multi_handle, &still_running);
+  do {
+    CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
 
-  while(still_running) {
-    struct timeval timeout;
-    int rc; /* select() return code */
-    CURLMcode mc; /* curl_multi_fdset() return code */
+    if(still_running)
+      /* wait for activity, timeout or "nothing" */
+      mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
 
-    fd_set fdread;
-    fd_set fdwrite;
-    fd_set fdexcep;
-    int maxfd = -1;
-
-    long curl_timeo = -1;
-
-    FD_ZERO(&fdread);
-    FD_ZERO(&fdwrite);
-    FD_ZERO(&fdexcep);
-
-    /* set a suitable timeout to play around with */
-    timeout.tv_sec = 1;
-    timeout.tv_usec = 0;
-
-    curl_multi_timeout(multi_handle, &curl_timeo);
-    if(curl_timeo >= 0) {
-      timeout.tv_sec = curl_timeo / 1000;
-      if(timeout.tv_sec > 1)
-        timeout.tv_sec = 1;
-      else
-        timeout.tv_usec = (curl_timeo % 1000) * 1000;
-    }
-
-    /* get file descriptors from the transfers */
-    mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
-
-    if(mc != CURLM_OK) {
-      fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
+    if(mc)
       break;
-    }
-
-    /* On success the value of maxfd is guaranteed to be >= -1. We call
-       select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
-       no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
-       to sleep 100ms, which is the minimum suggested value in the
-       curl_multi_fdset() doc. */
-
-    if(maxfd == -1) {
-#ifdef _WIN32
-      Sleep(100);
-      rc = 0;
-#else
-      /* Portable sleep for platforms other than Windows. */
-      struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
-      rc = select(0, NULL, NULL, NULL, &wait);
-#endif
-    }
-    else {
-      /* Note that on some platforms 'timeout' may be modified by select().
-         If you need access to the original value save a copy beforehand. */
-      rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
-    }
-
-    switch(rc) {
-    case -1:
-      /* select error */
-      break;
-    case 0:
-    default:
-      /* timeout or readable/writable sockets */
-      curl_multi_perform(multi_handle, &still_running);
-      break;
-    }
-  }
+  } while(still_running);
 
   for(i = 0; i < num_transfers; i++) {
     curl_multi_remove_handle(multi_handle, trans[i].easy);
index 56f463dc717992ff62f5b8cc56c5657aa12dd11d..3d32f2245de130581b09e07622c1c09c42987f4b 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -213,7 +213,6 @@ int main(void)
 {
   CURL *easy;
   CURLM *multi_handle;
-  int still_running; /* keep number of running handles */
   int transfers = 1; /* we start with one */
   struct CURLMsg *m;
 
@@ -235,78 +234,16 @@ int main(void)
   curl_multi_setopt(multi_handle, CURLMOPT_PUSHFUNCTION, server_push_callback);
   curl_multi_setopt(multi_handle, CURLMOPT_PUSHDATA, &transfers);
 
-  /* we start some action by calling perform right away */
-  curl_multi_perform(multi_handle, &still_running);
-
   do {
-    struct timeval timeout;
-    int rc; /* select() return code */
-    CURLMcode mc; /* curl_multi_fdset() return code */
-
-    fd_set fdread;
-    fd_set fdwrite;
-    fd_set fdexcep;
-    int maxfd = -1;
-
-    long curl_timeo = -1;
-
-    FD_ZERO(&fdread);
-    FD_ZERO(&fdwrite);
-    FD_ZERO(&fdexcep);
-
-    /* set a suitable timeout to play around with */
-    timeout.tv_sec = 1;
-    timeout.tv_usec = 0;
-
-    curl_multi_timeout(multi_handle, &curl_timeo);
-    if(curl_timeo >= 0) {
-      timeout.tv_sec = curl_timeo / 1000;
-      if(timeout.tv_sec > 1)
-        timeout.tv_sec = 1;
-      else
-        timeout.tv_usec = (curl_timeo % 1000) * 1000;
-    }
+    int still_running; /* keep number of running handles */
+    CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
 
-    /* get file descriptors from the transfers */
-    mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
+    if(still_running)
+      /* wait for activity, timeout or "nothing" */
+      mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
 
-    if(mc != CURLM_OK) {
-      fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
+    if(mc)
       break;
-    }
-
-    /* On success the value of maxfd is guaranteed to be >= -1. We call
-       select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
-       no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
-       to sleep 100ms, which is the minimum suggested value in the
-       curl_multi_fdset() doc. */
-
-    if(maxfd == -1) {
-#ifdef _WIN32
-      Sleep(100);
-      rc = 0;
-#else
-      /* Portable sleep for platforms other than Windows. */
-      struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
-      rc = select(0, NULL, NULL, NULL, &wait);
-#endif
-    }
-    else {
-      /* Note that on some platforms 'timeout' may be modified by select().
-         If you need access to the original value save a copy beforehand. */
-      rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
-    }
-
-    switch(rc) {
-    case -1:
-      /* select error */
-      break;
-    case 0:
-    default:
-      /* timeout or readable/writable sockets */
-      curl_multi_perform(multi_handle, &still_running);
-      break;
-    }
 
     /*
      * A little caution when doing server push is that libcurl itself has
index 8545d5aebe6c0871e6b541387d22fd8f6b21992f..9485825b3589543582b659abf858a3926985e83f 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -279,79 +279,17 @@ int main(int argc, char **argv)
   /* We do HTTP/2 so let's stick to one connection per host */
   curl_multi_setopt(multi_handle, CURLMOPT_MAX_HOST_CONNECTIONS, 1L);
 
-  /* we start some action by calling perform right away */
-  curl_multi_perform(multi_handle, &still_running);
+  do {
+    CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
 
-  while(still_running) {
-    struct timeval timeout;
-    int rc; /* select() return code */
-    CURLMcode mc; /* curl_multi_fdset() return code */
+    if(still_running)
+      /* wait for activity, timeout or "nothing" */
+      mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
 
-    fd_set fdread;
-    fd_set fdwrite;
-    fd_set fdexcep;
-    int maxfd = -1;
-
-    long curl_timeo = -1;
-
-    FD_ZERO(&fdread);
-    FD_ZERO(&fdwrite);
-    FD_ZERO(&fdexcep);
-
-    /* set a suitable timeout to play around with */
-    timeout.tv_sec = 1;
-    timeout.tv_usec = 0;
-
-    curl_multi_timeout(multi_handle, &curl_timeo);
-    if(curl_timeo >= 0) {
-      timeout.tv_sec = curl_timeo / 1000;
-      if(timeout.tv_sec > 1)
-        timeout.tv_sec = 1;
-      else
-        timeout.tv_usec = (curl_timeo % 1000) * 1000;
-    }
-
-    /* get file descriptors from the transfers */
-    mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
-
-    if(mc != CURLM_OK) {
-      fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
+    if(mc)
       break;
-    }
 
-    /* On success the value of maxfd is guaranteed to be >= -1. We call
-       select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
-       no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
-       to sleep 100ms, which is the minimum suggested value in the
-       curl_multi_fdset() doc. */
-
-    if(maxfd == -1) {
-#ifdef _WIN32
-      Sleep(100);
-      rc = 0;
-#else
-      /* Portable sleep for platforms other than Windows. */
-      struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
-      rc = select(0, NULL, NULL, NULL, &wait);
-#endif
-    }
-    else {
-      /* Note that on some platforms 'timeout' may be modified by select().
-         If you need access to the original value save a copy beforehand. */
-      rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
-    }
-
-    switch(rc) {
-    case -1:
-      /* select error */
-      break;
-    case 0:
-    default:
-      /* timeout or readable/writable sockets */
-      curl_multi_perform(multi_handle, &still_running);
-      break;
-    }
-  }
+  } while(still_running);
 
   curl_multi_cleanup(multi_handle);
 
index 4283e1a9280c2ebad6aab14c961a07b231042e18..d4ad958281076c49e6cbe0901b509a15dd24e540 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
 /* This is a simple example showing how to fetch mail using libcurl's IMAP
  * capabilities. It builds on the imap-fetch.c example to demonstrate how to
  * use libcurl's multi interface.
- *
- * Note that this example requires libcurl 7.30.0 or above.
  */
 
-#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
-
-static struct timeval tvnow(void)
-{
-  struct timeval now;
-
-  /* time() returns the value of time in seconds since the epoch */
-  now.tv_sec = (long)time(NULL);
-  now.tv_usec = 0;
-
-  return now;
-}
-
-static long tvdiff(struct timeval newer, struct timeval older)
-{
-  return (newer.tv_sec - older.tv_sec) * 1000 +
-    (newer.tv_usec - older.tv_usec) / 1000;
-}
-
 int main(void)
 {
   CURL *curl;
   CURLM *mcurl;
   int still_running = 1;
-  struct timeval mp_start;
 
   curl_global_init(CURL_GLOBAL_DEFAULT);
 
@@ -82,86 +60,16 @@ int main(void)
   /* Tell the multi stack about our easy handle */
   curl_multi_add_handle(mcurl, curl);
 
-  /* Record the start time which we can use later */
-  mp_start = tvnow();
-
-  /* We start some action by calling perform right away */
-  curl_multi_perform(mcurl, &still_running);
-
-  while(still_running) {
-    struct timeval timeout;
-    fd_set fdread;
-    fd_set fdwrite;
-    fd_set fdexcep;
-    int maxfd = -1;
-    int rc;
-    CURLMcode mc; /* curl_multi_fdset() return code */
+  do {
+    CURLMcode mc = curl_multi_perform(mcurl, &still_running);
 
-    long curl_timeo = -1;
+    if(still_running)
+      /* wait for activity, timeout or "nothing" */
+      mc = curl_multi_poll(mcurl, NULL, 0, 1000, NULL);
 
-    /* Initialise the file descriptors */
-    FD_ZERO(&fdread);
-    FD_ZERO(&fdwrite);
-    FD_ZERO(&fdexcep);
-
-    /* Set a suitable timeout to play around with */
-    timeout.tv_sec = 1;
-    timeout.tv_usec = 0;
-
-    curl_multi_timeout(mcurl, &curl_timeo);
-    if(curl_timeo >= 0) {
-      timeout.tv_sec = curl_timeo / 1000;
-      if(timeout.tv_sec > 1)
-        timeout.tv_sec = 1;
-      else
-        timeout.tv_usec = (curl_timeo % 1000) * 1000;
-    }
-
-    /* get file descriptors from the transfers */
-    mc = curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd);
-
-    if(mc != CURLM_OK) {
-      fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
-      break;
-    }
-
-    /* On success the value of maxfd is guaranteed to be >= -1. We call
-       select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
-       no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
-       to sleep 100ms, which is the minimum suggested value in the
-       curl_multi_fdset() doc. */
-
-    if(maxfd == -1) {
-#ifdef _WIN32
-      Sleep(100);
-      rc = 0;
-#else
-      /* Portable sleep for platforms other than Windows. */
-      struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
-      rc = select(0, NULL, NULL, NULL, &wait);
-#endif
-    }
-    else {
-      /* Note that on some platforms 'timeout' may be modified by select().
-         If you need access to the original value save a copy beforehand. */
-      rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
-    }
-
-    if(tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) {
-      fprintf(stderr,
-              "ABORTING: Since it seems that we would have run forever.\n");
-      break;
-    }
-
-    switch(rc) {
-    case -1:  /* select error */
-      break;
-    case 0:   /* timeout */
-    default:  /* action */
-      curl_multi_perform(mcurl, &still_running);
+    if(mc)
       break;
-    }
-  }
+  } while(still_running);
 
   /* Always cleanup */
   curl_multi_remove_handle(mcurl, curl);
index 52748d433a23178417d8be25c7afa79755419780..76c25750be298f09039e8d6c36de12fa23ca3731 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -48,7 +48,7 @@ int main(void)
   CURL *handles[HANDLECOUNT];
   CURLM *multi_handle;
 
-  int still_running = 0; /* keep number of running handles */
+  int still_running = 1; /* keep number of running handles */
   int i;
 
   CURLMsg *msg; /* for picking up messages with the transfer status */
@@ -71,79 +71,16 @@ int main(void)
   for(i = 0; i<HANDLECOUNT; i++)
     curl_multi_add_handle(multi_handle, handles[i]);
 
-  /* we start some action by calling perform right away */
-  curl_multi_perform(multi_handle, &still_running);
-
   while(still_running) {
-    struct timeval timeout;
-    int rc; /* select() return code */
-    CURLMcode mc; /* curl_multi_fdset() return code */
-
-    fd_set fdread;
-    fd_set fdwrite;
-    fd_set fdexcep;
-    int maxfd = -1;
-
-    long curl_timeo = -1;
-
-    FD_ZERO(&fdread);
-    FD_ZERO(&fdwrite);
-    FD_ZERO(&fdexcep);
-
-    /* set a suitable timeout to play around with */
-    timeout.tv_sec = 1;
-    timeout.tv_usec = 0;
-
-    curl_multi_timeout(multi_handle, &curl_timeo);
-    if(curl_timeo >= 0) {
-      timeout.tv_sec = curl_timeo / 1000;
-      if(timeout.tv_sec > 1)
-        timeout.tv_sec = 1;
-      else
-        timeout.tv_usec = (curl_timeo % 1000) * 1000;
-    }
+    CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
 
-    /* get file descriptors from the transfers */
-    mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
+    if(still_running)
+      /* wait for activity, timeout or "nothing" */
+      mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
 
-    if(mc != CURLM_OK) {
-      fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
+    if(mc)
       break;
-    }
-
-    /* On success the value of maxfd is guaranteed to be >= -1. We call
-       select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
-       no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
-       to sleep 100ms, which is the minimum suggested value in the
-       curl_multi_fdset() doc. */
-
-    if(maxfd == -1) {
-#ifdef _WIN32
-      Sleep(100);
-      rc = 0;
-#else
-      /* Portable sleep for platforms other than Windows. */
-      struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
-      rc = select(0, NULL, NULL, NULL, &wait);
-#endif
-    }
-    else {
-      /* Note that on some platforms 'timeout' may be modified by select().
-         If you need access to the original value save a copy beforehand. */
-      rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
-    }
-
-    switch(rc) {
-    case -1:
-      /* select error */
-      break;
-    case 0: /* timeout */
-    default: /* action */
-      curl_multi_perform(multi_handle, &still_running);
-      break;
-    }
   }
-
   /* See how the transfers went */
   while((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
     if(msg->msg == CURLMSG_DONE) {
index 4021ef5cc4e37562d5aabb6047de69f3761b2013..af79e56dfddc469f1f32fe78072ffff53bcd3f40 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -147,81 +147,17 @@ int main(void)
   /* add the individual transfers */
   curl_multi_add_handle(multi_handle, http_handle);
 
-  /* we start some action by calling perform right away */
-  curl_multi_perform(multi_handle, &still_running);
+  do {
+    CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
 
-  while(still_running) {
-    struct timeval timeout;
-    int rc; /* select() return code */
-    CURLMcode mc; /* curl_multi_fdset() return code */
+    if(still_running)
+      /* wait for activity, timeout or "nothing" */
+      mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
 
-    fd_set fdread;
-    fd_set fdwrite;
-    fd_set fdexcep;
-    int maxfd = -1;
-
-    long curl_timeo = -1;
-
-    FD_ZERO(&fdread);
-    FD_ZERO(&fdwrite);
-    FD_ZERO(&fdexcep);
-
-    /* set a suitable timeout to play around with */
-    timeout.tv_sec = 1;
-    timeout.tv_usec = 0;
-
-    curl_multi_timeout(multi_handle, &curl_timeo);
-    if(curl_timeo >= 0) {
-      timeout.tv_sec = curl_timeo / 1000;
-      if(timeout.tv_sec > 1)
-        timeout.tv_sec = 1;
-      else
-        timeout.tv_usec = (curl_timeo % 1000) * 1000;
-    }
-
-    /* get file descriptors from the transfers */
-    mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
-
-    if(mc != CURLM_OK) {
-      fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
+    if(mc)
       break;
-    }
 
-    /* On success the value of maxfd is guaranteed to be >= -1. We call
-       select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
-       no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
-       to sleep 100ms, which is the minimum suggested value in the
-       curl_multi_fdset() doc. */
-
-    if(maxfd == -1) {
-#ifdef _WIN32
-      Sleep(100);
-      rc = 0;
-#else
-      /* Portable sleep for platforms other than Windows. */
-      struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
-      rc = select(0, NULL, NULL, NULL, &wait);
-#endif
-    }
-    else {
-      /* Note that on some platforms 'timeout' may be modified by select().
-         If you need access to the original value save a copy beforehand. */
-      rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
-    }
-
-    switch(rc) {
-    case -1:
-      /* select error */
-      still_running = 0;
-      printf("select() returns error, this is badness\n");
-      break;
-    case 0:
-    default:
-      /* timeout or readable/writable sockets */
-      curl_multi_perform(multi_handle, &still_running);
-      break;
-    }
-  }
+  } while(still_running);
 
   curl_multi_cleanup(multi_handle);
 
index 005989570ac55bcf770e18aeeb3b4d3a09cb4f8f..efcace0e74fa0f31b1b2de85cb954bff19b5b4e1 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -42,7 +42,7 @@ int main(void)
   CURL *http_handle2;
   CURLM *multi_handle;
 
-  int still_running = 0; /* keep number of running handles */
+  int still_running = 1; /* keep number of running handles */
 
   http_handle = curl_easy_init();
   http_handle2 = curl_easy_init();
@@ -60,80 +60,32 @@ int main(void)
   curl_multi_add_handle(multi_handle, http_handle);
   curl_multi_add_handle(multi_handle, http_handle2);
 
-  /* we start some action by calling perform right away */
-  curl_multi_perform(multi_handle, &still_running);
-
   while(still_running) {
-    struct timeval timeout;
-    int rc; /* select() return code */
-    CURLMcode mc; /* curl_multi_fdset() return code */
-
-    fd_set fdread;
-    fd_set fdwrite;
-    fd_set fdexcep;
-    int maxfd = -1;
-
-    long curl_timeo = -1;
-
-    FD_ZERO(&fdread);
-    FD_ZERO(&fdwrite);
-    FD_ZERO(&fdexcep);
-
-    /* set a suitable timeout to play around with */
-    timeout.tv_sec = 1;
-    timeout.tv_usec = 0;
-
-    curl_multi_timeout(multi_handle, &curl_timeo);
-    if(curl_timeo >= 0) {
-      timeout.tv_sec = curl_timeo / 1000;
-      if(timeout.tv_sec > 1)
-        timeout.tv_sec = 1;
-      else
-        timeout.tv_usec = (curl_timeo % 1000) * 1000;
-    }
-
-    /* get file descriptors from the transfers */
-    mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
-
-    if(mc != CURLM_OK) {
-      fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
-      break;
-    }
-
-    /* On success the value of maxfd is guaranteed to be >= -1. We call
-       select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
-       no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
-       to sleep 100ms, which is the minimum suggested value in the
-       curl_multi_fdset() doc. */
-
-    if(maxfd == -1) {
-#ifdef _WIN32
-      Sleep(100);
-      rc = 0;
-#else
-      /* Portable sleep for platforms other than Windows. */
-      struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
-      rc = select(0, NULL, NULL, NULL, &wait);
-#endif
-    }
-    else {
-      /* Note that on some platforms 'timeout' may be modified by select().
-         If you need access to the original value save a copy beforehand. */
-      rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
-    }
-
-    switch(rc) {
-    case -1:
-      /* select error */
-      break;
-    case 0:
-    default:
-      /* timeout or readable/writable sockets */
-      curl_multi_perform(multi_handle, &still_running);
+    CURLMsg *msg;
+    int queued;
+    CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
+
+    if(still_running)
+      /* wait for activity, timeout or "nothing" */
+      mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
+
+    if(mc)
       break;
-    }
+
+    do {
+      msg = curl_multi_info_read(multi_handle, &queued);
+      if(msg) {
+        if(msg->msg == CURLMSG_DONE) {
+          /* a transfer ended */
+          fprintf(stderr, "Transfer completed\n");
+        }
+      }
+    } while(msg);
   }
 
+  curl_multi_remove_handle(multi_handle, http_handle);
+  curl_multi_remove_handle(multi_handle, http_handle2);
+
   curl_multi_cleanup(multi_handle);
 
   curl_easy_cleanup(http_handle);
index 0d4709256c751319ed419067961ece21fbd50617..b9defd4529b85436c370be710035f212b164160c 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -81,80 +81,17 @@ int main(void)
 
     curl_multi_add_handle(multi_handle, curl);
 
-    curl_multi_perform(multi_handle, &still_running);
+    do {
+      CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
 
-    while(still_running) {
-      struct timeval timeout;
-      int rc; /* select() return code */
-      CURLMcode mc; /* curl_multi_fdset() return code */
+      if(still_running)
+        /* wait for activity, timeout or "nothing" */
+        mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
 
-      fd_set fdread;
-      fd_set fdwrite;
-      fd_set fdexcep;
-      int maxfd = -1;
-
-      long curl_timeo = -1;
-
-      FD_ZERO(&fdread);
-      FD_ZERO(&fdwrite);
-      FD_ZERO(&fdexcep);
-
-      /* set a suitable timeout to play around with */
-      timeout.tv_sec = 1;
-      timeout.tv_usec = 0;
-
-      curl_multi_timeout(multi_handle, &curl_timeo);
-      if(curl_timeo >= 0) {
-        timeout.tv_sec = curl_timeo / 1000;
-        if(timeout.tv_sec > 1)
-          timeout.tv_sec = 1;
-        else
-          timeout.tv_usec = (curl_timeo % 1000) * 1000;
-      }
-
-      /* get file descriptors from the transfers */
-      mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
-
-      if(mc != CURLM_OK) {
-        fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
-        break;
-      }
-
-      /* On success the value of maxfd is guaranteed to be >= -1. We call
-         select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
-         no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
-         to sleep 100ms, which is the minimum suggested value in the
-         curl_multi_fdset() doc. */
-
-      if(maxfd == -1) {
-#ifdef _WIN32
-        Sleep(100);
-        rc = 0;
-#else
-        /* Portable sleep for platforms other than Windows. */
-        struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
-        rc = select(0, NULL, NULL, NULL, &wait);
-#endif
-      }
-      else {
-        /* Note that on some platforms 'timeout' may be modified by select().
-           If you need access to the original value save a copy beforehand. */
-        rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
-      }
-
-      switch(rc) {
-      case -1:
-        /* select error */
+      if(mc)
         break;
-      case 0:
-      default:
-        /* timeout or readable/writable sockets */
-        printf("perform!\n");
-        curl_multi_perform(multi_handle, &still_running);
-        printf("running: %d!\n", still_running);
-        break;
-      }
-    }
+
+    } while(still_running);
 
     curl_multi_cleanup(multi_handle);
 
diff --git a/docs/examples/multi-legacy.c b/docs/examples/multi-legacy.c
new file mode 100644 (file)
index 0000000..ca1a9b9
--- /dev/null
@@ -0,0 +1,177 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * 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.
+ *
+ ***************************************************************************/
+/* <DESC>
+ * A basic application source code using the multi interface doing two
+ * transfers in parallel without curl_multi_wait/poll.
+ * </DESC>
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+/* somewhat unix-specific */
+#include <sys/time.h>
+#include <unistd.h>
+
+/* curl stuff */
+#include <curl/curl.h>
+
+/*
+ * Download a HTTP file and upload an FTP file simultaneously.
+ */
+
+#define HANDLECOUNT 2   /* Number of simultaneous transfers */
+#define HTTP_HANDLE 0   /* Index for the HTTP transfer */
+#define FTP_HANDLE 1    /* Index for the FTP transfer */
+
+int main(void)
+{
+  CURL *handles[HANDLECOUNT];
+  CURLM *multi_handle;
+
+  int still_running = 0; /* keep number of running handles */
+  int i;
+
+  CURLMsg *msg; /* for picking up messages with the transfer status */
+  int msgs_left; /* how many messages are left */
+
+  /* Allocate one CURL handle per transfer */
+  for(i = 0; i<HANDLECOUNT; i++)
+    handles[i] = curl_easy_init();
+
+  /* set the options (I left out a few, you'll get the point anyway) */
+  curl_easy_setopt(handles[HTTP_HANDLE], CURLOPT_URL, "https://example.com");
+
+  curl_easy_setopt(handles[FTP_HANDLE], CURLOPT_URL, "ftp://example.com");
+  curl_easy_setopt(handles[FTP_HANDLE], CURLOPT_UPLOAD, 1L);
+
+  /* init a multi stack */
+  multi_handle = curl_multi_init();
+
+  /* add the individual transfers */
+  for(i = 0; i<HANDLECOUNT; i++)
+    curl_multi_add_handle(multi_handle, handles[i]);
+
+  /* we start some action by calling perform right away */
+  curl_multi_perform(multi_handle, &still_running);
+
+  while(still_running) {
+    struct timeval timeout;
+    int rc; /* select() return code */
+    CURLMcode mc; /* curl_multi_fdset() return code */
+
+    fd_set fdread;
+    fd_set fdwrite;
+    fd_set fdexcep;
+    int maxfd = -1;
+
+    long curl_timeo = -1;
+
+    FD_ZERO(&fdread);
+    FD_ZERO(&fdwrite);
+    FD_ZERO(&fdexcep);
+
+    /* set a suitable timeout to play around with */
+    timeout.tv_sec = 1;
+    timeout.tv_usec = 0;
+
+    curl_multi_timeout(multi_handle, &curl_timeo);
+    if(curl_timeo >= 0) {
+      timeout.tv_sec = curl_timeo / 1000;
+      if(timeout.tv_sec > 1)
+        timeout.tv_sec = 1;
+      else
+        timeout.tv_usec = (curl_timeo % 1000) * 1000;
+    }
+
+    /* get file descriptors from the transfers */
+    mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+    if(mc != CURLM_OK) {
+      fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
+      break;
+    }
+
+    /* On success the value of maxfd is guaranteed to be >= -1. We call
+       select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
+       no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
+       to sleep 100ms, which is the minimum suggested value in the
+       curl_multi_fdset() doc. */
+
+    if(maxfd == -1) {
+#ifdef _WIN32
+      Sleep(100);
+      rc = 0;
+#else
+      /* Portable sleep for platforms other than Windows. */
+      struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
+      rc = select(0, NULL, NULL, NULL, &wait);
+#endif
+    }
+    else {
+      /* Note that on some platforms 'timeout' may be modified by select().
+         If you need access to the original value save a copy beforehand. */
+      rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
+    }
+
+    switch(rc) {
+    case -1:
+      /* select error */
+      break;
+    case 0: /* timeout */
+    default: /* action */
+      curl_multi_perform(multi_handle, &still_running);
+      break;
+    }
+  }
+
+  /* See how the transfers went */
+  while((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
+    if(msg->msg == CURLMSG_DONE) {
+      int idx;
+
+      /* Find out which handle this message is about */
+      for(idx = 0; idx<HANDLECOUNT; idx++) {
+        int found = (msg->easy_handle == handles[idx]);
+        if(found)
+          break;
+      }
+
+      switch(idx) {
+      case HTTP_HANDLE:
+        printf("HTTP transfer completed with status %d\n", msg->data.result);
+        break;
+      case FTP_HANDLE:
+        printf("FTP transfer completed with status %d\n", msg->data.result);
+        break;
+      }
+    }
+  }
+
+  curl_multi_cleanup(multi_handle);
+
+  /* Free the CURL handles */
+  for(i = 0; i<HANDLECOUNT; i++)
+    curl_easy_cleanup(handles[i]);
+
+  return 0;
+}
diff --git a/docs/examples/multi-poll.c b/docs/examples/multi-poll.c
deleted file mode 100644 (file)
index 5efb67b..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * 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.
- *
- ***************************************************************************/
-/* <DESC>
- * single download with the multi interface's curl_multi_poll
- * </DESC>
- */
-
-#include <stdio.h>
-#include <string.h>
-
-/* somewhat unix-specific */
-#include <sys/time.h>
-#include <unistd.h>
-
-/* curl stuff */
-#include <curl/curl.h>
-
-int main(void)
-{
-  CURL *http_handle;
-  CURLM *multi_handle;
-  int still_running = 1; /* keep number of running handles */
-
-  curl_global_init(CURL_GLOBAL_DEFAULT);
-
-  http_handle = curl_easy_init();
-
-  curl_easy_setopt(http_handle, CURLOPT_URL, "https://www.example.com/");
-
-  multi_handle = curl_multi_init();
-
-  curl_multi_add_handle(multi_handle, http_handle);
-
-  while(still_running) {
-    CURLMcode mc; /* curl_multi_poll() return code */
-    int numfds;
-
-    /* we start some action by calling perform right away */
-    mc = curl_multi_perform(multi_handle, &still_running);
-
-    if(still_running)
-      /* wait for activity, timeout or "nothing" */
-      mc = curl_multi_poll(multi_handle, NULL, 0, 1000, &numfds);
-
-    if(mc != CURLM_OK) {
-      fprintf(stderr, "curl_multi_wait() failed, code %d.\n", mc);
-      break;
-    }
-  }
-
-  curl_multi_remove_handle(multi_handle, http_handle);
-  curl_easy_cleanup(http_handle);
-  curl_multi_cleanup(multi_handle);
-  curl_global_cleanup();
-
-  return 0;
-}
index e80a90c5bf309d01f0325b50dfb01726e6f29cf8..a7af0408ca22f151a7f0172d18221717e590f0a6 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -77,80 +77,16 @@ int main(void)
 
     curl_multi_add_handle(multi_handle, curl);
 
-    curl_multi_perform(multi_handle, &still_running);
+    do {
+      CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
 
-    while(still_running) {
-      struct timeval timeout;
-      int rc; /* select() return code */
-      CURLMcode mc; /* curl_multi_fdset() return code */
+      if(still_running)
+        /* wait for activity, timeout or "nothing" */
+        mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
 
-      fd_set fdread;
-      fd_set fdwrite;
-      fd_set fdexcep;
-      int maxfd = -1;
-
-      long curl_timeo = -1;
-
-      FD_ZERO(&fdread);
-      FD_ZERO(&fdwrite);
-      FD_ZERO(&fdexcep);
-
-      /* set a suitable timeout to play around with */
-      timeout.tv_sec = 1;
-      timeout.tv_usec = 0;
-
-      curl_multi_timeout(multi_handle, &curl_timeo);
-      if(curl_timeo >= 0) {
-        timeout.tv_sec = curl_timeo / 1000;
-        if(timeout.tv_sec > 1)
-          timeout.tv_sec = 1;
-        else
-          timeout.tv_usec = (curl_timeo % 1000) * 1000;
-      }
-
-      /* get file descriptors from the transfers */
-      mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
-
-      if(mc != CURLM_OK) {
-        fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
-        break;
-      }
-
-      /* On success the value of maxfd is guaranteed to be >= -1. We call
-         select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
-         no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
-         to sleep 100ms, which is the minimum suggested value in the
-         curl_multi_fdset() doc. */
-
-      if(maxfd == -1) {
-#ifdef _WIN32
-        Sleep(100);
-        rc = 0;
-#else
-        /* Portable sleep for platforms other than Windows. */
-        struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
-        rc = select(0, NULL, NULL, NULL, &wait);
-#endif
-      }
-      else {
-        /* Note that on some platforms 'timeout' may be modified by select().
-           If you need access to the original value save a copy beforehand. */
-        rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
-      }
-
-      switch(rc) {
-      case -1:
-        /* select error */
-        break;
-      case 0:
-      default:
-        /* timeout or readable/writable sockets */
-        printf("perform!\n");
-        curl_multi_perform(multi_handle, &still_running);
-        printf("running: %d!\n", still_running);
+      if(mc)
         break;
-      }
-    }
+    } while(still_running);
 
     curl_multi_cleanup(multi_handle);
 
index 2c64d2375177caac32a374164696a5d46340e9f6..272d4efe99896b2e8a372a2c96c9d0b1450d7561 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -50,9 +50,7 @@ int main(void)
 {
   CURL *http_handle;
   CURLM *multi_handle;
-
-  int still_running = 0; /* keep number of running handles */
-  int repeats = 0;
+  int still_running = 1; /* keep number of running handles */
 
   curl_global_init(CURL_GLOBAL_DEFAULT);
 
@@ -67,37 +65,18 @@ int main(void)
   /* add the individual transfers */
   curl_multi_add_handle(multi_handle, http_handle);
 
-  /* we start some action by calling perform right away */
-  curl_multi_perform(multi_handle, &still_running);
-
-  while(still_running) {
-    CURLMcode mc; /* curl_multi_wait() return code */
-    int numfds;
+  do {
+    CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
 
     /* wait for activity, timeout or "nothing" */
-    mc = curl_multi_wait(multi_handle, NULL, 0, 1000, &numfds);
+    mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
 
     if(mc != CURLM_OK) {
       fprintf(stderr, "curl_multi_wait() 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;
-
-    curl_multi_perform(multi_handle, &still_running);
-  }
+  } while(still_running);
 
   curl_multi_remove_handle(multi_handle, http_handle);
 
index 713dc7fa1c18b6d4ea0d7b8632a40fe58491ea43..c819aab0816177b44f9da0f8e1908735190ae30e 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
 /* This is a simple example showing how to retrieve mail using libcurl's POP3
  * capabilities. It builds on the pop3-retr.c example to demonstrate how to use
  * libcurl's multi interface.
- *
- * Note that this example requires libcurl 7.20.0 or above.
  */
 
-#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
-
-static struct timeval tvnow(void)
-{
-  struct timeval now;
-
-  /* time() returns the value of time in seconds since the epoch */
-  now.tv_sec = (long)time(NULL);
-  now.tv_usec = 0;
-
-  return now;
-}
-
-static long tvdiff(struct timeval newer, struct timeval older)
-{
-  return (newer.tv_sec - older.tv_sec) * 1000 +
-    (newer.tv_usec - older.tv_usec) / 1000;
-}
-
 int main(void)
 {
   CURL *curl;
   CURLM *mcurl;
   int still_running = 1;
-  struct timeval mp_start;
 
   curl_global_init(CURL_GLOBAL_DEFAULT);
 
@@ -82,86 +60,17 @@ int main(void)
   /* Tell the multi stack about our easy handle */
   curl_multi_add_handle(mcurl, curl);
 
-  /* Record the start time which we can use later */
-  mp_start = tvnow();
-
-  /* We start some action by calling perform right away */
-  curl_multi_perform(mcurl, &still_running);
-
-  while(still_running) {
-    struct timeval timeout;
-    fd_set fdread;
-    fd_set fdwrite;
-    fd_set fdexcep;
-    int maxfd = -1;
-    int rc;
-    CURLMcode mc; /* curl_multi_fdset() return code */
-
-    long curl_timeo = -1;
-
-    /* Initialise the file descriptors */
-    FD_ZERO(&fdread);
-    FD_ZERO(&fdwrite);
-    FD_ZERO(&fdexcep);
-
-    /* Set a suitable timeout to play around with */
-    timeout.tv_sec = 1;
-    timeout.tv_usec = 0;
-
-    curl_multi_timeout(mcurl, &curl_timeo);
-    if(curl_timeo >= 0) {
-      timeout.tv_sec = curl_timeo / 1000;
-      if(timeout.tv_sec > 1)
-        timeout.tv_sec = 1;
-      else
-        timeout.tv_usec = (curl_timeo % 1000) * 1000;
-    }
-
-    /* get file descriptors from the transfers */
-    mc = curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd);
-
-    if(mc != CURLM_OK) {
-      fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
-      break;
-    }
-
-    /* On success the value of maxfd is guaranteed to be >= -1. We call
-       select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
-       no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
-       to sleep 100ms, which is the minimum suggested value in the
-       curl_multi_fdset() doc. */
-
-    if(maxfd == -1) {
-#ifdef _WIN32
-      Sleep(100);
-      rc = 0;
-#else
-      /* Portable sleep for platforms other than Windows. */
-      struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
-      rc = select(0, NULL, NULL, NULL, &wait);
-#endif
-    }
-    else {
-      /* Note that on some platforms 'timeout' may be modified by select().
-         If you need access to the original value save a copy beforehand. */
-      rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
-    }
-
-    if(tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) {
-      fprintf(stderr,
-              "ABORTING: Since it seems that we would have run forever.\n");
-      break;
-    }
+  do {
+    CURLMcode mc = curl_multi_perform(mcurl, &still_running);
 
-    switch(rc) {
-    case -1:  /* select error */
-      break;
-    case 0:   /* timeout */
-    default:  /* action */
-      curl_multi_perform(mcurl, &still_running);
+    if(still_running)
+      /* wait for activity, timeout or "nothing" */
+      mc = curl_multi_poll(mcurl, NULL, 0, 1000, NULL);
+
+    if(mc)
       break;
-    }
-  }
+
+  } while(still_running);
 
   /* Always cleanup */
   curl_multi_remove_handle(mcurl, curl);
index a52f0ae58ee4f5c251a1be61a7f95226b2fe360d..ac867a21ae7e4690be4074fd131fdaa45c9c44a8 100644 (file)
 /* This is an example showing how to send mail using libcurl's SMTP
  * capabilities. It builds on the smtp-mail.c example to demonstrate how to use
  * libcurl's multi interface.
- *
- * Note that this example requires libcurl 7.20.0 or above.
  */
 
 #define FROM_MAIL     "<sender@example.com>"
 #define TO_MAIL       "<recipient@example.com>"
 #define CC_MAIL       "<info@example.com>"
 
-#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
-
 static const char *payload_text =
   "Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n"
   "To: " TO_MAIL "\r\n"
@@ -84,29 +80,11 @@ static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
   return 0;
 }
 
-static struct timeval tvnow(void)
-{
-  struct timeval now;
-
-  /* time() returns the value of time in seconds since the epoch */
-  now.tv_sec = (long)time(NULL);
-  now.tv_usec = 0;
-
-  return now;
-}
-
-static long tvdiff(struct timeval newer, struct timeval older)
-{
-  return (newer.tv_sec - older.tv_sec) * 1000 +
-    (newer.tv_usec - older.tv_usec) / 1000;
-}
-
 int main(void)
 {
   CURL *curl;
   CURLM *mcurl;
   int still_running = 1;
-  struct timeval mp_start;
   struct curl_slist *recipients = NULL;
   struct upload_status upload_ctx = { 0 };
 
@@ -148,86 +126,17 @@ int main(void)
   /* Tell the multi stack about our easy handle */
   curl_multi_add_handle(mcurl, curl);
 
-  /* Record the start time which we can use later */
-  mp_start = tvnow();
-
-  /* We start some action by calling perform right away */
-  curl_multi_perform(mcurl, &still_running);
-
-  while(still_running) {
-    struct timeval timeout;
-    fd_set fdread;
-    fd_set fdwrite;
-    fd_set fdexcep;
-    int maxfd = -1;
-    int rc;
-    CURLMcode mc; /* curl_multi_fdset() return code */
-
-    long curl_timeo = -1;
-
-    /* Initialise the file descriptors */
-    FD_ZERO(&fdread);
-    FD_ZERO(&fdwrite);
-    FD_ZERO(&fdexcep);
-
-    /* Set a suitable timeout to play around with */
-    timeout.tv_sec = 1;
-    timeout.tv_usec = 0;
-
-    curl_multi_timeout(mcurl, &curl_timeo);
-    if(curl_timeo >= 0) {
-      timeout.tv_sec = curl_timeo / 1000;
-      if(timeout.tv_sec > 1)
-        timeout.tv_sec = 1;
-      else
-        timeout.tv_usec = (curl_timeo % 1000) * 1000;
-    }
-
-    /* get file descriptors from the transfers */
-    mc = curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd);
-
-    if(mc != CURLM_OK) {
-      fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
-      break;
-    }
-
-    /* On success the value of maxfd is guaranteed to be >= -1. We call
-       select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
-       no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
-       to sleep 100ms, which is the minimum suggested value in the
-       curl_multi_fdset() doc. */
-
-    if(maxfd == -1) {
-#ifdef _WIN32
-      Sleep(100);
-      rc = 0;
-#else
-      /* Portable sleep for platforms other than Windows. */
-      struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
-      rc = select(0, NULL, NULL, NULL, &wait);
-#endif
-    }
-    else {
-      /* Note that on some platforms 'timeout' may be modified by select().
-         If you need access to the original value save a copy beforehand. */
-      rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
-    }
-
-    if(tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) {
-      fprintf(stderr,
-              "ABORTING: Since it seems that we would have run forever.\n");
-      break;
-    }
+  do {
+    CURLMcode mc = curl_multi_perform(mcurl, &still_running);
 
-    switch(rc) {
-    case -1:  /* select error */
-      break;
-    case 0:   /* timeout */
-    default:  /* action */
-      curl_multi_perform(mcurl, &still_running);
+    if(still_running)
+      /* wait for activity, timeout or "nothing" */
+      mc = curl_multi_poll(mcurl, NULL, 0, 1000, NULL);
+
+    if(mc)
       break;
-    }
-  }
+
+  } while(still_running);
 
   /* Free the list of recipients */
   curl_slist_free_all(recipients);