From 76627b322e369c209c60863b9e1f05e3ce02953d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 16 Apr 2007 16:34:08 +0000 Subject: - 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*(). --- lib/connect.c | 2 +- lib/multi.c | 23 +++++++++++++++++++++-- lib/select.c | 18 +++++++++--------- lib/select.h | 7 ++----- lib/socks.c | 4 ++-- lib/transfer.c | 17 +++++++++++------ lib/urldata.h | 2 ++ 7 files changed, 48 insertions(+), 25 deletions(-) (limited to 'lib') diff --git a/lib/connect.c b/lib/connect.c index 95791cf5d..dd67638ff 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -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; diff --git a/lib/multi.c b/lib/multi.c index 530357392..76614c760 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -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; diff --git a/lib/select.c b/lib/select.c index 2af14eb36..1cc819a2a 100644 --- a/lib/select.c +++ b/lib/select.c @@ -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; diff --git a/lib/select.h b/lib/select.h index 5a62a6fd8..77b3e915f 100644 --- a/lib/select.h +++ b/lib/select.h @@ -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); diff --git a/lib/socks.c b/lib/socks.c index 1157b960c..6b95e752d 100644 --- a/lib/socks.c +++ b/lib/socks.c @@ -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; } diff --git a/lib/transfer.c b/lib/transfer.c index b70f3b509..52b4c8966 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -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; diff --git a/lib/urldata.h b/lib/urldata.h index 419915569..b129ca708 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -900,6 +900,8 @@ struct connectdata { union { struct ftp_conn ftpc; } proto; + + int cselect_bits; /* bitmask of socket events */ }; /* The end of connectdata. */ -- cgit v1.2.3