Commit a607f8a2 authored by Jay Satiro's avatar Jay Satiro Committed by Daniel Stenberg
Browse files

examples: Don't call select() to sleep on windows

Windows does not support using select() for sleeping without a dummy
socket. Instead use Windows' Sleep() and sleep for 100ms which is the
minimum suggested value in the curl_multi_fdset() doc.

Prior to this change the multi examples would exit prematurely since
select() would error instead of sleeping when called without an fd.

Reported-by: Johan Lantz
Bug: http://curl.haxx.se/mail/lib-2014-11/0221.html
parent ed77fdf3
Loading
Loading
Loading
Loading
+24 −7
Original line number Diff line number Diff line
@@ -128,6 +128,7 @@ static int fill_buffer(URL_FILE *file, size_t want)
  fd_set fdexcep;
  struct timeval timeout;
  int rc;
  CURLMcode mc; /* curl_multi_fdset() return code */

  /* only attempt to fill buffer if transactions still running and buffer
   * doesnt exceed required size already
@@ -158,15 +159,31 @@ static int fill_buffer(URL_FILE *file, size_t want)
    }

    /* get file descriptors from the transfers */
    curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
    mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);

    /* In a real-world program you OF COURSE check the return code of the
       function calls.  On success, the value of maxfd is guaranteed to be
       greater or equal than -1.  We call select(maxfd + 1, ...), specially
       in case of (maxfd == -1), we call select(0, ...), which is basically
       equal to sleep. */
    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) we call
       select(0, ...), which is basically equal to sleeping the timeout. On
       Windows we can't sleep via select without a dummy socket and instead
       we Sleep() for 100ms which is the minimum suggested value in the
       curl_multi_fdset() doc. */

#ifdef _WIN32
    if(maxfd == -1) {
      Sleep(100);
      rc = 0;
    }
    else
#endif
    {
      rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
    }

    switch(rc) {
    case -1:
+26 −8
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ int main(void)
    fd_set fdexcep;
    int maxfd = -1;
    int rc;
    CURLMcode mc; /* curl_multi_fdset() return code */

    long curl_timeo = -1;

@@ -109,15 +110,32 @@ int main(void)
        timeout.tv_usec = (curl_timeo % 1000) * 1000;
    }

    /* Get file descriptors from the transfers */
    curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd);
    /* get file descriptors from the transfers */
    mc = curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd);

    /* In a real-world program you OF COURSE check the return code of the
       function calls.  On success, the value of maxfd is guaranteed to be
       greater or equal than -1.  We call select(maxfd + 1, ...), specially in
       case of (maxfd == -1), we call select(0, ...), which is basically equal
       to sleep. */
    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) we call
       select(0, ...), which is basically equal to sleeping the timeout. On
       Windows we can't sleep via select without a dummy socket and instead
       we Sleep() for 100ms which is the minimum suggested value in the
       curl_multi_fdset() doc. */

#ifdef _WIN32
    if(maxfd == -1) {
      Sleep(100);
      rc = 0;
    }
    else
#endif
    {
      rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
    }

    if(tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) {
      fprintf(stderr,
+24 −7
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ int main(void)
  do {
    struct timeval timeout;
    int rc; /* select() return code */
    CURLMcode mc; /* curl_multi_fdset() return code */

    fd_set fdread;
    fd_set fdwrite;
@@ -99,15 +100,31 @@ int main(void)
    }

    /* get file descriptors from the transfers */
    curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
    mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);

    /* In a real-world program you OF COURSE check the return code of the
       function calls.  On success, the value of maxfd is guaranteed to be
       greater or equal than -1.  We call select(maxfd + 1, ...), specially in
       case of (maxfd == -1), we call select(0, ...), which is basically equal
       to sleep. */
    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) we call
       select(0, ...), which is basically equal to sleeping the timeout. On
       Windows we can't sleep via select without a dummy socket and instead
       we Sleep() for 100ms which is the minimum suggested value in the
       curl_multi_fdset() doc. */

#ifdef _WIN32
    if(maxfd == -1) {
      Sleep(100);
      rc = 0;
    }
    else
#endif
    {
      rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
    }

    switch(rc) {
    case -1:
+24 −7
Original line number Diff line number Diff line
@@ -147,6 +147,7 @@ int main(void)
  do {
    struct timeval timeout;
    int rc; /* select() return code */
    CURLMcode mc; /* curl_multi_fdset() return code */

    fd_set fdread;
    fd_set fdwrite;
@@ -173,15 +174,31 @@ int main(void)
    }

    /* get file descriptors from the transfers */
    curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
    mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);

    /* In a real-world program you OF COURSE check the return code of the
       function calls.  On success, the value of maxfd is guaranteed to be
       greater or equal than -1.  We call select(maxfd + 1, ...), specially in
       case of (maxfd == -1), we call select(0, ...), which is basically equal
       to sleep. */
    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) we call
       select(0, ...), which is basically equal to sleeping the timeout. On
       Windows we can't sleep via select without a dummy socket and instead
       we Sleep() for 100ms which is the minimum suggested value in the
       curl_multi_fdset() doc. */

#ifdef _WIN32
    if(maxfd == -1) {
      Sleep(100);
      rc = 0;
    }
    else
#endif
    {
      rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
    }

    switch(rc) {
    case -1:
+24 −7
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ int main(void)
  do {
    struct timeval timeout;
    int rc; /* select() return code */
    CURLMcode mc; /* curl_multi_fdset() return code */

    fd_set fdread;
    fd_set fdwrite;
@@ -88,15 +89,31 @@ int main(void)
    }

    /* get file descriptors from the transfers */
    curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
    mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);

    /* In a real-world program you OF COURSE check the return code of the
       function calls.  On success, the value of maxfd is guaranteed to be
       greater or equal than -1.  We call select(maxfd + 1, ...), specially in
       case of (maxfd == -1), we call select(0, ...), which is basically equal
       to sleep. */
    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) we call
       select(0, ...), which is basically equal to sleeping the timeout. On
       Windows we can't sleep via select without a dummy socket and instead
       we Sleep() for 100ms which is the minimum suggested value in the
       curl_multi_fdset() doc. */

#ifdef _WIN32
    if(maxfd == -1) {
      Sleep(100);
      rc = 0;
    }
    else
#endif
    {
      rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
    }

    switch(rc) {
    case -1:
Loading