Commit de24d7bd authored by Sara Golemon's avatar Sara Golemon Committed by Daniel Stenberg
Browse files

multi: add curl_multi_wait()

/*
 * Name:     curl_multi_wait()
 *
 * Desc:     Poll on all fds within a CURLM set as well as any
 *           additional fds passed to the function.
 *
 * Returns:  CURLMcode type, general multi error code.
 */
CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle,
                                      struct curl_waitfd extra_fds[],
                                      unsigned int extra_nfds,
                                      int timeout_ms);
parent 2f6e1a8c
Loading
Loading
Loading
Loading
+27 −1
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 1998 - 2012, 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
@@ -89,6 +89,19 @@ struct CURLMsg {
};
typedef struct CURLMsg CURLMsg;

/* Based on poll(2) structure and values.
 * We don't use pollfd and POLL* constants explicitly
 * to cover platforms without poll(). */
#define CURL_WAIT_POLLIN    0x0001
#define CURL_WAIT_POLLPRI   0x0002
#define CURL_WAIT_POLLOUT   0x0004

struct curl_waitfd {
  curl_socket_t fd;
  short events;
  short revents; /* not supported yet */
};

/*
 * Name:    curl_multi_init()
 *
@@ -133,6 +146,19 @@ CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
                                       fd_set *exc_fd_set,
                                       int *max_fd);

/*
 * Name:     curl_multi_wait()
 *
 * Desc:     Poll on all fds within a CURLM set as well as any
 *           additional fds passed to the function.
 *
 * Returns:  CURLMcode type, general multi error code.
 */
CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle,
                                      struct curl_waitfd extra_fds[],
                                      unsigned int extra_nfds,
                                      int timeout_ms);

 /*
  * Name:    curl_multi_perform()
  *
+87 −0
Original line number Diff line number Diff line
@@ -941,6 +941,93 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle,
  return CURLM_OK;
}

CURLMcode curl_multi_wait(CURLM *multi_handle,
                          struct curl_waitfd extra_fds[],
                          unsigned int extra_nfds,
                          int timeout_ms)
{
  struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
  struct Curl_one_easy *easy;
  curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
  int bitmap;
  unsigned int i;
  unsigned int nfds = extra_nfds;
  struct pollfd *ufds;

  if(!GOOD_MULTI_HANDLE(multi))
    return CURLM_BAD_HANDLE;

  /* Count up how many fds we have from the multi handle */
  easy=multi->easy.next;
  while(easy != &multi->easy) {
    bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE);

    for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
      curl_socket_t s = CURL_SOCKET_BAD;

      if(bitmap & GETSOCK_READSOCK(i)) {
        ++nfds;
        s = sockbunch[i];
      }
      if(bitmap & GETSOCK_WRITESOCK(i)) {
        ++nfds;
        s = sockbunch[i];
      }
      if(s == CURL_SOCKET_BAD) {
        break;
      }
    }

    easy = easy->next; /* check next handle */
  }

  ufds = (struct pollfd *)malloc(nfds * sizeof(struct pollfd));
  nfds = 0;

  /* Add the curl handles to our pollfds first */
  easy=multi->easy.next;
  while(easy != &multi->easy) {
    bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE);

    for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
      curl_socket_t s = CURL_SOCKET_BAD;

      if(bitmap & GETSOCK_READSOCK(i)) {
        ufds[nfds].fd = sockbunch[i];
        ufds[nfds].events = POLLIN;
        ++nfds;
        s = sockbunch[i];
      }
      if(bitmap & GETSOCK_WRITESOCK(i)) {
        ufds[nfds].fd = sockbunch[i];
        ufds[nfds].events = POLLOUT;
        ++nfds;
        s = sockbunch[i];
      }
      if(s == CURL_SOCKET_BAD) {
        break;
      }
    }

    easy = easy->next; /* check next handle */
  }

  /* Add external file descriptions from poll-like struct curl_waitfd */
  for(i = 0; i < extra_nfds; i++) {
    ufds[nfds].fd = extra_fds[i].fd;
    ufds[nfds].events = (short) (
      ((extra_fds[i].events & CURL_WAIT_POLLIN)  ? POLLIN  : 0) |
      ((extra_fds[i].events & CURL_WAIT_POLLPRI) ? POLLPRI : 0) |
      ((extra_fds[i].events & CURL_WAIT_POLLOUT) ? POLLOUT : 0) );
    ++nfds;
  }

  /* wait... */
  Curl_poll(ufds, nfds, timeout_ms);
  free(ufds);
  return CURLM_OK;
}

static CURLMcode multi_runsingle(struct Curl_multi *multi,
                                 struct timeval now,
                                 struct Curl_one_easy *easy)