XRootD
XrdTpcCurlMulti.cc
Go to the documentation of this file.
1 
2 #include "XrdTpcCurlMulti.hh"
3 
4 #include <cerrno>
5 #include <sys/select.h>
6 
7 #ifndef HAVE_CURL_MULTI_WAIT
8 CURLMcode curl_multi_wait_impl(CURLM *multi_handle, int timeout_ms, int *numfds) {
9  int max_fds = FD_SETSIZE;
10  fd_set read_fd_set[FD_SETSIZE];
11  fd_set write_fd_set[FD_SETSIZE];
12  fd_set exc_fd_set[FD_SETSIZE];
13 
14  FD_ZERO(read_fd_set);
15  FD_ZERO(write_fd_set);
16  FD_ZERO(exc_fd_set);
17 
18  CURLMcode fdset_result = curl_multi_fdset(multi_handle, read_fd_set,
19  write_fd_set, exc_fd_set, &max_fds);
20 
21  if (CURLM_OK != fdset_result) {
22  return fdset_result;
23  }
24 
25  struct timeval timeout;
26  if (max_fds == -1) {
27  // Per the curl documentation, this case "is because libcurl currently
28  // does something that isn't possible for your application to monitor
29  // with a socket and unfortunately you can then not know exactly when
30  // the current action is completed using select()."
31  //
32  // We use their recommendation to sleep for 100ms.
33  max_fds = 0;
34  timeout.tv_sec = 0;
35  timeout.tv_usec = 100*1000;
36  } else {
37  max_fds ++;
38  timeout.tv_sec = timeout_ms / 1000;
39  timeout.tv_usec = (timeout_ms % 1000) * 1000;
40  }
41  int select_result = select(max_fds, read_fd_set, write_fd_set, exc_fd_set,
42  &timeout);
43 
44  if (select_result >= 0) {
45  *numfds = select_result;
46  return CURLM_OK;
47  }
48  if (errno == EINTR) {
49  return CURLM_OK;
50  }
51  if (errno == ENOMEM) {
52  return CURLM_OUT_OF_MEMORY;
53  }
54  if (errno == EBADF) {
55  return CURLM_BAD_SOCKET;
56  }
57  return CURLM_INTERNAL_ERROR;
58 }
59 #endif
60 
CURLMcode curl_multi_wait_impl(CURLM *multi_handle, int timeout_ms, int *numfds)