]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
- Robert Iakobashvil added curl_multi_socket_action() to libcurl, which is a
authorDaniel Stenberg <daniel@haxx.se>
Mon, 16 Apr 2007 16:34:08 +0000 (16:34 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 16 Apr 2007 16:34:08 +0000 (16:34 +0000)
  function that deprecates the curl_multi_socket() function. Using the new
  function the application tell libcurl what action that was found in the
  socket that it passes in. This gives a significant performance boost as it
  allows libcurl to avoid a call to poll()/select() for every call to
  curl_multi_socket*().

CHANGES
RELEASE-NOTES
docs/libcurl/curl_multi_socket.3
include/curl/multi.h
lib/connect.c
lib/multi.c
lib/select.c
lib/select.h
lib/socks.c
lib/transfer.c
lib/urldata.h

diff --git a/CHANGES b/CHANGES
index 21d90e0bc5beba3f44678ce0611366e756801b43..79863cbe9124028fc87fdab98aa1c8171341faa0 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,14 @@
 
                                   Changelog
 
+Daniel S (16 April 2007)
+- Robert Iakobashvil added curl_multi_socket_action() to libcurl, which is a
+  function that deprecates the curl_multi_socket() function. Using the new
+  function the application tell libcurl what action that was found in the
+  socket that it passes in. This gives a significant performance boost as it
+  allows libcurl to avoid a call to poll()/select() for every call to
+  curl_multi_socket*().
+
 Daniel S (14 April 2007)
 - Jay Austin added "DH PARAMETERS" to the stunnel.pem certificate for the test
   suite to make stunnel run better in some (most?) environments.
index db4a2162220236945f4974c5ecbd25957c801d9e..1a6239a15dbdc5095d694497ec691b6fe7dc71ff 100644 (file)
@@ -11,7 +11,8 @@ Curl and libcurl 7.16.3
 
 This release includes the following changes:
  
- o 
+ o Added curl_multi_socket_action()
+ o Deprecated curl_multi_socket()
 
 This release includes the following bugfixes:
 
@@ -37,6 +38,6 @@ New curl mirrors:
 This release would not have looked like this without help, code, reports and
 advice from friends like these:
 
- Song Ma, Dan Fandrich, Yang Tse, Jay Austin
+ Song Ma, Dan Fandrich, Yang Tse, Jay Austin, Robert Iakobashvil
 
         Thanks! (and sorry if I forgot to mention someone)
index 9ad8257f11225dc443f909f54cc09dce1480702b..3cfd20b40a39c274ba9ea7962f42827908f0929d 100644 (file)
@@ -4,29 +4,40 @@
 .SH NAME
 curl_multi_socket \- reads/writes available data
 .SH SYNOPSIS
+.nf
 #include <curl/curl.h>
 
+CURLMcode curl_multi_socket_action(CURLM * multi_handle, 
+                                   curl_socket_t sockfd, int ev_bitmask,
+                                   int *running_handles);
+
 CURLMcode curl_multi_socket(CURLM * multi_handle, curl_socket_t sockfd,
                             int *running_handles);
 
 CURLMcode curl_multi_socket_all(CURLM *multi_handle,
                                 int *running_handles);
+.fi
 .SH DESCRIPTION
 Alternative versions of \fIcurl_multi_perform(3)\fP that allows the
-application to pass in one of the file descriptors/sockets that have been
-detected to have \&"action" on them and let libcurl perform. This allows
-libcurl to not have to scan through all possible file descriptors to check for
-action. When the application has detected action on a socket handled by
-libcurl, it should call \fIcurl_multi_socket(3)\fP with the \fBsockfd\fP
-argument set to the socket with the action.
+application to pass in the file descriptor/socket that has been detected to
+have \&"action" on it and let libcurl perform. This allows libcurl to not have
+to scan through all possible file descriptors to check for action. When the
+application has detected action on a socket handled by libcurl, it should call
+\fIcurl_multi_socket_action(3)\fP with the \fBsockfd\fP argument set to the
+socket with the action. When the events on a socket are known, they can be
+passed as an events bitmask \fBev_bitmask\fP by first setting \fBev_bitmask\fP
+to 0, and then adding using bitwise OR (|) any combination of events to be
+choosen from CURL_CSELECT_IN, CURL_CSELECT_OUT or CURL_CSELECT_ERR. When the
+events on a socket are unknown, pass 0 instead, and libcurl will test the
+descriptor internally.
 
 At return, the int \fBrunning_handles\fP points to will contain the number of
 still running easy handles within the multi handle. When this number reaches
 zero, all transfers are complete/done. Note that when you call
-\fIcurl_multi_socket(3)\fP on a specific socket and the counter decreases by
-one, it DOES NOT necessarily mean that this exact socket/transfer is the one
-that completed. Use \fIcurl_multi_info_read(3)\fP to figure out which easy
-handle that completed.
+\fIcurl_multi_socket_action(3)\fP on a specific socket and the counter
+decreases by one, it DOES NOT necessarily mean that this exact socket/transfer
+is the one that completed. Use \fIcurl_multi_info_read(3)\fP to figure out
+which easy handle that completed.
 
 The curl_multi_socket functions inform the application about updates in the
 socket (file descriptor) status by doing none, one or multiple calls to the
@@ -44,6 +55,10 @@ wait for socket actions \- at most \- before doing the timeout action: call
 the \fBcurl_multi_socket(3)\fP function with the \fBsockfd\fP argument set to
 CURL_SOCKET_TIMEOUT.
 
+Usage of \fIcurl_multi_socket(3)\fP is depricated, whereas the function is
+equivalent to \fIcurl_multi_socket_action(3)\fP, when \fBev_bitmask\fP is set 
+to 0.
+
 .SH "CALLBACK DETAILS"
 
 The socket \fBcallback\fP function uses a prototype like this
@@ -115,12 +130,15 @@ callback is called.
 
 7. Wait for action on any of libcurl's sockets
 
-8, When action happens, call curl_multi_socket() for the socket(s) that got
+8, When action happens, call curl_multi_socket_action() for the socket(s) that got
 action.
 
 9. Go back to step 6.
 .SH AVAILABILITY
-This function was added in libcurl 7.15.4, although not deemed stable yet.
+This function was added in libcurl 7.15.4, although deemed stablesince 7.16.0.
+
+\fIcurl_multi_socket(3)\fP is deprecated, use
+\fIcurl_multi_socket_action(3)\fP instead!
 .SH "SEE ALSO"
 .BR curl_multi_cleanup "(3), " curl_multi_init "(3), "
 .BR curl_multi_fdset "(3), " curl_multi_info_read "(3)"
index d2533728d919ddedc4ba5b80dfa5b4fd5bd362b4..5eab527aea6ec50ecdbbf0e4a4d0bca36d766a90 100644 (file)
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, 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
@@ -224,6 +224,10 @@ CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
 
 #define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
 
+#define CURL_CSELECT_IN   0x01
+#define CURL_CSELECT_OUT  0x02
+#define CURL_CSELECT_ERR  0x04
+
 typedef int (*curl_socket_callback)(CURL *easy,      /* easy handle */
                                     curl_socket_t s, /* socket */
                                     int what,        /* see above */
@@ -249,9 +253,21 @@ typedef int (*curl_multi_timer_callback)(CURLM *multi,    /* multi handle */
 CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
                                         int *running_handles);
 
+CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle,
+                                               curl_socket_t s,
+                                               int ev_bitmask,
+                                               int *running_handles);
+
 CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle,
                                             int *running_handles);
 
+#ifndef CURL_ALLOW_OLD_MULTI_SOCKET
+/* This macro below was added in 7.16.3 to push users who recompile to use
+   the new curl_multi_socket_action() instead of the old curl_multi_socket()
+*/
+#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z)
+#endif
+
 /*
  * Name:    curl_multi_timeout()
  *
index 95791cf5ddc3d5fcf51fa57891fe8c7e11a9ee42..dd67638fff0409597760c0b31e2b6e78ce78a55f 100644 (file)
@@ -206,7 +206,7 @@ int waitconnect(curl_socket_t sockfd, /* socket */
     /* timeout, no connect today */
     return WAITCONN_TIMEOUT;
 
-  if(rc & CSELECT_ERR)
+  if(rc & CURL_CSELECT_ERR)
     /* error condition caught */
     return WAITCONN_FDSET_ERROR;
 
index 530357392fb8609ba132801b7601ff840b891dee..76614c7608a28ba0169e26be0607c3252da3c658 100644 (file)
@@ -1661,6 +1661,7 @@ static void singlesocket(struct Curl_multi *multi,
 static CURLMcode multi_socket(struct Curl_multi *multi,
                               bool checkall,
                               curl_socket_t s,
+                              int ev_bitmask,
                               int *running_handles)
 {
   CURLMcode result = CURLM_OK;
@@ -1698,8 +1699,14 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
       /* bad bad bad bad bad bad bad */
       return CURLM_INTERNAL_ERROR;
 
+    if (data->set.one_easy->easy_conn)  /* set socket event bitmask */
+      data->set.one_easy->easy_conn->cselect_bits = ev_bitmask;
+
     result = multi_runsingle(multi, data->set.one_easy);
 
+    if (data->set.one_easy->easy_conn)
+      data->set.one_easy->easy_conn->cselect_bits = 0;
+
     if(result == CURLM_OK)
       /* get the socket(s) and check if the state has been changed since
          last */
@@ -1791,12 +1798,24 @@ CURLMcode curl_multi_setopt(CURLM *multi_handle,
   return res;
 }
 
+/* we define curl_multi_socket() in the public multi.h header */
+#undef curl_multi_socket
 
 CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
                             int *running_handles)
 {
   CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s,
-                                  running_handles);
+                                  0, running_handles);
+  if (CURLM_OK == result)
+    update_timer((struct Curl_multi *)multi_handle);
+  return result;
+}
+
+CURLMcode curl_multi_socket_action(CURLM *multi_handle, curl_socket_t s,
+                                     int ev_bitmask, int *running_handles)
+{
+  CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s,
+                                  ev_bitmask, running_handles);
   if (CURLM_OK == result)
     update_timer((struct Curl_multi *)multi_handle);
   return result;
@@ -1806,7 +1825,7 @@ CURLMcode curl_multi_socket_all(CURLM *multi_handle, int *running_handles)
 
 {
   CURLMcode result = multi_socket((struct Curl_multi *)multi_handle,
-                                  TRUE, CURL_SOCKET_BAD, running_handles);
+                                  TRUE, CURL_SOCKET_BAD, 0, running_handles);
   if (CURLM_OK == result)
     update_timer((struct Curl_multi *)multi_handle);
   return result;
index 2af14eb362212350c4d8739f3c03f4c7a73fd346..1cc819a2a3dc4e38d06c08dac399f81ca98ca9ee 100644 (file)
@@ -161,7 +161,7 @@ static int wait_ms(int timeout_ms)
  * Return values:
  *   -1 = system call error or fd >= FD_SETSIZE
  *    0 = timeout
- *    CSELECT_IN | CSELECT_OUT | CSELECT_ERR
+ *    CURL_CSELECT_IN | CURL_CSELECT_OUT | CURL_CSELECT_ERR
  */
 int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd, int timeout_ms)
 {
@@ -223,16 +223,16 @@ int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd, int timeout_m
   num = 0;
   if (readfd != CURL_SOCKET_BAD) {
     if (pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
-      ret |= CSELECT_IN;
+      ret |= CURL_CSELECT_IN;
     if (pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
-      ret |= CSELECT_ERR;
+      ret |= CURL_CSELECT_ERR;
     num++;
   }
   if (writefd != CURL_SOCKET_BAD) {
     if (pfd[num].revents & (POLLWRNORM|POLLOUT))
-      ret |= CSELECT_OUT;
+      ret |= CURL_CSELECT_OUT;
     if (pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL))
-      ret |= CSELECT_ERR;
+      ret |= CURL_CSELECT_ERR;
   }
 
   return ret;
@@ -279,15 +279,15 @@ int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd, int timeout_m
   ret = 0;
   if (readfd != CURL_SOCKET_BAD) {
     if (FD_ISSET(readfd, &fds_read))
-      ret |= CSELECT_IN;
+      ret |= CURL_CSELECT_IN;
     if (FD_ISSET(readfd, &fds_err))
-      ret |= CSELECT_ERR;
+      ret |= CURL_CSELECT_ERR;
   }
   if (writefd != CURL_SOCKET_BAD) {
     if (FD_ISSET(writefd, &fds_write))
-      ret |= CSELECT_OUT;
+      ret |= CURL_CSELECT_OUT;
     if (FD_ISSET(writefd, &fds_err))
-      ret |= CSELECT_ERR;
+      ret |= CURL_CSELECT_ERR;
   }
 
   return ret;
index 5a62a6fd8981043abf8f0dbf7ec3d9887466d71b..77b3e915f324569018e2f856197d0d071387e642 100644 (file)
@@ -76,11 +76,8 @@ struct pollfd
 #define POLLRDBAND POLLPRI
 #endif
 
-#define CSELECT_IN   0x01
-#define CSELECT_OUT  0x02
-#define CSELECT_ERR  0x04
-
-int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd, int timeout_ms);
+int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd,
+                      int timeout_ms);
 
 int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);
 
index 1157b960cabc9f6bda324d495bcd766aefd4ad99..6b95e752d61dc0e4bdded9ffe828a7fe18850c57 100644 (file)
@@ -383,7 +383,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
     return CURLE_OPERATION_TIMEDOUT;
   }
 
-  if(result & CSELECT_ERR) {
+  if(result & CURL_CSELECT_ERR) {
     failf(conn->data, "SOCKS5: error occured during connection");
     return CURLE_COULDNT_CONNECT;
   }
@@ -415,7 +415,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
     return CURLE_OPERATION_TIMEDOUT;
   }
 
-  if(result & CSELECT_ERR) {
+  if(result & CURL_CSELECT_ERR) {
     failf(conn->data, "SOCKS5 read error occured");
     return CURLE_RECV_ERROR;
   }
index b70f3b5094f6077bc4fc1c2e0070577f807f2b2c..52b4c8966b9604866c8db5f60f3180491733ba07 100644 (file)
@@ -314,9 +314,10 @@ CURLcode Curl_readwrite(struct connectdata *conn,
 
   curl_socket_t fd_read;
   curl_socket_t fd_write;
-  int select_res;
-
   curl_off_t contentlength;
+  int select_res = conn->cselect_bits;
+
+  conn->cselect_bits = 0;
 
   /* only use the proper socket if the *_HOLD bit is not set simultaneously as
      then we are in rate limiting state in that transfer direction */
@@ -331,8 +332,12 @@ CURLcode Curl_readwrite(struct connectdata *conn,
   else
     fd_write = CURL_SOCKET_BAD;
 
-  select_res = Curl_socket_ready(fd_read, fd_write, 0);
-  if(select_res == CSELECT_ERR) {
+   if (!select_res) { /* Call for select()/poll() only, if read/write/error 
+                         status is not known. */
+       select_res = Curl_socket_ready(fd_read, fd_write, 0);
+   }
+  if(select_res == CURL_CSELECT_ERR) {
     failf(data, "select/poll returned error");
     return CURLE_SEND_ERROR;
   }
@@ -342,7 +347,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
        the stream was rewound (in which case we have data in a
        buffer) */
     if((k->keepon & KEEP_READ) &&
-       ((select_res & CSELECT_IN) || conn->bits.stream_was_rewound)) {
+       ((select_res & CURL_CSELECT_IN) || conn->bits.stream_was_rewound)) {
       /* read */
       bool is_empty_data = FALSE;
 
@@ -1350,7 +1355,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
 
     /* If we still have writing to do, we check if we have a writable
        socket. */
-    if((k->keepon & KEEP_WRITE) && (select_res & CSELECT_OUT)) {
+    if((k->keepon & KEEP_WRITE) && (select_res & CURL_CSELECT_OUT)) {
       /* write */
 
       int i, si;
index 4199155695b98dc7d5e29068fc5dc0d9a4fb072f..b129ca7081146fdf80926ac2645eb5c917149371 100644 (file)
@@ -900,6 +900,8 @@ struct connectdata {
   union {
     struct ftp_conn ftpc;
   } proto;
+
+  int cselect_bits; /* bitmask of socket events */
 };
 
 /* The end of connectdata. */