mirror of
https://github.com/curl/curl.git
synced 2026-04-14 22:21:41 +03:00
lib: replace getsock() logic with pollsets
`getsock()` calls operated on a global limit that could not be configure beyond 16 sockets. This is no longer adequate with the new happy eyeballing strategy. Instead, do the following: - make `struct easy_pollset` dynamic. Starting with a minimal room for two sockets, the very common case, allow it to grow on demand. - replace all protocol handler getsock() calls with pollsets and a CURLcode to return failures - add CURLcode return for all connection filter `adjust_pollset()` callbacks, since they too can now fail. - use appropriately in multi.c and multi_ev.c - fix unit2600 to trigger pollset growth Closes #18164
This commit is contained in:
parent
c85c2b7be7
commit
5b80b4c012
54 changed files with 1002 additions and 873 deletions
|
|
@ -273,15 +273,15 @@ static void async_ares_cleanup(struct Curl_easy *data)
|
|||
}
|
||||
|
||||
/*
|
||||
* Curl_async_getsock() is called when someone from the outside world
|
||||
* Curl_async_pollset() is called when someone from the outside world
|
||||
* (using curl_multi_fdset()) wants to get our fd_set setup.
|
||||
*/
|
||||
|
||||
int Curl_async_getsock(struct Curl_easy *data, curl_socket_t *socks)
|
||||
CURLcode Curl_async_pollset(struct Curl_easy *data, struct easy_pollset *ps)
|
||||
{
|
||||
struct async_ares_ctx *ares = &data->state.async.ares;
|
||||
DEBUGASSERT(ares->channel);
|
||||
return Curl_ares_getsock(data, ares->channel, socks);
|
||||
return Curl_ares_pollset(data, ares->channel, ps);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@
|
|||
#endif
|
||||
|
||||
/*
|
||||
* Curl_ares_getsock() is called when the outside world (using
|
||||
* Curl_ares_pollset() is called when the outside world (using
|
||||
* curl_multi_fdset()) wants to get our fd_set setup and we are talking with
|
||||
* ares. The caller must make sure that this function is only called when we
|
||||
* have a working ares channel.
|
||||
|
|
@ -78,18 +78,38 @@
|
|||
* Returns: sockets-in-use-bitmap
|
||||
*/
|
||||
|
||||
int Curl_ares_getsock(struct Curl_easy *data,
|
||||
ares_channel channel,
|
||||
curl_socket_t *socks)
|
||||
|
||||
CURLcode Curl_ares_pollset(struct Curl_easy *data,
|
||||
ares_channel channel,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct timeval maxtime = { CURL_TIMEOUT_RESOLVE, 0 };
|
||||
struct timeval timebuf;
|
||||
int max = ares_getsock(channel,
|
||||
(ares_socket_t *)socks, MAX_SOCKSPEREASYHANDLE);
|
||||
struct timeval *timeout = ares_timeout(channel, &maxtime, &timebuf);
|
||||
timediff_t milli = curlx_tvtoms(timeout);
|
||||
curl_socket_t sockets[16]; /* ARES documented limit */
|
||||
unsigned int bitmap, i;
|
||||
struct timeval *timeout;
|
||||
timediff_t milli;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
bitmap = ares_getsock(channel, (ares_socket_t *)sockets,
|
||||
CURL_ARRAYSIZE(sockets));
|
||||
for(i = 0; i < CURL_ARRAYSIZE(sockets); ++i) {
|
||||
int flags = 0;
|
||||
if(ARES_GETSOCK_READABLE(bitmap, i))
|
||||
flags |= CURL_POLL_IN;
|
||||
if(ARES_GETSOCK_WRITABLE(bitmap, i))
|
||||
flags |= CURL_POLL_OUT;
|
||||
if(!flags)
|
||||
break;
|
||||
result = Curl_pollset_change(data, ps, sockets[i], flags, 0);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
timeout = ares_timeout(channel, &maxtime, &timebuf);
|
||||
milli = curlx_tvtoms(timeout);
|
||||
Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
|
||||
return max;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@
|
|||
#include "url.h"
|
||||
#include "multiif.h"
|
||||
#include "curl_threads.h"
|
||||
#include "select.h"
|
||||
#include "strdup.h"
|
||||
|
||||
#ifdef USE_ARES
|
||||
|
|
@ -629,33 +630,25 @@ CURLcode Curl_async_is_resolved(struct Curl_easy *data,
|
|||
}
|
||||
}
|
||||
|
||||
int Curl_async_getsock(struct Curl_easy *data, curl_socket_t *socks)
|
||||
CURLcode Curl_async_pollset(struct Curl_easy *data, struct easy_pollset *ps)
|
||||
{
|
||||
struct async_thrdd_ctx *thrdd = &data->state.async.thrdd;
|
||||
int ret_val = 0;
|
||||
#if !defined(CURL_DISABLE_SOCKETPAIR) || defined(USE_HTTPSRR_ARES)
|
||||
int socketi = 0;
|
||||
#else
|
||||
(void)socks;
|
||||
#endif
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
#ifdef USE_HTTPSRR_ARES
|
||||
if(thrdd->rr.channel) {
|
||||
ret_val = Curl_ares_getsock(data, thrdd->rr.channel, socks);
|
||||
for(socketi = 0; socketi < (MAX_SOCKSPEREASYHANDLE - 1); socketi++)
|
||||
if(!ARES_GETSOCK_READABLE(ret_val, socketi) &&
|
||||
!ARES_GETSOCK_WRITABLE(ret_val, socketi))
|
||||
break;
|
||||
result = Curl_ares_pollset(data, thrdd->rr.channel, ps);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
if(!thrdd->addr)
|
||||
return ret_val;
|
||||
return result;
|
||||
|
||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
||||
if(thrdd->addr) {
|
||||
/* return read fd to client for polling the DNS resolution status */
|
||||
socks[socketi] = thrdd->addr->sock_pair[0];
|
||||
ret_val |= GETSOCK_READSOCK(socketi);
|
||||
result = Curl_pollset_add_in(data, ps, thrdd->addr->sock_pair[0]);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
|
@ -673,7 +666,7 @@ int Curl_async_getsock(struct Curl_easy *data, curl_socket_t *socks)
|
|||
Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
|
|
|
|||
14
lib/asyn.h
14
lib/asyn.h
|
|
@ -37,6 +37,7 @@ struct Curl_dns_entry;
|
|||
struct addrinfo;
|
||||
struct hostent;
|
||||
struct connectdata;
|
||||
struct easy_pollset;
|
||||
|
||||
#if defined(CURLRES_ARES) && defined(CURLRES_THREADED)
|
||||
#error cannot have both CURLRES_ARES and CURLRES_THREADED defined
|
||||
|
|
@ -70,15 +71,15 @@ void Curl_async_global_cleanup(void);
|
|||
*/
|
||||
CURLcode Curl_async_get_impl(struct Curl_easy *easy, void **impl);
|
||||
|
||||
/* Curl_async_getsock()
|
||||
/* Curl_async_pollset()
|
||||
*
|
||||
* This function is called from the Curl_multi_getsock() function. 'sock' is a
|
||||
* This function is called from the Curl_multi_pollset() function. 'sock' is a
|
||||
* pointer to an array to hold the file descriptors, with 'numsock' being the
|
||||
* size of that array (in number of entries). This function is supposed to
|
||||
* return bitmask indicating what file descriptors (referring to array indexes
|
||||
* in the 'sock' array) to wait for, read/write.
|
||||
*/
|
||||
int Curl_async_getsock(struct Curl_easy *data, curl_socket_t *sock);
|
||||
CURLcode Curl_async_pollset(struct Curl_easy *data, struct easy_pollset *ps);
|
||||
|
||||
/*
|
||||
* Curl_async_is_resolved()
|
||||
|
|
@ -127,9 +128,10 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
|
|||
/* common functions for c-ares and threaded resolver with HTTPSRR */
|
||||
#include <ares.h>
|
||||
|
||||
int Curl_ares_getsock(struct Curl_easy *data,
|
||||
ares_channel channel,
|
||||
curl_socket_t *socks);
|
||||
CURLcode Curl_ares_pollset(struct Curl_easy *data,
|
||||
ares_channel channel,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
int Curl_ares_perform(ares_channel channel,
|
||||
timediff_t timeout_ms);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -682,11 +682,12 @@ out:
|
|||
return result;
|
||||
}
|
||||
|
||||
static void cf_h1_proxy_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
static CURLcode cf_h1_proxy_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct h1_tunnel_state *ts = cf->ctx;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(!cf->connected) {
|
||||
/* If we are not connected, but the filter "below" is
|
||||
|
|
@ -698,13 +699,14 @@ static void cf_h1_proxy_adjust_pollset(struct Curl_cfilter *cf,
|
|||
response headers or if we are still sending the request, wait
|
||||
for write. */
|
||||
if(tunnel_want_send(ts))
|
||||
Curl_pollset_set_out_only(data, ps, sock);
|
||||
result = Curl_pollset_set_out_only(data, ps, sock);
|
||||
else
|
||||
Curl_pollset_set_in_only(data, ps, sock);
|
||||
result = Curl_pollset_set_in_only(data, ps, sock);
|
||||
}
|
||||
else
|
||||
Curl_pollset_set_out_only(data, ps, sock);
|
||||
result = Curl_pollset_set_out_only(data, ps, sock);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void cf_h1_proxy_destroy(struct Curl_cfilter *cf,
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#include "http_proxy.h"
|
||||
#include "multiif.h"
|
||||
#include "sendf.h"
|
||||
#include "select.h"
|
||||
#include "cf-h2-proxy.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
|
|
@ -1202,14 +1203,15 @@ static bool cf_h2_proxy_data_pending(struct Curl_cfilter *cf,
|
|||
return cf->next ? cf->next->cft->has_data_pending(cf->next, data) : FALSE;
|
||||
}
|
||||
|
||||
static void cf_h2_proxy_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
static CURLcode cf_h2_proxy_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct cf_h2_proxy_ctx *ctx = cf->ctx;
|
||||
struct cf_call_data save;
|
||||
curl_socket_t sock = Curl_conn_cf_get_socket(cf, data);
|
||||
bool want_recv, want_send;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(!cf->connected && ctx->h2) {
|
||||
want_send = nghttp2_session_want_write(ctx->h2) ||
|
||||
|
|
@ -1234,9 +1236,9 @@ static void cf_h2_proxy_adjust_pollset(struct Curl_cfilter *cf,
|
|||
!Curl_bufq_is_empty(&ctx->outbufq) ||
|
||||
!Curl_bufq_is_empty(&ctx->tunnel.sendbuf);
|
||||
|
||||
Curl_pollset_set(data, ps, sock, want_recv, want_send);
|
||||
CURL_TRC_CF(data, cf, "adjust_pollset, want_recv=%d want_send=%d",
|
||||
want_recv, want_send);
|
||||
result = Curl_pollset_set(data, ps, sock, want_recv, want_send);
|
||||
CURL_TRC_CF(data, cf, "adjust_pollset, want_recv=%d want_send=%d -> %d",
|
||||
want_recv, want_send, result);
|
||||
CF_DATA_RESTORE(cf, save);
|
||||
}
|
||||
else if(ctx->sent_goaway && !cf->shutdown) {
|
||||
|
|
@ -1246,11 +1248,12 @@ static void cf_h2_proxy_adjust_pollset(struct Curl_cfilter *cf,
|
|||
!Curl_bufq_is_empty(&ctx->outbufq) ||
|
||||
!Curl_bufq_is_empty(&ctx->tunnel.sendbuf);
|
||||
want_recv = nghttp2_session_want_read(ctx->h2);
|
||||
Curl_pollset_set(data, ps, sock, want_recv, want_send);
|
||||
CURL_TRC_CF(data, cf, "adjust_pollset, want_recv=%d want_send=%d",
|
||||
want_recv, want_send);
|
||||
result = Curl_pollset_set(data, ps, sock, want_recv, want_send);
|
||||
CURL_TRC_CF(data, cf, "adjust_pollset, want_recv=%d want_send=%d -> %d",
|
||||
want_recv, want_send, result);
|
||||
CF_DATA_RESTORE(cf, save);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode h2_handle_tunnel_close(struct Curl_cfilter *cf,
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "cf-haproxy.h"
|
||||
#include "curl_trc.h"
|
||||
#include "multiif.h"
|
||||
#include "select.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
|
|
@ -178,15 +179,17 @@ static void cf_haproxy_close(struct Curl_cfilter *cf,
|
|||
cf->next->cft->do_close(cf->next, data);
|
||||
}
|
||||
|
||||
static void cf_haproxy_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
static CURLcode cf_haproxy_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
if(cf->next->connected && !cf->connected) {
|
||||
/* If we are not connected, but the filter "below" is
|
||||
* and not waiting on something, we are sending. */
|
||||
Curl_pollset_set_out_only(data, ps, Curl_conn_cf_get_socket(cf, data));
|
||||
return Curl_pollset_set_out_only(
|
||||
data, ps, Curl_conn_cf_get_socket(cf, data));
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
struct Curl_cftype Curl_cft_haproxy = {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "multiif.h"
|
||||
#include "cf-https-connect.h"
|
||||
#include "http2.h"
|
||||
#include "select.h"
|
||||
#include "vquic/vquic.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
|
|
@ -426,22 +427,24 @@ static CURLcode cf_hc_shutdown(struct Curl_cfilter *cf,
|
|||
return result;
|
||||
}
|
||||
|
||||
static void cf_hc_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
static CURLcode cf_hc_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
if(!cf->connected) {
|
||||
struct cf_hc_ctx *ctx = cf->ctx;
|
||||
size_t i;
|
||||
|
||||
for(i = 0; i < ctx->baller_count; i++) {
|
||||
for(i = 0; (i < ctx->baller_count) && !result; i++) {
|
||||
struct cf_hc_baller *b = &ctx->ballers[i];
|
||||
if(!cf_hc_baller_is_active(b))
|
||||
continue;
|
||||
Curl_conn_cf_adjust_pollset(b->cf, data, ps);
|
||||
result = Curl_conn_cf_adjust_pollset(b->cf, data, ps);
|
||||
}
|
||||
CURL_TRC_CF(data, cf, "adjust_pollset -> %d socks", ps->num);
|
||||
CURL_TRC_CF(data, cf, "adjust_pollset -> %d, %d socks", result, ps->n);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool cf_hc_data_pending(struct Curl_cfilter *cf,
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@
|
|||
#include "curl_trc.h"
|
||||
#include "multiif.h"
|
||||
#include "progress.h"
|
||||
#include "select.h"
|
||||
#include "vquic/vquic.h" /* for quic cfilters */
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
|
|
@ -533,16 +534,18 @@ static CURLcode cf_ip_ballers_shutdown(struct cf_ip_ballers *bs,
|
|||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void cf_ip_ballers_pollset(struct cf_ip_ballers *bs,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
static CURLcode cf_ip_ballers_pollset(struct cf_ip_ballers *bs,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct cf_ip_attempt *a;
|
||||
for(a = bs->running; a; a = a->next) {
|
||||
CURLcode result = CURLE_OK;
|
||||
for(a = bs->running; a && !result; a = a->next) {
|
||||
if(a->result)
|
||||
continue;
|
||||
Curl_conn_cf_adjust_pollset(a->cf, data, ps);
|
||||
result = Curl_conn_cf_adjust_pollset(a->cf, data, ps);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool cf_ip_ballers_pending(struct cf_ip_ballers *bs,
|
||||
|
|
@ -713,16 +716,18 @@ static CURLcode cf_ip_happy_shutdown(struct Curl_cfilter *cf,
|
|||
return result;
|
||||
}
|
||||
|
||||
static void cf_ip_happy_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
static CURLcode cf_ip_happy_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct cf_ip_happy_ctx *ctx = cf->ctx;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(!cf->connected) {
|
||||
cf_ip_ballers_pollset(&ctx->ballers, data, ps);
|
||||
CURL_TRC_CF(data, cf, "adjust_pollset -> %d socks", ps->num);
|
||||
result = cf_ip_ballers_pollset(&ctx->ballers, data, ps);
|
||||
CURL_TRC_CF(data, cf, "adjust_pollset -> %d, %d socks", result, ps->n);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode cf_ip_happy_connect(struct Curl_cfilter *cf,
|
||||
|
|
|
|||
|
|
@ -1376,11 +1376,12 @@ out:
|
|||
return result;
|
||||
}
|
||||
|
||||
static void cf_socket_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
static CURLcode cf_socket_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct cf_socket_ctx *ctx = cf->ctx;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(ctx->sock != CURL_SOCKET_BAD) {
|
||||
/* A listening socket filter needs to be connected before the accept
|
||||
|
|
@ -1388,21 +1389,22 @@ static void cf_socket_adjust_pollset(struct Curl_cfilter *cf,
|
|||
* FTP no longer does the socket checks and accept calls and delegates
|
||||
* all that to the filter. */
|
||||
if(ctx->listening) {
|
||||
Curl_pollset_set_in_only(data, ps, ctx->sock);
|
||||
result = Curl_pollset_set_in_only(data, ps, ctx->sock);
|
||||
CURL_TRC_CF(data, cf, "adjust_pollset, listening, POLLIN fd=%"
|
||||
FMT_SOCKET_T, ctx->sock);
|
||||
}
|
||||
else if(!cf->connected) {
|
||||
Curl_pollset_set_out_only(data, ps, ctx->sock);
|
||||
result = Curl_pollset_set_out_only(data, ps, ctx->sock);
|
||||
CURL_TRC_CF(data, cf, "adjust_pollset, !connected, POLLOUT fd=%"
|
||||
FMT_SOCKET_T, ctx->sock);
|
||||
}
|
||||
else if(!ctx->active) {
|
||||
Curl_pollset_add_in(data, ps, ctx->sock);
|
||||
result = Curl_pollset_add_in(data, ps, ctx->sock);
|
||||
CURL_TRC_CF(data, cf, "adjust_pollset, !active, POLLIN fd=%"
|
||||
FMT_SOCKET_T, ctx->sock);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
|
|
|
|||
211
lib/cfilters.c
211
lib/cfilters.c
|
|
@ -67,14 +67,15 @@ CURLcode Curl_cf_def_shutdown(struct Curl_cfilter *cf,
|
|||
static void conn_report_connect_stats(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
||||
void Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
CURLcode Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
/* NOP */
|
||||
(void)cf;
|
||||
(void)data;
|
||||
(void)ps;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
|
||||
|
|
@ -469,6 +470,7 @@ CURLcode Curl_conn_connect(struct Curl_easy *data,
|
|||
{
|
||||
#define CF_CONN_NUM_POLLS_ON_STACK 5
|
||||
struct pollfd a_few_on_stack[CF_CONN_NUM_POLLS_ON_STACK];
|
||||
struct easy_pollset ps;
|
||||
struct curl_pollfds cpfds;
|
||||
struct Curl_cfilter *cf;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
|
@ -486,6 +488,7 @@ CURLcode Curl_conn_connect(struct Curl_easy *data,
|
|||
if(*done)
|
||||
return CURLE_OK;
|
||||
|
||||
Curl_pollset_init(&ps);
|
||||
Curl_pollfds_init(&cpfds, a_few_on_stack, CF_CONN_NUM_POLLS_ON_STACK);
|
||||
while(!*done) {
|
||||
if(Curl_conn_needs_flush(data, sockindex)) {
|
||||
|
|
@ -523,7 +526,6 @@ CURLcode Curl_conn_connect(struct Curl_easy *data,
|
|||
/* check allowed time left */
|
||||
const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
|
||||
curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
|
||||
struct easy_pollset ps;
|
||||
int rc;
|
||||
|
||||
if(timeout_ms < 0) {
|
||||
|
|
@ -534,12 +536,14 @@ CURLcode Curl_conn_connect(struct Curl_easy *data,
|
|||
}
|
||||
|
||||
CURL_TRC_CF(data, cf, "Curl_conn_connect(block=1), do poll");
|
||||
Curl_pollset_reset(&ps);
|
||||
Curl_pollfds_reset(&cpfds);
|
||||
memset(&ps, 0, sizeof(ps));
|
||||
/* In general, we want to send after connect, wait on that. */
|
||||
if(sockfd != CURL_SOCKET_BAD)
|
||||
Curl_pollset_set_out_only(data, &ps, sockfd);
|
||||
Curl_conn_adjust_pollset(data, data->conn, &ps);
|
||||
result = Curl_conn_adjust_pollset(data, data->conn, &ps);
|
||||
if(result)
|
||||
goto out;
|
||||
result = Curl_pollfds_add_ps(&cpfds, &ps);
|
||||
if(result)
|
||||
goto out;
|
||||
|
|
@ -557,6 +561,7 @@ CURLcode Curl_conn_connect(struct Curl_easy *data,
|
|||
}
|
||||
|
||||
out:
|
||||
Curl_pollset_cleanup(&ps);
|
||||
Curl_pollfds_cleanup(&cpfds);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -710,10 +715,11 @@ bool Curl_conn_needs_flush(struct Curl_easy *data, int sockindex)
|
|||
return Curl_conn_cf_needs_flush(data->conn->cfilter[sockindex], data);
|
||||
}
|
||||
|
||||
void Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
CURLcode Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
/* Get the lowest not-connected filter, if there are any */
|
||||
while(cf && !cf->connected && cf->next && !cf->next->connected)
|
||||
cf = cf->next;
|
||||
|
|
@ -722,23 +728,26 @@ void Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf,
|
|||
cf = cf->next;
|
||||
/* From there on, give all filters a chance to adjust the pollset.
|
||||
* Lower filters are called later, so they may override */
|
||||
while(cf) {
|
||||
cf->cft->adjust_pollset(cf, data, ps);
|
||||
while(cf && !result) {
|
||||
result = cf->cft->adjust_pollset(cf, data, ps);
|
||||
cf = cf->next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void Curl_conn_adjust_pollset(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
struct easy_pollset *ps)
|
||||
CURLcode Curl_conn_adjust_pollset(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
int i;
|
||||
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(conn);
|
||||
for(i = 0; i < 2; ++i) {
|
||||
Curl_conn_cf_adjust_pollset(conn->cfilter[i], data, ps);
|
||||
for(i = 0; (i < 2) && !result; ++i) {
|
||||
result = Curl_conn_cf_adjust_pollset(conn->cfilter[i], data, ps);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int Curl_conn_cf_poll(struct Curl_cfilter *cf,
|
||||
|
|
@ -746,35 +755,18 @@ int Curl_conn_cf_poll(struct Curl_cfilter *cf,
|
|||
timediff_t timeout_ms)
|
||||
{
|
||||
struct easy_pollset ps;
|
||||
struct pollfd pfds[MAX_SOCKSPEREASYHANDLE];
|
||||
unsigned int i, npfds = 0;
|
||||
int result;
|
||||
|
||||
DEBUGASSERT(cf);
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(data->conn);
|
||||
memset(&ps, 0, sizeof(ps));
|
||||
memset(pfds, 0, sizeof(pfds));
|
||||
Curl_pollset_init(&ps);
|
||||
|
||||
Curl_conn_cf_adjust_pollset(cf, data, &ps);
|
||||
DEBUGASSERT(ps.num <= MAX_SOCKSPEREASYHANDLE);
|
||||
for(i = 0; i < ps.num; ++i) {
|
||||
short events = 0;
|
||||
if(ps.actions[i] & CURL_POLL_IN) {
|
||||
events |= POLLIN;
|
||||
}
|
||||
if(ps.actions[i] & CURL_POLL_OUT) {
|
||||
events |= POLLOUT;
|
||||
}
|
||||
if(events) {
|
||||
pfds[npfds].fd = ps.sockets[i];
|
||||
pfds[npfds].events = events;
|
||||
++npfds;
|
||||
}
|
||||
}
|
||||
|
||||
if(!npfds)
|
||||
DEBUGF(infof(data, "no sockets to poll!"));
|
||||
return Curl_poll(pfds, npfds, timeout_ms);
|
||||
result = Curl_conn_cf_adjust_pollset(cf, data, &ps);
|
||||
if(!result)
|
||||
result = Curl_pollset_poll(data, &ps, timeout_ms);
|
||||
Curl_pollset_cleanup(&ps);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Curl_conn_get_current_host(struct Curl_easy *data, int sockindex,
|
||||
|
|
@ -1099,142 +1091,3 @@ CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex,
|
|||
*pnwritten = 0;
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
void Curl_pollset_reset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
size_t i;
|
||||
(void)data;
|
||||
memset(ps, 0, sizeof(*ps));
|
||||
for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++)
|
||||
ps->sockets[i] = CURL_SOCKET_BAD;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void Curl_pollset_change(struct Curl_easy *data,
|
||||
struct easy_pollset *ps, curl_socket_t sock,
|
||||
int add_flags, int remove_flags)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
(void)data;
|
||||
DEBUGASSERT(VALID_SOCK(sock));
|
||||
if(!VALID_SOCK(sock))
|
||||
return;
|
||||
|
||||
DEBUGASSERT(add_flags <= (CURL_POLL_IN|CURL_POLL_OUT));
|
||||
DEBUGASSERT(remove_flags <= (CURL_POLL_IN|CURL_POLL_OUT));
|
||||
DEBUGASSERT((add_flags&remove_flags) == 0); /* no overlap */
|
||||
for(i = 0; i < ps->num; ++i) {
|
||||
if(ps->sockets[i] == sock) {
|
||||
ps->actions[i] &= (unsigned char)(~remove_flags);
|
||||
ps->actions[i] |= (unsigned char)add_flags;
|
||||
/* all gone? remove socket */
|
||||
if(!ps->actions[i]) {
|
||||
if((i + 1) < ps->num) {
|
||||
memmove(&ps->sockets[i], &ps->sockets[i + 1],
|
||||
(ps->num - (i + 1)) * sizeof(ps->sockets[0]));
|
||||
memmove(&ps->actions[i], &ps->actions[i + 1],
|
||||
(ps->num - (i + 1)) * sizeof(ps->actions[0]));
|
||||
}
|
||||
--ps->num;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* not present */
|
||||
if(add_flags) {
|
||||
/* Having more SOCKETS per easy handle than what is defined
|
||||
* is a programming error. This indicates that we need
|
||||
* to raise this limit, making easy_pollset larger.
|
||||
* Since we use this in tight loops, we do not want to make
|
||||
* the pollset dynamic unnecessarily.
|
||||
* The current maximum in practise is HTTP/3 eyeballing where
|
||||
* we have up to 4 sockets involved in connection setup.
|
||||
*/
|
||||
DEBUGASSERT(i < MAX_SOCKSPEREASYHANDLE);
|
||||
if(i < MAX_SOCKSPEREASYHANDLE) {
|
||||
ps->sockets[i] = sock;
|
||||
ps->actions[i] = (unsigned char)add_flags;
|
||||
ps->num = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Curl_pollset_set(struct Curl_easy *data,
|
||||
struct easy_pollset *ps, curl_socket_t sock,
|
||||
bool do_in, bool do_out)
|
||||
{
|
||||
Curl_pollset_change(data, ps, sock,
|
||||
(do_in ? CURL_POLL_IN : 0)|
|
||||
(do_out ? CURL_POLL_OUT : 0),
|
||||
(!do_in ? CURL_POLL_IN : 0)|
|
||||
(!do_out ? CURL_POLL_OUT : 0));
|
||||
}
|
||||
|
||||
static void ps_add(struct Curl_easy *data, struct easy_pollset *ps,
|
||||
int bitmap, curl_socket_t *socks)
|
||||
{
|
||||
if(bitmap) {
|
||||
int i;
|
||||
for(i = 0; i < MAX_SOCKSPEREASYHANDLE; ++i) {
|
||||
if(!(bitmap & GETSOCK_MASK_RW(i)) || !VALID_SOCK((socks[i]))) {
|
||||
break;
|
||||
}
|
||||
if(bitmap & GETSOCK_READSOCK(i)) {
|
||||
if(bitmap & GETSOCK_WRITESOCK(i))
|
||||
Curl_pollset_add_inout(data, ps, socks[i]);
|
||||
else
|
||||
/* is READ, since we checked MASK_RW above */
|
||||
Curl_pollset_add_in(data, ps, socks[i]);
|
||||
}
|
||||
else
|
||||
Curl_pollset_add_out(data, ps, socks[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Curl_pollset_add_socks(struct Curl_easy *data,
|
||||
struct easy_pollset *ps,
|
||||
int (*get_socks_cb)(struct Curl_easy *data,
|
||||
curl_socket_t *socks))
|
||||
{
|
||||
curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
|
||||
int bitmap;
|
||||
|
||||
bitmap = get_socks_cb(data, socks);
|
||||
ps_add(data, ps, bitmap, socks);
|
||||
}
|
||||
|
||||
void Curl_pollset_check(struct Curl_easy *data,
|
||||
struct easy_pollset *ps, curl_socket_t sock,
|
||||
bool *pwant_read, bool *pwant_write)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
(void)data;
|
||||
DEBUGASSERT(VALID_SOCK(sock));
|
||||
for(i = 0; i < ps->num; ++i) {
|
||||
if(ps->sockets[i] == sock) {
|
||||
*pwant_read = !!(ps->actions[i] & CURL_POLL_IN);
|
||||
*pwant_write = !!(ps->actions[i] & CURL_POLL_OUT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
*pwant_read = *pwant_write = FALSE;
|
||||
}
|
||||
|
||||
bool Curl_pollset_want_read(struct Curl_easy *data,
|
||||
struct easy_pollset *ps,
|
||||
curl_socket_t sock)
|
||||
{
|
||||
unsigned int i;
|
||||
(void)data;
|
||||
for(i = 0; i < ps->num; ++i) {
|
||||
if((ps->sockets[i] == sock) && (ps->actions[i] & CURL_POLL_IN))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ struct easy_pollset;
|
|||
* @param data the easy handle the pollset is about
|
||||
* @param ps the pollset (inout) for the easy handle
|
||||
*/
|
||||
typedef void Curl_cft_adjust_pollset(struct Curl_cfilter *cf,
|
||||
typedef CURLcode Curl_cft_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
|
|
@ -244,7 +244,7 @@ void Curl_cf_def_destroy_this(struct Curl_cfilter *cf,
|
|||
|
||||
/* Default implementations for the type functions, implementing pass-through
|
||||
* the filter chain. */
|
||||
void Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf,
|
||||
CURLcode Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
|
||||
|
|
@ -477,16 +477,16 @@ void Curl_conn_forget_socket(struct Curl_easy *data, int sockindex);
|
|||
/**
|
||||
* Adjust the pollset for the filter chain starting at `cf`.
|
||||
*/
|
||||
void Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
CURLcode Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
/**
|
||||
* Adjust pollset from filters installed at transfer's connection.
|
||||
*/
|
||||
void Curl_conn_adjust_pollset(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
struct easy_pollset *ps);
|
||||
CURLcode Curl_conn_adjust_pollset(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
/**
|
||||
* Curl_poll() the filter chain at `cf` with timeout `timeout_ms`.
|
||||
|
|
@ -632,56 +632,6 @@ CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex,
|
|||
size_t *pnwritten);
|
||||
|
||||
|
||||
void Curl_pollset_reset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
/* Change the poll flags (CURL_POLL_IN/CURL_POLL_OUT) to the poll set for
|
||||
* socket `sock`. If the socket is not already part of the poll set, it
|
||||
* will be added.
|
||||
* If the socket is present and all poll flags are cleared, it will be removed.
|
||||
*/
|
||||
void Curl_pollset_change(struct Curl_easy *data,
|
||||
struct easy_pollset *ps, curl_socket_t sock,
|
||||
int add_flags, int remove_flags);
|
||||
|
||||
void Curl_pollset_set(struct Curl_easy *data,
|
||||
struct easy_pollset *ps, curl_socket_t sock,
|
||||
bool do_in, bool do_out);
|
||||
|
||||
#define Curl_pollset_add_in(data, ps, sock) \
|
||||
Curl_pollset_change((data), (ps), (sock), CURL_POLL_IN, 0)
|
||||
#define Curl_pollset_add_out(data, ps, sock) \
|
||||
Curl_pollset_change((data), (ps), (sock), CURL_POLL_OUT, 0)
|
||||
#define Curl_pollset_add_inout(data, ps, sock) \
|
||||
Curl_pollset_change((data), (ps), (sock), \
|
||||
CURL_POLL_IN|CURL_POLL_OUT, 0)
|
||||
#define Curl_pollset_set_in_only(data, ps, sock) \
|
||||
Curl_pollset_change((data), (ps), (sock), \
|
||||
CURL_POLL_IN, CURL_POLL_OUT)
|
||||
#define Curl_pollset_set_out_only(data, ps, sock) \
|
||||
Curl_pollset_change((data), (ps), (sock), \
|
||||
CURL_POLL_OUT, CURL_POLL_IN)
|
||||
|
||||
void Curl_pollset_add_socks(struct Curl_easy *data,
|
||||
struct easy_pollset *ps,
|
||||
int (*get_socks_cb)(struct Curl_easy *data,
|
||||
curl_socket_t *socks));
|
||||
|
||||
/**
|
||||
* Check if the pollset, as is, wants to read and/or write regarding
|
||||
* the given socket.
|
||||
*/
|
||||
void Curl_pollset_check(struct Curl_easy *data,
|
||||
struct easy_pollset *ps, curl_socket_t sock,
|
||||
bool *pwant_read, bool *pwant_write);
|
||||
|
||||
/**
|
||||
* Return TRUE if the pollset contains socket with CURL_POLL_IN.
|
||||
*/
|
||||
bool Curl_pollset_want_read(struct Curl_easy *data,
|
||||
struct easy_pollset *ps,
|
||||
curl_socket_t sock);
|
||||
|
||||
/**
|
||||
* Types and macros used to keep the current easy handle in filter calls,
|
||||
* allowing for nested invocations. See #10336.
|
||||
|
|
|
|||
|
|
@ -486,18 +486,24 @@ void Curl_cshutdn_setfds(struct cshutdn *cshutdn,
|
|||
{
|
||||
if(Curl_llist_head(&cshutdn->list)) {
|
||||
struct Curl_llist_node *e;
|
||||
struct easy_pollset ps;
|
||||
|
||||
Curl_pollset_init(&ps);
|
||||
for(e = Curl_llist_head(&cshutdn->list); e;
|
||||
e = Curl_node_next(e)) {
|
||||
struct easy_pollset ps;
|
||||
unsigned int i;
|
||||
struct connectdata *conn = Curl_node_elem(e);
|
||||
memset(&ps, 0, sizeof(ps));
|
||||
CURLcode result;
|
||||
|
||||
Curl_pollset_reset(&ps);
|
||||
Curl_attach_connection(data, conn);
|
||||
Curl_conn_adjust_pollset(data, conn, &ps);
|
||||
result = Curl_conn_adjust_pollset(data, conn, &ps);
|
||||
Curl_detach_connection(data);
|
||||
|
||||
for(i = 0; i < ps.num; i++) {
|
||||
if(result)
|
||||
continue;
|
||||
|
||||
for(i = 0; i < ps.n; i++) {
|
||||
#ifdef __DJGPP__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Warith-conversion"
|
||||
|
|
@ -514,6 +520,7 @@ void Curl_cshutdn_setfds(struct cshutdn *cshutdn,
|
|||
*maxfd = (int)ps.sockets[i];
|
||||
}
|
||||
}
|
||||
Curl_pollset_cleanup(&ps);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -528,17 +535,21 @@ unsigned int Curl_cshutdn_add_waitfds(struct cshutdn *cshutdn,
|
|||
struct Curl_llist_node *e;
|
||||
struct easy_pollset ps;
|
||||
struct connectdata *conn;
|
||||
CURLcode result;
|
||||
|
||||
Curl_pollset_init(&ps);
|
||||
for(e = Curl_llist_head(&cshutdn->list); e;
|
||||
e = Curl_node_next(e)) {
|
||||
conn = Curl_node_elem(e);
|
||||
memset(&ps, 0, sizeof(ps));
|
||||
Curl_pollset_reset(&ps);
|
||||
Curl_attach_connection(data, conn);
|
||||
Curl_conn_adjust_pollset(data, conn, &ps);
|
||||
result = Curl_conn_adjust_pollset(data, conn, &ps);
|
||||
Curl_detach_connection(data);
|
||||
|
||||
need += Curl_waitfds_add_ps(cwfds, &ps);
|
||||
if(!result)
|
||||
need += Curl_waitfds_add_ps(cwfds, &ps);
|
||||
}
|
||||
Curl_pollset_cleanup(&ps);
|
||||
}
|
||||
return need;
|
||||
}
|
||||
|
|
@ -554,20 +565,24 @@ CURLcode Curl_cshutdn_add_pollfds(struct cshutdn *cshutdn,
|
|||
struct easy_pollset ps;
|
||||
struct connectdata *conn;
|
||||
|
||||
Curl_pollset_init(&ps);
|
||||
for(e = Curl_llist_head(&cshutdn->list); e;
|
||||
e = Curl_node_next(e)) {
|
||||
conn = Curl_node_elem(e);
|
||||
memset(&ps, 0, sizeof(ps));
|
||||
Curl_pollset_reset(&ps);
|
||||
Curl_attach_connection(data, conn);
|
||||
Curl_conn_adjust_pollset(data, conn, &ps);
|
||||
result = Curl_conn_adjust_pollset(data, conn, &ps);
|
||||
Curl_detach_connection(data);
|
||||
|
||||
result = Curl_pollfds_add_ps(cpfds, &ps);
|
||||
if(!result)
|
||||
result = Curl_pollfds_add_ps(cpfds, &ps);
|
||||
if(result) {
|
||||
Curl_pollset_cleanup(&ps);
|
||||
Curl_pollfds_cleanup(cpfds);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
Curl_pollset_cleanup(&ps);
|
||||
}
|
||||
out:
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -81,10 +81,10 @@ const struct Curl_handler Curl_handler_rtmp = {
|
|||
rtmp_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* proto_pollset */
|
||||
ZERO_NULL, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -106,10 +106,10 @@ const struct Curl_handler Curl_handler_rtmpt = {
|
|||
rtmp_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* proto_pollset */
|
||||
ZERO_NULL, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -131,10 +131,10 @@ const struct Curl_handler Curl_handler_rtmpe = {
|
|||
rtmp_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* proto_pollset */
|
||||
ZERO_NULL, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -156,10 +156,10 @@ const struct Curl_handler Curl_handler_rtmpte = {
|
|||
rtmp_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* proto_pollset */
|
||||
ZERO_NULL, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -181,10 +181,10 @@ const struct Curl_handler Curl_handler_rtmps = {
|
|||
rtmp_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* proto_pollset */
|
||||
ZERO_NULL, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -206,10 +206,10 @@ const struct Curl_handler Curl_handler_rtmpts = {
|
|||
rtmp_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* proto_pollset */
|
||||
ZERO_NULL, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
|
|||
|
|
@ -92,10 +92,10 @@ const struct Curl_handler Curl_handler_dict = {
|
|||
ZERO_NULL, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* proto_pollset */
|
||||
ZERO_NULL, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
|
|||
|
|
@ -120,10 +120,10 @@ const struct Curl_handler Curl_handler_file = {
|
|||
file_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* proto_pollset */
|
||||
ZERO_NULL, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
file_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
|
|||
55
lib/ftp.c
55
lib/ftp.c
|
|
@ -214,10 +214,10 @@ static CURLcode ftp_disconnect(struct Curl_easy *data,
|
|||
struct connectdata *conn, bool dead_connection);
|
||||
static CURLcode ftp_do_more(struct Curl_easy *data, int *completed);
|
||||
static CURLcode ftp_multi_statemach(struct Curl_easy *data, bool *done);
|
||||
static int ftp_getsock(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t *socks);
|
||||
static int ftp_domore_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks);
|
||||
static CURLcode ftp_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
static CURLcode ftp_domore_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
static CURLcode ftp_doing(struct Curl_easy *data,
|
||||
bool *dophase_done);
|
||||
static CURLcode ftp_setup_connection(struct Curl_easy *data,
|
||||
|
|
@ -257,10 +257,10 @@ const struct Curl_handler Curl_handler_ftp = {
|
|||
ftp_connect, /* connect_it */
|
||||
ftp_multi_statemach, /* connecting */
|
||||
ftp_doing, /* doing */
|
||||
ftp_getsock, /* proto_getsock */
|
||||
ftp_getsock, /* doing_getsock */
|
||||
ftp_domore_getsock, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ftp_pollset, /* proto_pollset */
|
||||
ftp_pollset, /* doing_pollset */
|
||||
ftp_domore_pollset, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
ftp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -290,10 +290,10 @@ const struct Curl_handler Curl_handler_ftps = {
|
|||
ftp_connect, /* connect_it */
|
||||
ftp_multi_statemach, /* connecting */
|
||||
ftp_doing, /* doing */
|
||||
ftp_getsock, /* proto_getsock */
|
||||
ftp_getsock, /* doing_getsock */
|
||||
ftp_domore_getsock, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ftp_pollset, /* proto_pollset */
|
||||
ftp_pollset, /* doing_pollset */
|
||||
ftp_domore_pollset, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
ftp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -781,42 +781,39 @@ static CURLcode ftp_state_pwd(struct Curl_easy *data,
|
|||
}
|
||||
|
||||
/* For the FTP "protocol connect" and "doing" phases only */
|
||||
static int ftp_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
curl_socket_t *socks)
|
||||
static CURLcode ftp_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct ftp_conn *ftpc = Curl_conn_meta_get(conn, CURL_META_FTP_CONN);
|
||||
return ftpc ? Curl_pp_getsock(data, &ftpc->pp, socks) : GETSOCK_BLANK;
|
||||
struct ftp_conn *ftpc = Curl_conn_meta_get(data->conn, CURL_META_FTP_CONN);
|
||||
return ftpc ? Curl_pp_pollset(data, &ftpc->pp, ps) : CURLE_OK;
|
||||
}
|
||||
|
||||
/* For the FTP "DO_MORE" phase only */
|
||||
static int ftp_domore_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks)
|
||||
static CURLcode ftp_domore_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct ftp_conn *ftpc = Curl_conn_meta_get(conn, CURL_META_FTP_CONN);
|
||||
(void)data;
|
||||
struct ftp_conn *ftpc = Curl_conn_meta_get(data->conn, CURL_META_FTP_CONN);
|
||||
|
||||
if(!ftpc)
|
||||
return GETSOCK_BLANK;
|
||||
return CURLE_OK;
|
||||
|
||||
/* When in DO_MORE state, we could be either waiting for us to connect to a
|
||||
* remote site, or we could wait for that site to connect to us. Or just
|
||||
* handle ordinary commands.
|
||||
*/
|
||||
CURL_TRC_FTP(data, "[%s] ftp_domore_getsock()", FTP_CSTATE(ftpc));
|
||||
CURL_TRC_FTP(data, "[%s] ftp_domore_pollset()", FTP_CSTATE(ftpc));
|
||||
|
||||
if(FTP_STOP == ftpc->state) {
|
||||
/* if stopped and still in this state, then we are also waiting for a
|
||||
connect on the secondary connection */
|
||||
DEBUGASSERT(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD ||
|
||||
(conn->cfilter[SECONDARYSOCKET] &&
|
||||
!Curl_conn_is_connected(conn, SECONDARYSOCKET)));
|
||||
socks[0] = conn->sock[FIRSTSOCKET];
|
||||
DEBUGASSERT(data->conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD ||
|
||||
(data->conn->cfilter[SECONDARYSOCKET] &&
|
||||
!Curl_conn_is_connected(data->conn, SECONDARYSOCKET)));
|
||||
/* An unconnected SECONDARY will add its socket by itself
|
||||
* via its adjust_pollset() */
|
||||
return GETSOCK_READSOCK(0);
|
||||
return Curl_pollset_add_in(data, ps, data->conn->sock[FIRSTSOCKET]);
|
||||
}
|
||||
return Curl_pp_getsock(data, &ftpc->pp, socks);
|
||||
return Curl_pp_pollset(data, &ftpc->pp, ps);
|
||||
}
|
||||
|
||||
/* This is called after the FTP_QUOTE state is passed.
|
||||
|
|
|
|||
16
lib/gopher.c
16
lib/gopher.c
|
|
@ -70,10 +70,10 @@ const struct Curl_handler Curl_handler_gopher = {
|
|||
ZERO_NULL, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* proto_pollset */
|
||||
ZERO_NULL, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -96,10 +96,10 @@ const struct Curl_handler Curl_handler_gophers = {
|
|||
gopher_connect, /* connect_it */
|
||||
gopher_connecting, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* proto_pollset */
|
||||
ZERO_NULL, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
|
|||
12
lib/hostip.c
12
lib/hostip.c
|
|
@ -1527,21 +1527,21 @@ CURLcode Curl_resolv_check(struct Curl_easy *data,
|
|||
}
|
||||
#endif
|
||||
|
||||
int Curl_resolv_getsock(struct Curl_easy *data,
|
||||
curl_socket_t *socks)
|
||||
CURLcode Curl_resolv_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
#ifdef CURLRES_ASYNCH
|
||||
#ifndef CURL_DISABLE_DOH
|
||||
if(data->conn->bits.doh)
|
||||
/* nothing to wait for during DoH resolve, those handles have their own
|
||||
sockets */
|
||||
return GETSOCK_BLANK;
|
||||
return CURLE_OK;
|
||||
#endif
|
||||
return Curl_async_getsock(data, socks);
|
||||
return Curl_async_pollset(data, ps);
|
||||
#else
|
||||
(void)data;
|
||||
(void)socks;
|
||||
return GETSOCK_BLANK;
|
||||
(void)ps;
|
||||
return CURLE_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ struct addrinfo;
|
|||
struct hostent;
|
||||
struct Curl_easy;
|
||||
struct connectdata;
|
||||
struct easy_pollset;
|
||||
|
||||
enum alpnid {
|
||||
ALPN_none = 0,
|
||||
|
|
@ -199,8 +200,8 @@ CURLcode Curl_resolv_check(struct Curl_easy *data,
|
|||
#else
|
||||
#define Curl_resolv_check(x,y) CURLE_NOT_BUILT_IN
|
||||
#endif
|
||||
int Curl_resolv_getsock(struct Curl_easy *data,
|
||||
curl_socket_t *socks);
|
||||
CURLcode Curl_resolv_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
CURLcode Curl_resolver_error(struct Curl_easy *data);
|
||||
|
||||
|
|
|
|||
26
lib/http.c
26
lib/http.c
|
|
@ -137,10 +137,10 @@ const struct Curl_handler Curl_handler_http = {
|
|||
Curl_http_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
Curl_http_getsock_do, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* proto_pollset */
|
||||
Curl_http_do_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
ZERO_NULL, /* disconnect */
|
||||
Curl_http_write_resp, /* write_resp */
|
||||
Curl_http_write_resp_hd, /* write_resp_hd */
|
||||
|
|
@ -167,10 +167,10 @@ const struct Curl_handler Curl_handler_https = {
|
|||
Curl_http_connect, /* connect_it */
|
||||
NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
NULL, /* proto_getsock */
|
||||
Curl_http_getsock_do, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
NULL, /* proto_pollset */
|
||||
Curl_http_do_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
ZERO_NULL, /* disconnect */
|
||||
Curl_http_write_resp, /* write_resp */
|
||||
Curl_http_write_resp_hd, /* write_resp_hd */
|
||||
|
|
@ -1524,14 +1524,12 @@ CURLcode Curl_http_connect(struct Curl_easy *data, bool *done)
|
|||
/* this returns the socket to wait for in the DO and DOING state for the multi
|
||||
interface and then we are always _sending_ a request and thus we wait for
|
||||
the single socket to become writable only */
|
||||
int Curl_http_getsock_do(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
curl_socket_t *socks)
|
||||
CURLcode Curl_http_do_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
/* write mode */
|
||||
(void)conn;
|
||||
socks[0] = Curl_conn_get_socket(data, FIRSTSOCKET);
|
||||
return GETSOCK_WRITESOCK(0);
|
||||
curl_socket_t sock = Curl_conn_get_socket(data, FIRSTSOCKET);
|
||||
return Curl_pollset_add_out(data, ps, sock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -115,8 +115,8 @@ CURLcode Curl_http_setup_conn(struct Curl_easy *data,
|
|||
CURLcode Curl_http(struct Curl_easy *data, bool *done);
|
||||
CURLcode Curl_http_done(struct Curl_easy *data, CURLcode, bool premature);
|
||||
CURLcode Curl_http_connect(struct Curl_easy *data, bool *done);
|
||||
int Curl_http_getsock_do(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t *socks);
|
||||
CURLcode Curl_http_do_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
CURLcode Curl_http_write_resp(struct Curl_easy *data,
|
||||
const char *buf, size_t blen,
|
||||
bool is_eos);
|
||||
|
|
|
|||
14
lib/http2.c
14
lib/http2.c
|
|
@ -2465,17 +2465,18 @@ out:
|
|||
return result;
|
||||
}
|
||||
|
||||
static void cf_h2_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
static CURLcode cf_h2_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct cf_h2_ctx *ctx = cf->ctx;
|
||||
struct cf_call_data save;
|
||||
curl_socket_t sock;
|
||||
bool want_recv, want_send;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(!ctx->h2)
|
||||
return;
|
||||
return CURLE_OK;
|
||||
|
||||
sock = Curl_conn_cf_get_socket(cf, data);
|
||||
Curl_pollset_check(data, ps, sock, &want_recv, &want_send);
|
||||
|
|
@ -2493,7 +2494,7 @@ static void cf_h2_adjust_pollset(struct Curl_cfilter *cf,
|
|||
(!c_exhaust && nghttp2_session_want_write(ctx->h2)) ||
|
||||
!Curl_bufq_is_empty(&ctx->outbufq);
|
||||
|
||||
Curl_pollset_set(data, ps, sock, want_recv, want_send);
|
||||
result = Curl_pollset_set(data, ps, sock, want_recv, want_send);
|
||||
CF_DATA_RESTORE(cf, save);
|
||||
}
|
||||
else if(ctx->sent_goaway && !cf->shutdown) {
|
||||
|
|
@ -2502,9 +2503,10 @@ static void cf_h2_adjust_pollset(struct Curl_cfilter *cf,
|
|||
want_send = nghttp2_session_want_write(ctx->h2) ||
|
||||
!Curl_bufq_is_empty(&ctx->outbufq);
|
||||
want_recv = nghttp2_session_want_read(ctx->h2);
|
||||
Curl_pollset_set(data, ps, sock, want_recv, want_send);
|
||||
result = Curl_pollset_set(data, ps, sock, want_recv, want_send);
|
||||
CF_DATA_RESTORE(cf, save);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode cf_h2_connect(struct Curl_cfilter *cf,
|
||||
|
|
|
|||
31
lib/imap.c
31
lib/imap.c
|
|
@ -157,8 +157,8 @@ static CURLcode imap_connect(struct Curl_easy *data, bool *done);
|
|||
static CURLcode imap_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool dead);
|
||||
static CURLcode imap_multi_statemach(struct Curl_easy *data, bool *done);
|
||||
static int imap_getsock(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t *socks);
|
||||
static CURLcode imap_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
static CURLcode imap_doing(struct Curl_easy *data, bool *dophase_done);
|
||||
static CURLcode imap_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
|
@ -196,10 +196,10 @@ const struct Curl_handler Curl_handler_imap = {
|
|||
imap_connect, /* connect_it */
|
||||
imap_multi_statemach, /* connecting */
|
||||
imap_doing, /* doing */
|
||||
imap_getsock, /* proto_getsock */
|
||||
imap_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
imap_pollset, /* proto_pollset */
|
||||
imap_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
imap_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -227,10 +227,10 @@ const struct Curl_handler Curl_handler_imaps = {
|
|||
imap_connect, /* connect_it */
|
||||
imap_multi_statemach, /* connecting */
|
||||
imap_doing, /* doing */
|
||||
imap_getsock, /* proto_getsock */
|
||||
imap_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
imap_pollset, /* proto_pollset */
|
||||
imap_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
imap_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -1560,13 +1560,12 @@ static CURLcode imap_block_statemach(struct Curl_easy *data,
|
|||
}
|
||||
|
||||
/* For the IMAP "protocol connect" and "doing" phases only */
|
||||
static int imap_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
curl_socket_t *socks)
|
||||
static CURLcode imap_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct imap_conn *imapc = Curl_conn_meta_get(conn, CURL_META_IMAP_CONN);
|
||||
return imapc ?
|
||||
Curl_pp_getsock(data, &imapc->pp, socks) : GETSOCK_BLANK;
|
||||
struct imap_conn *imapc =
|
||||
Curl_conn_meta_get(data->conn, CURL_META_IMAP_CONN);
|
||||
return imapc ? Curl_pp_pollset(data, &imapc->pp, ps) : CURLE_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
|||
16
lib/ldap.c
16
lib/ldap.c
|
|
@ -177,10 +177,10 @@ const struct Curl_handler Curl_handler_ldap = {
|
|||
ZERO_NULL, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* proto_pollset */
|
||||
ZERO_NULL, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -207,10 +207,10 @@ const struct Curl_handler Curl_handler_ldaps = {
|
|||
ZERO_NULL, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* proto_pollset */
|
||||
ZERO_NULL, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
|
|||
21
lib/mqtt.c
21
lib/mqtt.c
|
|
@ -107,8 +107,8 @@ static CURLcode mqtt_do(struct Curl_easy *data, bool *done);
|
|||
static CURLcode mqtt_done(struct Curl_easy *data,
|
||||
CURLcode status, bool premature);
|
||||
static CURLcode mqtt_doing(struct Curl_easy *data, bool *done);
|
||||
static int mqtt_getsock(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t *sock);
|
||||
static CURLcode mqtt_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
static CURLcode mqtt_setup_conn(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
||||
|
|
@ -125,10 +125,10 @@ const struct Curl_handler Curl_handler_mqtt = {
|
|||
ZERO_NULL, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
mqtt_doing, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
mqtt_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* proto_pollset */
|
||||
mqtt_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -213,13 +213,10 @@ static CURLcode mqtt_send(struct Curl_easy *data,
|
|||
/* Generic function called by the multi interface to figure out what socket(s)
|
||||
to wait for and for what actions during the DOING and PROTOCONNECT
|
||||
states */
|
||||
static int mqtt_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
curl_socket_t *sock)
|
||||
static CURLcode mqtt_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
(void)data;
|
||||
sock[0] = conn->sock[FIRSTSOCKET];
|
||||
return GETSOCK_READSOCK(FIRSTSOCKET);
|
||||
return Curl_pollset_add_in(data, ps, data->conn->sock[FIRSTSOCKET]);
|
||||
}
|
||||
|
||||
static int mqtt_encode_len(char *buf, size_t len)
|
||||
|
|
|
|||
203
lib/multi.c
203
lib/multi.c
|
|
@ -907,118 +907,103 @@ void Curl_attach_connection(struct Curl_easy *data,
|
|||
conn->handler->attach(data, conn);
|
||||
}
|
||||
|
||||
static int connecting_getsock(struct Curl_easy *data, curl_socket_t *socks)
|
||||
static CURLcode mstate_connecting_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
curl_socket_t sockfd;
|
||||
|
||||
if(!conn)
|
||||
return GETSOCK_BLANK;
|
||||
sockfd = Curl_conn_get_socket(data, FIRSTSOCKET);
|
||||
if(sockfd != CURL_SOCKET_BAD) {
|
||||
/* Default is to wait to something from the server */
|
||||
socks[0] = sockfd;
|
||||
return GETSOCK_READSOCK(0);
|
||||
if(data->conn) {
|
||||
curl_socket_t sockfd = Curl_conn_get_socket(data, FIRSTSOCKET);
|
||||
if(sockfd != CURL_SOCKET_BAD) {
|
||||
/* Default is to wait to something from the server */
|
||||
return Curl_pollset_change(data, ps, sockfd, CURL_POLL_IN, 0);
|
||||
}
|
||||
}
|
||||
return GETSOCK_BLANK;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static int protocol_getsock(struct Curl_easy *data, curl_socket_t *socks)
|
||||
static CURLcode mstate_protocol_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
curl_socket_t sockfd;
|
||||
|
||||
if(!conn)
|
||||
return GETSOCK_BLANK;
|
||||
if(conn->handler->proto_getsock)
|
||||
return conn->handler->proto_getsock(data, conn, socks);
|
||||
sockfd = Curl_conn_get_socket(data, FIRSTSOCKET);
|
||||
if(sockfd != CURL_SOCKET_BAD) {
|
||||
/* Default is to wait to something from the server */
|
||||
socks[0] = sockfd;
|
||||
return GETSOCK_READSOCK(0);
|
||||
if(data->conn) {
|
||||
curl_socket_t sockfd;
|
||||
if(data->conn->handler->proto_pollset)
|
||||
return data->conn->handler->proto_pollset(data, ps);
|
||||
sockfd = Curl_conn_get_socket(data, FIRSTSOCKET);
|
||||
if(sockfd != CURL_SOCKET_BAD) {
|
||||
/* Default is to wait to something from the server */
|
||||
return Curl_pollset_change(data, ps, sockfd, CURL_POLL_IN, 0);
|
||||
}
|
||||
}
|
||||
return GETSOCK_BLANK;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static int domore_getsock(struct Curl_easy *data, curl_socket_t *socks)
|
||||
static CURLcode mstate_do_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
if(!conn)
|
||||
return GETSOCK_BLANK;
|
||||
if(conn->handler->domore_getsock)
|
||||
return conn->handler->domore_getsock(data, conn, socks);
|
||||
else if(conn->sockfd != CURL_SOCKET_BAD) {
|
||||
/* Default is that we want to send something to the server */
|
||||
socks[0] = conn->sockfd;
|
||||
return GETSOCK_WRITESOCK(0);
|
||||
if(data->conn) {
|
||||
if(data->conn->handler->doing_pollset)
|
||||
return data->conn->handler->doing_pollset(data, ps);
|
||||
else if(conn->sockfd != CURL_SOCKET_BAD) {
|
||||
/* Default is that we want to send something to the server */
|
||||
return Curl_pollset_add_out(data, ps, conn->sockfd);
|
||||
}
|
||||
}
|
||||
return GETSOCK_BLANK;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static int doing_getsock(struct Curl_easy *data, curl_socket_t *socks)
|
||||
static CURLcode mstate_domore_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
if(!conn)
|
||||
return GETSOCK_BLANK;
|
||||
if(conn->handler->doing_getsock)
|
||||
return conn->handler->doing_getsock(data, conn, socks);
|
||||
else if(conn->sockfd != CURL_SOCKET_BAD) {
|
||||
/* Default is that we want to send something to the server */
|
||||
socks[0] = conn->sockfd;
|
||||
return GETSOCK_WRITESOCK(0);
|
||||
if(data->conn) {
|
||||
if(data->conn->handler->domore_pollset)
|
||||
return data->conn->handler->domore_pollset(data, ps);
|
||||
else if(data->conn->sockfd != CURL_SOCKET_BAD) {
|
||||
/* Default is that we want to send something to the server */
|
||||
return Curl_pollset_add_out(data, ps, data->conn->sockfd);
|
||||
}
|
||||
}
|
||||
return GETSOCK_BLANK;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static int perform_getsock(struct Curl_easy *data, curl_socket_t *sock)
|
||||
static CURLcode mstate_perform_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
if(!conn)
|
||||
return GETSOCK_BLANK;
|
||||
else if(conn->handler->perform_getsock)
|
||||
return conn->handler->perform_getsock(data, conn, sock);
|
||||
if(!data->conn)
|
||||
return CURLE_OK;
|
||||
else if(data->conn->handler->perform_pollset)
|
||||
return data->conn->handler->perform_pollset(data, ps);
|
||||
else {
|
||||
/* Default is to obey the data->req.keepon flags for send/recv */
|
||||
int bitmap = GETSOCK_BLANK;
|
||||
unsigned sockindex = 0;
|
||||
CURLcode result = CURLE_OK;
|
||||
if(CURL_WANT_RECV(data)) {
|
||||
DEBUGASSERT(conn->sockfd != CURL_SOCKET_BAD);
|
||||
bitmap |= GETSOCK_READSOCK(sockindex);
|
||||
sock[sockindex] = conn->sockfd;
|
||||
DEBUGASSERT(data->conn->sockfd != CURL_SOCKET_BAD);
|
||||
result = Curl_pollset_add_in(data, ps, data->conn->sockfd);
|
||||
}
|
||||
|
||||
if(Curl_req_want_send(data)) {
|
||||
if((conn->sockfd != conn->writesockfd) ||
|
||||
bitmap == GETSOCK_BLANK) {
|
||||
/* only if they are not the same socket and we have a readable
|
||||
one, we increase index */
|
||||
if(bitmap != GETSOCK_BLANK)
|
||||
sockindex++; /* increase index if we need two entries */
|
||||
|
||||
DEBUGASSERT(conn->writesockfd != CURL_SOCKET_BAD);
|
||||
sock[sockindex] = conn->writesockfd;
|
||||
}
|
||||
bitmap |= GETSOCK_WRITESOCK(sockindex);
|
||||
if(!result && Curl_req_want_send(data)) {
|
||||
DEBUGASSERT(data->conn->writesockfd != CURL_SOCKET_BAD);
|
||||
result = Curl_pollset_add_out(data, ps, data->conn->writesockfd);
|
||||
}
|
||||
return bitmap;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initializes `poll_set` with the current socket poll actions needed
|
||||
* for transfer `data`. */
|
||||
void Curl_multi_getsock(struct Curl_easy *data,
|
||||
struct easy_pollset *ps,
|
||||
const char *caller)
|
||||
CURLMcode Curl_multi_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps,
|
||||
const char *caller)
|
||||
{
|
||||
CURLMcode mresult = CURLM_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
bool expect_sockets = TRUE;
|
||||
|
||||
/* If the transfer has no connection, this is fine. Happens when
|
||||
called via curl_multi_remove_handle() => Curl_multi_ev_assess() =>
|
||||
Curl_multi_getsock(). */
|
||||
Curl_pollset_reset(data, ps);
|
||||
Curl_multi_pollset(). */
|
||||
Curl_pollset_reset(ps);
|
||||
if(!data->conn)
|
||||
return;
|
||||
return CURLM_OK;
|
||||
|
||||
switch(data->mstate) {
|
||||
case MSTATE_INIT:
|
||||
|
|
@ -1030,7 +1015,7 @@ void Curl_multi_getsock(struct Curl_easy *data,
|
|||
break;
|
||||
|
||||
case MSTATE_RESOLVING:
|
||||
Curl_pollset_add_socks(data, ps, Curl_resolv_getsock);
|
||||
result = Curl_resolv_pollset(data, ps);
|
||||
/* connection filters are not involved in this phase. It's ok if we get no
|
||||
* sockets to wait for. Resolving can wake up from other sources. */
|
||||
expect_sockets = FALSE;
|
||||
|
|
@ -1038,31 +1023,36 @@ void Curl_multi_getsock(struct Curl_easy *data,
|
|||
|
||||
case MSTATE_CONNECTING:
|
||||
case MSTATE_TUNNELING:
|
||||
Curl_pollset_add_socks(data, ps, connecting_getsock);
|
||||
Curl_conn_adjust_pollset(data, data->conn, ps);
|
||||
result = mstate_connecting_pollset(data, ps);
|
||||
if(!result)
|
||||
result = Curl_conn_adjust_pollset(data, data->conn, ps);
|
||||
break;
|
||||
|
||||
case MSTATE_PROTOCONNECT:
|
||||
case MSTATE_PROTOCONNECTING:
|
||||
Curl_pollset_add_socks(data, ps, protocol_getsock);
|
||||
Curl_conn_adjust_pollset(data, data->conn, ps);
|
||||
result = mstate_protocol_pollset(data, ps);
|
||||
if(!result)
|
||||
result = Curl_conn_adjust_pollset(data, data->conn, ps);
|
||||
break;
|
||||
|
||||
case MSTATE_DO:
|
||||
case MSTATE_DOING:
|
||||
Curl_pollset_add_socks(data, ps, doing_getsock);
|
||||
Curl_conn_adjust_pollset(data, data->conn, ps);
|
||||
result = mstate_do_pollset(data, ps);
|
||||
if(!result)
|
||||
result = Curl_conn_adjust_pollset(data, data->conn, ps);
|
||||
break;
|
||||
|
||||
case MSTATE_DOING_MORE:
|
||||
Curl_pollset_add_socks(data, ps, domore_getsock);
|
||||
Curl_conn_adjust_pollset(data, data->conn, ps);
|
||||
result = mstate_domore_pollset(data, ps);
|
||||
if(!result)
|
||||
result = Curl_conn_adjust_pollset(data, data->conn, ps);
|
||||
break;
|
||||
|
||||
case MSTATE_DID: /* same as PERFORMING in regard to polling */
|
||||
case MSTATE_PERFORMING:
|
||||
Curl_pollset_add_socks(data, ps, perform_getsock);
|
||||
Curl_conn_adjust_pollset(data, data->conn, ps);
|
||||
result = mstate_perform_pollset(data, ps);
|
||||
if(!result)
|
||||
result = Curl_conn_adjust_pollset(data, data->conn, ps);
|
||||
break;
|
||||
|
||||
case MSTATE_RATELIMITING:
|
||||
|
|
@ -1084,6 +1074,15 @@ void Curl_multi_getsock(struct Curl_easy *data,
|
|||
break;
|
||||
}
|
||||
|
||||
if(result) {
|
||||
if(result == CURLE_OUT_OF_MEMORY)
|
||||
mresult = CURLM_OUT_OF_MEMORY;
|
||||
else {
|
||||
failf(data, "error determining pollset: %d", result);
|
||||
mresult = CURLM_INTERNAL_ERROR;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Unblocked and waiting to receive with buffered input.
|
||||
* Make transfer run again at next opportunity. */
|
||||
|
|
@ -1097,7 +1096,7 @@ void Curl_multi_getsock(struct Curl_easy *data,
|
|||
Curl_multi_mark_dirty(data);
|
||||
}
|
||||
|
||||
switch(ps->num) {
|
||||
switch(ps->n) {
|
||||
case 0:
|
||||
CURL_TRC_M(data, "%s pollset[], timeouts=%zu, paused %d/%d (r/w)",
|
||||
caller, Curl_llist_count(&data->state.timeoutlist),
|
||||
|
|
@ -1124,10 +1123,10 @@ void Curl_multi_getsock(struct Curl_easy *data,
|
|||
break;
|
||||
default:
|
||||
CURL_TRC_M(data, "%s pollset[fds=%u], timeouts=%zu",
|
||||
caller, ps->num, Curl_llist_count(&data->state.timeoutlist));
|
||||
caller, ps->n, Curl_llist_count(&data->state.timeoutlist));
|
||||
break;
|
||||
}
|
||||
if(expect_sockets && !ps->num && data->multi &&
|
||||
if(expect_sockets && !ps->n && data->multi &&
|
||||
!Curl_uint_bset_contains(&data->multi->dirty, data->mid) &&
|
||||
!Curl_llist_count(&data->state.timeoutlist) &&
|
||||
!Curl_cwriter_is_paused(data) && !Curl_creader_is_paused(data) &&
|
||||
|
|
@ -1140,6 +1139,8 @@ void Curl_multi_getsock(struct Curl_easy *data,
|
|||
infof(data, "WARNING: no socket in pollset or timer, transfer may stall!");
|
||||
DEBUGASSERT(0);
|
||||
}
|
||||
out:
|
||||
return mresult;
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_fdset(CURLM *m,
|
||||
|
|
@ -1151,6 +1152,7 @@ CURLMcode curl_multi_fdset(CURLM *m,
|
|||
and then we must make sure that is done. */
|
||||
int this_max_fd = -1;
|
||||
struct Curl_multi *multi = m;
|
||||
struct easy_pollset ps;
|
||||
unsigned int i, mid;
|
||||
(void)exc_fd_set; /* not used */
|
||||
|
||||
|
|
@ -1160,18 +1162,18 @@ CURLMcode curl_multi_fdset(CURLM *m,
|
|||
if(multi->in_callback)
|
||||
return CURLM_RECURSIVE_API_CALL;
|
||||
|
||||
Curl_pollset_init(&ps);
|
||||
if(Curl_uint_bset_first(&multi->process, &mid)) {
|
||||
do {
|
||||
struct Curl_easy *data = Curl_multi_get_easy(multi, mid);
|
||||
struct easy_pollset ps;
|
||||
|
||||
if(!data) {
|
||||
DEBUGASSERT(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
Curl_multi_getsock(data, &ps, "curl_multi_fdset");
|
||||
for(i = 0; i < ps.num; i++) {
|
||||
Curl_multi_pollset(data, &ps, "curl_multi_fdset");
|
||||
for(i = 0; i < ps.n; i++) {
|
||||
if(!FDSET_SOCK(ps.sockets[i]))
|
||||
/* pretend it does not exist */
|
||||
continue;
|
||||
|
|
@ -1197,6 +1199,7 @@ CURLMcode curl_multi_fdset(CURLM *m,
|
|||
read_fd_set, write_fd_set, &this_max_fd);
|
||||
|
||||
*max_fd = this_max_fd;
|
||||
Curl_pollset_cleanup(&ps);
|
||||
|
||||
return CURLM_OK;
|
||||
}
|
||||
|
|
@ -1209,6 +1212,7 @@ CURLMcode curl_multi_waitfds(CURLM *m,
|
|||
struct Curl_waitfds cwfds;
|
||||
CURLMcode result = CURLM_OK;
|
||||
struct Curl_multi *multi = m;
|
||||
struct easy_pollset ps;
|
||||
unsigned int need = 0, mid;
|
||||
|
||||
if(!ufds && (size || !fd_count))
|
||||
|
|
@ -1220,18 +1224,18 @@ CURLMcode curl_multi_waitfds(CURLM *m,
|
|||
if(multi->in_callback)
|
||||
return CURLM_RECURSIVE_API_CALL;
|
||||
|
||||
Curl_pollset_init(&ps);
|
||||
Curl_waitfds_init(&cwfds, ufds, size);
|
||||
if(Curl_uint_bset_first(&multi->process, &mid)) {
|
||||
do {
|
||||
struct Curl_easy *data = Curl_multi_get_easy(multi, mid);
|
||||
struct easy_pollset ps;
|
||||
if(!data) {
|
||||
DEBUGASSERT(0);
|
||||
Curl_uint_bset_remove(&multi->process, mid);
|
||||
Curl_uint_bset_remove(&multi->dirty, mid);
|
||||
continue;
|
||||
}
|
||||
Curl_multi_getsock(data, &ps, "curl_multi_waitfds");
|
||||
Curl_multi_pollset(data, &ps, "curl_multi_waitfds");
|
||||
need += Curl_waitfds_add_ps(&cwfds, &ps);
|
||||
}
|
||||
while(Curl_uint_bset_next(&multi->process, mid, &mid));
|
||||
|
|
@ -1245,6 +1249,7 @@ CURLMcode curl_multi_waitfds(CURLM *m,
|
|||
|
||||
if(fd_count)
|
||||
*fd_count = need;
|
||||
Curl_pollset_cleanup(&ps);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -1278,6 +1283,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
|
|||
struct curltime expire_time;
|
||||
long timeout_internal;
|
||||
int retcode = 0;
|
||||
struct easy_pollset ps;
|
||||
struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK];
|
||||
struct curl_pollfds cpfds;
|
||||
unsigned int curl_nfds = 0; /* how many pfds are for curl transfers */
|
||||
|
|
@ -1302,12 +1308,12 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
|
|||
if(timeout_ms < 0)
|
||||
return CURLM_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
Curl_pollset_init(&ps);
|
||||
Curl_pollfds_init(&cpfds, a_few_on_stack, NUM_POLLS_ON_STACK);
|
||||
|
||||
/* Add the curl handles to our pollfds first */
|
||||
if(Curl_uint_bset_first(&multi->process, &mid)) {
|
||||
do {
|
||||
struct easy_pollset ps;
|
||||
data = Curl_multi_get_easy(multi, mid);
|
||||
if(!data) {
|
||||
DEBUGASSERT(0);
|
||||
|
|
@ -1315,7 +1321,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
|
|||
Curl_uint_bset_remove(&multi->dirty, mid);
|
||||
continue;
|
||||
}
|
||||
Curl_multi_getsock(data, &ps, "multi_wait");
|
||||
Curl_multi_pollset(data, &ps, "multi_wait");
|
||||
if(Curl_pollfds_add_ps(&cpfds, &ps)) {
|
||||
result = CURLM_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
|
|
@ -1514,6 +1520,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
|
|||
}
|
||||
|
||||
out:
|
||||
Curl_pollset_cleanup(&ps);
|
||||
Curl_pollfds_cleanup(&cpfds);
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -317,7 +317,7 @@ static CURLMcode mev_pollset_diff(struct Curl_multi *multi,
|
|||
DEBUGASSERT(prev_ps);
|
||||
|
||||
/* Handle changes to sockets the transfer is interested in. */
|
||||
for(i = 0; i < ps->num; i++) {
|
||||
for(i = 0; i < ps->n; i++) {
|
||||
unsigned char last_action;
|
||||
bool first_time = FALSE; /* data/conn appears first time on socket */
|
||||
|
||||
|
|
@ -362,7 +362,7 @@ static CURLMcode mev_pollset_diff(struct Curl_multi *multi,
|
|||
entry->conn ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
for(j = 0; j < prev_ps->num; j++) {
|
||||
for(j = 0; j < prev_ps->n; j++) {
|
||||
if(s == prev_ps->sockets[j]) {
|
||||
last_action = prev_ps->actions[j];
|
||||
break;
|
||||
|
|
@ -377,11 +377,11 @@ static CURLMcode mev_pollset_diff(struct Curl_multi *multi,
|
|||
}
|
||||
|
||||
/* Handle changes to sockets the transfer is NO LONGER interested in. */
|
||||
for(i = 0; i < prev_ps->num; i++) {
|
||||
for(i = 0; i < prev_ps->n; i++) {
|
||||
bool stillused = FALSE;
|
||||
|
||||
s = prev_ps->sockets[i];
|
||||
for(j = 0; j < ps->num; j++) {
|
||||
for(j = 0; j < ps->n; j++) {
|
||||
if(s == ps->sockets[j]) {
|
||||
/* socket is still supervised */
|
||||
stillused = TRUE;
|
||||
|
|
@ -437,15 +437,19 @@ static CURLMcode mev_pollset_diff(struct Curl_multi *multi,
|
|||
} /* for loop over num */
|
||||
|
||||
/* Remember for next time */
|
||||
memcpy(prev_ps, ps, sizeof(*prev_ps));
|
||||
Curl_pollset_move(prev_ps, ps);
|
||||
return CURLM_OK;
|
||||
}
|
||||
|
||||
static void mev_pollset_dtor(void *key, size_t klen, void *entry)
|
||||
{
|
||||
struct easy_pollset *ps = entry;
|
||||
(void)key;
|
||||
(void)klen;
|
||||
free(entry);
|
||||
if(ps) {
|
||||
Curl_pollset_cleanup(ps);
|
||||
free(ps);
|
||||
}
|
||||
}
|
||||
|
||||
static struct easy_pollset*
|
||||
|
|
@ -453,7 +457,7 @@ mev_add_new_conn_pollset(struct connectdata *conn)
|
|||
{
|
||||
struct easy_pollset *ps;
|
||||
|
||||
ps = calloc(1, sizeof(*ps));
|
||||
ps = Curl_pollset_create();
|
||||
if(!ps)
|
||||
return NULL;
|
||||
if(Curl_conn_meta_set(conn, CURL_META_MEV_POLLSET, ps, mev_pollset_dtor))
|
||||
|
|
@ -466,7 +470,7 @@ mev_add_new_xfer_pollset(struct Curl_easy *data)
|
|||
{
|
||||
struct easy_pollset *ps;
|
||||
|
||||
ps = calloc(1, sizeof(*ps));
|
||||
ps = Curl_pollset_create();
|
||||
if(!ps)
|
||||
return NULL;
|
||||
if(Curl_meta_set(data, CURL_META_MEV_POLLSET, ps, mev_pollset_dtor))
|
||||
|
|
@ -486,42 +490,47 @@ mev_get_last_pollset(struct Curl_easy *data,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void mev_init_cur_pollset(struct easy_pollset *ps,
|
||||
struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
memset(ps, 0, sizeof(*ps));
|
||||
if(conn)
|
||||
Curl_conn_adjust_pollset(data, conn, ps);
|
||||
else if(data)
|
||||
Curl_multi_getsock(data, ps, "ev assess");
|
||||
}
|
||||
|
||||
static CURLMcode mev_assess(struct Curl_multi *multi,
|
||||
struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
if(multi && multi->socket_cb) {
|
||||
struct easy_pollset ps, *last_ps;
|
||||
struct easy_pollset ps, *last_ps;
|
||||
CURLMcode res = CURLM_OK;
|
||||
|
||||
mev_init_cur_pollset(&ps, data, conn);
|
||||
last_ps = mev_get_last_pollset(data, conn);
|
||||
if(!multi || !multi->socket_cb)
|
||||
return CURLM_OK;
|
||||
|
||||
if(!last_ps && ps.num) {
|
||||
if(conn)
|
||||
last_ps = mev_add_new_conn_pollset(conn);
|
||||
else
|
||||
last_ps = mev_add_new_xfer_pollset(data);
|
||||
if(!last_ps)
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
Curl_pollset_init(&ps);
|
||||
if(conn) {
|
||||
CURLcode r = Curl_conn_adjust_pollset(data, conn, &ps);
|
||||
if(r) {
|
||||
res = (r == CURLE_OUT_OF_MEMORY) ?
|
||||
CURLM_OUT_OF_MEMORY : CURLM_INTERNAL_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(last_ps)
|
||||
return mev_pollset_diff(multi, data, conn, &ps, last_ps);
|
||||
else
|
||||
DEBUGASSERT(!ps.num);
|
||||
}
|
||||
return CURLM_OK;
|
||||
else if(data)
|
||||
Curl_multi_pollset(data, &ps, "ev assess");
|
||||
last_ps = mev_get_last_pollset(data, conn);
|
||||
|
||||
if(!last_ps && ps.n) {
|
||||
if(conn)
|
||||
last_ps = mev_add_new_conn_pollset(conn);
|
||||
else
|
||||
last_ps = mev_add_new_xfer_pollset(data);
|
||||
if(!last_ps) {
|
||||
res = CURLM_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if(last_ps)
|
||||
res = mev_pollset_diff(multi, data, conn, &ps, last_ps);
|
||||
else
|
||||
DEBUGASSERT(!ps.n);
|
||||
out:
|
||||
Curl_pollset_cleanup(&ps);
|
||||
return res;
|
||||
}
|
||||
|
||||
CURLMcode Curl_multi_ev_assess_xfer(struct Curl_multi *multi,
|
||||
|
|
|
|||
|
|
@ -72,12 +72,6 @@ typedef enum {
|
|||
MSTATE_LAST /* 18 - not a true state, never use this */
|
||||
} CURLMstate;
|
||||
|
||||
/* we support N sockets per easy handle. Set the corresponding bit to what
|
||||
action we should wait for */
|
||||
#define MAX_SOCKSPEREASYHANDLE 5
|
||||
#define GETSOCK_READABLE (0x00ff)
|
||||
#define GETSOCK_WRITABLE (0xff00)
|
||||
|
||||
#define CURLPIPE_ANY (CURLPIPE_MULTIPLEX)
|
||||
|
||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
||||
|
|
|
|||
|
|
@ -53,20 +53,6 @@ struct Curl_multi *Curl_multi_handle(unsigned int xfer_table_size,
|
|||
size_t dnssize,
|
||||
size_t sesssize);
|
||||
|
||||
/* the write bits start at bit 16 for the *getsock() bitmap */
|
||||
#define GETSOCK_WRITEBITSTART 16
|
||||
|
||||
#define GETSOCK_BLANK 0 /* no bits set */
|
||||
|
||||
/* set the bit for the given sock number to make the bitmap for writable */
|
||||
#define GETSOCK_WRITESOCK(x) (1 << (GETSOCK_WRITEBITSTART + (x)))
|
||||
|
||||
/* set the bit for the given sock number to make the bitmap for readable */
|
||||
#define GETSOCK_READSOCK(x) (1 << (x))
|
||||
|
||||
/* mask for checking if read and/or write is set for index x */
|
||||
#define GETSOCK_MASK_RW(x) (GETSOCK_READSOCK(x)|GETSOCK_WRITESOCK(x))
|
||||
|
||||
/**
|
||||
* Let the multi handle know that the socket is about to be closed.
|
||||
* The multi will then remove anything it knows about the socket, so
|
||||
|
|
@ -86,9 +72,9 @@ CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
|
|||
/* Return the value of the CURLMOPT_MAX_CONCURRENT_STREAMS option */
|
||||
unsigned int Curl_multi_max_concurrent_streams(struct Curl_multi *multi);
|
||||
|
||||
void Curl_multi_getsock(struct Curl_easy *data,
|
||||
struct easy_pollset *ps,
|
||||
const char *caller);
|
||||
CURLMcode Curl_multi_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps,
|
||||
const char *caller);
|
||||
|
||||
/**
|
||||
* Borrow the transfer buffer from the multi, suitable
|
||||
|
|
|
|||
|
|
@ -126,10 +126,10 @@ const struct Curl_handler Curl_handler_ldap = {
|
|||
oldap_connect, /* connect_it */
|
||||
oldap_connecting, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* proto_pollset */
|
||||
ZERO_NULL, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
oldap_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -156,10 +156,10 @@ const struct Curl_handler Curl_handler_ldaps = {
|
|||
oldap_connect, /* connect_it */
|
||||
oldap_connecting, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* proto_pollset */
|
||||
ZERO_NULL, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
oldap_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
|
|||
|
|
@ -397,19 +397,13 @@ CURLcode Curl_pp_readresp(struct Curl_easy *data,
|
|||
return result;
|
||||
}
|
||||
|
||||
int Curl_pp_getsock(struct Curl_easy *data,
|
||||
struct pingpong *pp, curl_socket_t *socks)
|
||||
CURLcode Curl_pp_pollset(struct Curl_easy *data,
|
||||
struct pingpong *pp,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
socks[0] = conn->sock[FIRSTSOCKET];
|
||||
|
||||
if(pp->sendleft) {
|
||||
/* write mode */
|
||||
return GETSOCK_WRITESOCK(0);
|
||||
}
|
||||
|
||||
/* read mode */
|
||||
return GETSOCK_READSOCK(0);
|
||||
int flags = pp->sendleft ? CURL_POLL_OUT : CURL_POLL_IN;
|
||||
return Curl_pollset_change(data, ps, data->conn->sock[FIRSTSOCKET],
|
||||
flags, 0);
|
||||
}
|
||||
|
||||
bool Curl_pp_needs_flush(struct Curl_easy *data,
|
||||
|
|
|
|||
|
|
@ -147,8 +147,9 @@ CURLcode Curl_pp_flushsend(struct Curl_easy *data,
|
|||
/* call this when a pingpong connection is disconnected */
|
||||
CURLcode Curl_pp_disconnect(struct pingpong *pp);
|
||||
|
||||
int Curl_pp_getsock(struct Curl_easy *data, struct pingpong *pp,
|
||||
curl_socket_t *socks);
|
||||
CURLcode Curl_pp_pollset(struct Curl_easy *data,
|
||||
struct pingpong *pp,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
|||
31
lib/pop3.c
31
lib/pop3.c
|
|
@ -153,8 +153,8 @@ static CURLcode pop3_connect(struct Curl_easy *data, bool *done);
|
|||
static CURLcode pop3_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool dead);
|
||||
static CURLcode pop3_multi_statemach(struct Curl_easy *data, bool *done);
|
||||
static int pop3_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks);
|
||||
static CURLcode pop3_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
static CURLcode pop3_doing(struct Curl_easy *data, bool *dophase_done);
|
||||
static CURLcode pop3_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
|
@ -186,10 +186,10 @@ const struct Curl_handler Curl_handler_pop3 = {
|
|||
pop3_connect, /* connect_it */
|
||||
pop3_multi_statemach, /* connecting */
|
||||
pop3_doing, /* doing */
|
||||
pop3_getsock, /* proto_getsock */
|
||||
pop3_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
pop3_pollset, /* proto_pollset */
|
||||
pop3_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
pop3_disconnect, /* disconnect */
|
||||
pop3_write, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -217,10 +217,10 @@ const struct Curl_handler Curl_handler_pop3s = {
|
|||
pop3_connect, /* connect_it */
|
||||
pop3_multi_statemach, /* connecting */
|
||||
pop3_doing, /* doing */
|
||||
pop3_getsock, /* proto_getsock */
|
||||
pop3_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
pop3_pollset, /* proto_pollset */
|
||||
pop3_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
pop3_disconnect, /* disconnect */
|
||||
pop3_write, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -1269,13 +1269,12 @@ static CURLcode pop3_block_statemach(struct Curl_easy *data,
|
|||
}
|
||||
|
||||
/* For the POP3 "protocol connect" and "doing" phases only */
|
||||
static int pop3_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks)
|
||||
static CURLcode pop3_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN);
|
||||
if(pop3c)
|
||||
return Curl_pp_getsock(data, &pop3c->pp, socks);
|
||||
return GETSOCK_BLANK;
|
||||
struct pop3_conn *pop3c =
|
||||
Curl_conn_meta_get(data->conn, CURL_META_POP3_CONN);
|
||||
return pop3c ? Curl_pp_pollset(data, &pop3c->pp, ps) : CURLE_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
|||
20
lib/rtsp.c
20
lib/rtsp.c
|
|
@ -83,8 +83,8 @@ struct RTSP {
|
|||
static CURLcode rtsp_do(struct Curl_easy *data, bool *done);
|
||||
static CURLcode rtsp_done(struct Curl_easy *data, CURLcode, bool premature);
|
||||
static CURLcode rtsp_connect(struct Curl_easy *data, bool *done);
|
||||
static int rtsp_getsock_do(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks);
|
||||
static CURLcode rtsp_do_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
/*
|
||||
* Parse and write out an RTSP response.
|
||||
|
|
@ -110,13 +110,11 @@ static unsigned int rtsp_conncheck(struct Curl_easy *data,
|
|||
/* this returns the socket to wait for in the DO and DOING state for the multi
|
||||
interface and then we are always _sending_ a request and thus we wait for
|
||||
the single socket to become writable only */
|
||||
static int rtsp_getsock_do(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t *socks)
|
||||
static CURLcode rtsp_do_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
/* write mode */
|
||||
(void)data;
|
||||
socks[0] = conn->sock[FIRSTSOCKET];
|
||||
return GETSOCK_WRITESOCK(0);
|
||||
return Curl_pollset_add_out(data, ps, data->conn->sock[FIRSTSOCKET]);
|
||||
}
|
||||
|
||||
static
|
||||
|
|
@ -137,10 +135,10 @@ const struct Curl_handler Curl_handler_rtsp = {
|
|||
rtsp_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
rtsp_getsock_do, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* proto_pollset */
|
||||
rtsp_do_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
ZERO_NULL, /* disconnect */
|
||||
rtsp_rtp_write_resp, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
|
|||
235
lib/select.c
235
lib/select.c
|
|
@ -41,6 +41,7 @@
|
|||
#include "urldata.h"
|
||||
#include "connect.h"
|
||||
#include "select.h"
|
||||
#include "curl_trc.h"
|
||||
#include "curlx/timediff.h"
|
||||
#include "curlx/wait.h"
|
||||
#include "curlx/warnless.h"
|
||||
|
|
@ -423,7 +424,7 @@ CURLcode Curl_pollfds_add_ps(struct curl_pollfds *cpfds,
|
|||
|
||||
DEBUGASSERT(cpfds);
|
||||
DEBUGASSERT(ps);
|
||||
for(i = 0; i < ps->num; i++) {
|
||||
for(i = 0; i < ps->n; i++) {
|
||||
short events = 0;
|
||||
if(ps->actions[i] & CURL_POLL_IN)
|
||||
events |= POLLIN;
|
||||
|
|
@ -481,7 +482,7 @@ unsigned int Curl_waitfds_add_ps(struct Curl_waitfds *cwfds,
|
|||
|
||||
DEBUGASSERT(cwfds);
|
||||
DEBUGASSERT(ps);
|
||||
for(i = 0; i < ps->num; i++) {
|
||||
for(i = 0; i < ps->n; i++) {
|
||||
short events = 0;
|
||||
if(ps->actions[i] & CURL_POLL_IN)
|
||||
events |= CURL_WAIT_POLLIN;
|
||||
|
|
@ -492,3 +493,233 @@ unsigned int Curl_waitfds_add_ps(struct Curl_waitfds *cwfds,
|
|||
}
|
||||
return need;
|
||||
}
|
||||
|
||||
void Curl_pollset_reset(struct easy_pollset *ps)
|
||||
{
|
||||
unsigned int i;
|
||||
ps->n = 0;
|
||||
#ifdef DEBUGBUILD
|
||||
DEBUGASSERT(ps->init == CURL_EASY_POLLSET_MAGIC);
|
||||
#endif
|
||||
DEBUGASSERT(ps->count);
|
||||
for(i = 0; i < ps->count; i++)
|
||||
ps->sockets[i] = CURL_SOCKET_BAD;
|
||||
memset(ps->actions, 0, ps->count * sizeof(ps->actions[0]));
|
||||
}
|
||||
|
||||
void Curl_pollset_init(struct easy_pollset *ps)
|
||||
{
|
||||
#ifdef DEBUGBUILD
|
||||
ps->init = CURL_EASY_POLLSET_MAGIC;
|
||||
#endif
|
||||
ps->sockets = ps->def_sockets;
|
||||
ps->actions = ps->def_actions;
|
||||
ps->count = CURL_ARRAYSIZE(ps->def_sockets);
|
||||
ps->n = 0;
|
||||
Curl_pollset_reset(ps);
|
||||
}
|
||||
|
||||
struct easy_pollset *Curl_pollset_create(void)
|
||||
{
|
||||
struct easy_pollset *ps = calloc(1, sizeof(*ps));
|
||||
if(ps)
|
||||
Curl_pollset_init(ps);
|
||||
return ps;
|
||||
}
|
||||
|
||||
void Curl_pollset_cleanup(struct easy_pollset *ps)
|
||||
{
|
||||
#ifdef DEBUGBUILD
|
||||
DEBUGASSERT(ps->init == CURL_EASY_POLLSET_MAGIC);
|
||||
#endif
|
||||
if(ps->sockets != ps->def_sockets) {
|
||||
free(ps->sockets);
|
||||
ps->sockets = ps->def_sockets;
|
||||
}
|
||||
if(ps->actions != ps->def_actions) {
|
||||
free(ps->actions);
|
||||
ps->actions = ps->def_actions;
|
||||
}
|
||||
ps->count = CURL_ARRAYSIZE(ps->def_sockets);
|
||||
Curl_pollset_reset(ps);
|
||||
}
|
||||
|
||||
void Curl_pollset_move(struct easy_pollset *to, struct easy_pollset *from)
|
||||
{
|
||||
Curl_pollset_cleanup(to); /* deallocate anything in to */
|
||||
if(from->sockets != from->def_sockets) {
|
||||
DEBUGASSERT(from->actions != from->def_actions);
|
||||
to->sockets = from->sockets;
|
||||
to->actions = from->actions;
|
||||
to->count = from->count;
|
||||
to->n = from->n;
|
||||
Curl_pollset_init(from);
|
||||
}
|
||||
else {
|
||||
DEBUGASSERT(to->sockets == to->def_sockets);
|
||||
DEBUGASSERT(to->actions == to->def_actions);
|
||||
memcpy(to->sockets, from->sockets, to->count * sizeof(to->sockets[0]));
|
||||
memcpy(to->actions, from->actions, to->count * sizeof(to->actions[0]));
|
||||
to->n = from->n;
|
||||
Curl_pollset_init(from);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
CURLcode Curl_pollset_change(struct Curl_easy *data,
|
||||
struct easy_pollset *ps, curl_socket_t sock,
|
||||
int add_flags, int remove_flags)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
DEBUGASSERT(ps->init == CURL_EASY_POLLSET_MAGIC);
|
||||
#endif
|
||||
|
||||
(void)data;
|
||||
DEBUGASSERT(VALID_SOCK(sock));
|
||||
if(!VALID_SOCK(sock))
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
DEBUGASSERT(add_flags <= (CURL_POLL_IN|CURL_POLL_OUT));
|
||||
DEBUGASSERT(remove_flags <= (CURL_POLL_IN|CURL_POLL_OUT));
|
||||
DEBUGASSERT((add_flags&remove_flags) == 0); /* no overlap */
|
||||
for(i = 0; i < ps->n; ++i) {
|
||||
if(ps->sockets[i] == sock) {
|
||||
ps->actions[i] &= (unsigned char)(~remove_flags);
|
||||
ps->actions[i] |= (unsigned char)add_flags;
|
||||
/* all gone? remove socket */
|
||||
if(!ps->actions[i]) {
|
||||
if((i + 1) < ps->n) {
|
||||
memmove(&ps->sockets[i], &ps->sockets[i + 1],
|
||||
(ps->n - (i + 1)) * sizeof(ps->sockets[0]));
|
||||
memmove(&ps->actions[i], &ps->actions[i + 1],
|
||||
(ps->n - (i + 1)) * sizeof(ps->actions[0]));
|
||||
}
|
||||
--ps->n;
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
}
|
||||
/* not present */
|
||||
if(add_flags) {
|
||||
if(i >= ps->count) { /* need to grow */
|
||||
unsigned int new_count = CURLMAX(ps->count * 2, 8);
|
||||
curl_socket_t *nsockets;
|
||||
unsigned char *nactions;
|
||||
|
||||
CURL_TRC_M(data, "growing pollset capacity from %u to %u",
|
||||
ps->count, new_count);
|
||||
if(new_count <= ps->count)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
nsockets = calloc(new_count, sizeof(nsockets[0]));
|
||||
if(!nsockets)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
nactions = calloc(new_count, sizeof(nactions[0]));
|
||||
if(!nactions) {
|
||||
free(nsockets);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
memcpy(nsockets, ps->sockets, ps->count * sizeof(ps->sockets[0]));
|
||||
memcpy(nactions, ps->actions, ps->count * sizeof(ps->actions[0]));
|
||||
if(ps->sockets != ps->def_sockets)
|
||||
free(ps->sockets);
|
||||
ps->sockets = nsockets;
|
||||
if(ps->actions != ps->def_actions)
|
||||
free(ps->actions);
|
||||
ps->actions = nactions;
|
||||
ps->count = new_count;
|
||||
}
|
||||
DEBUGASSERT(i < ps->count);
|
||||
if(i < ps->count) {
|
||||
ps->sockets[i] = sock;
|
||||
ps->actions[i] = (unsigned char)add_flags;
|
||||
ps->n = i + 1;
|
||||
}
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode Curl_pollset_set(struct Curl_easy *data,
|
||||
struct easy_pollset *ps, curl_socket_t sock,
|
||||
bool do_in, bool do_out)
|
||||
{
|
||||
return Curl_pollset_change(data, ps, sock,
|
||||
(do_in ? CURL_POLL_IN : 0)|
|
||||
(do_out ? CURL_POLL_OUT : 0),
|
||||
(!do_in ? CURL_POLL_IN : 0)|
|
||||
(!do_out ? CURL_POLL_OUT : 0));
|
||||
}
|
||||
|
||||
int Curl_pollset_poll(struct Curl_easy *data,
|
||||
struct easy_pollset *ps,
|
||||
timediff_t timeout_ms)
|
||||
{
|
||||
struct pollfd *pfds;
|
||||
unsigned int i, npfds;
|
||||
int result;
|
||||
|
||||
(void)data;
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(data->conn);
|
||||
|
||||
if(!ps->n)
|
||||
return curlx_wait_ms(timeout_ms);
|
||||
|
||||
pfds = calloc(ps->n, sizeof(*pfds));
|
||||
if(!pfds)
|
||||
return -1;
|
||||
|
||||
npfds = 0;
|
||||
for(i = 0; i < ps->n; ++i) {
|
||||
short events = 0;
|
||||
if(ps->actions[i] & CURL_POLL_IN) {
|
||||
events |= POLLIN;
|
||||
}
|
||||
if(ps->actions[i] & CURL_POLL_OUT) {
|
||||
events |= POLLOUT;
|
||||
}
|
||||
if(events) {
|
||||
pfds[npfds].fd = ps->sockets[i];
|
||||
pfds[npfds].events = events;
|
||||
++npfds;
|
||||
}
|
||||
}
|
||||
|
||||
result = Curl_poll(pfds, npfds, timeout_ms);
|
||||
free(pfds);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Curl_pollset_check(struct Curl_easy *data,
|
||||
struct easy_pollset *ps, curl_socket_t sock,
|
||||
bool *pwant_read, bool *pwant_write)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
(void)data;
|
||||
DEBUGASSERT(VALID_SOCK(sock));
|
||||
for(i = 0; i < ps->n; ++i) {
|
||||
if(ps->sockets[i] == sock) {
|
||||
*pwant_read = !!(ps->actions[i] & CURL_POLL_IN);
|
||||
*pwant_write = !!(ps->actions[i] & CURL_POLL_OUT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
*pwant_read = *pwant_write = FALSE;
|
||||
}
|
||||
|
||||
bool Curl_pollset_want_read(struct Curl_easy *data,
|
||||
struct easy_pollset *ps,
|
||||
curl_socket_t sock)
|
||||
{
|
||||
unsigned int i;
|
||||
(void)data;
|
||||
for(i = 0; i < ps->n; ++i) {
|
||||
if((ps->sockets[i] == sock) && (ps->actions[i] & CURL_POLL_IN))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
|||
84
lib/select.h
84
lib/select.h
|
|
@ -110,6 +110,90 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms);
|
|||
} while(0)
|
||||
#endif
|
||||
|
||||
|
||||
/* Keep the sockets to poll for an easy handle.
|
||||
* `actions` are bitmaps of CURL_POLL_IN and CURL_POLL_OUT.
|
||||
* Starts with small capacity, grows on demand.
|
||||
*/
|
||||
#define EZ_POLLSET_DEF_COUNT 2
|
||||
|
||||
struct easy_pollset {
|
||||
curl_socket_t *sockets;
|
||||
unsigned char *actions;
|
||||
unsigned int n;
|
||||
unsigned int count;
|
||||
#ifdef DEBUGBUILD
|
||||
int init;
|
||||
#endif
|
||||
curl_socket_t def_sockets[EZ_POLLSET_DEF_COUNT];
|
||||
unsigned char def_actions[EZ_POLLSET_DEF_COUNT];
|
||||
};
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#define CURL_EASY_POLLSET_MAGIC 0x7a657370
|
||||
#endif
|
||||
|
||||
|
||||
/* allocate and initialise */
|
||||
struct easy_pollset *Curl_pollset_create(void);
|
||||
|
||||
/* Initialize before first use */
|
||||
void Curl_pollset_init(struct easy_pollset *ps);
|
||||
/* Free any allocated resources */
|
||||
void Curl_pollset_cleanup(struct easy_pollset *ps);
|
||||
/* Reset to an empty pollset */
|
||||
void Curl_pollset_reset(struct easy_pollset *ps);
|
||||
/* Move pollset from to pollset to, replacing all in to,
|
||||
* leaving from empty. */
|
||||
void Curl_pollset_move(struct easy_pollset *to, struct easy_pollset *from);
|
||||
|
||||
/* Change the poll flags (CURL_POLL_IN/CURL_POLL_OUT) to the poll set for
|
||||
* socket `sock`. If the socket is not already part of the poll set, it
|
||||
* will be added.
|
||||
* If the socket is present and all poll flags are cleared, it will be removed.
|
||||
*/
|
||||
CURLcode Curl_pollset_change(struct Curl_easy *data,
|
||||
struct easy_pollset *ps, curl_socket_t sock,
|
||||
int add_flags, int remove_flags);
|
||||
|
||||
CURLcode Curl_pollset_set(struct Curl_easy *data,
|
||||
struct easy_pollset *ps, curl_socket_t sock,
|
||||
bool do_in, bool do_out);
|
||||
|
||||
#define Curl_pollset_add_in(data, ps, sock) \
|
||||
Curl_pollset_change((data), (ps), (sock), CURL_POLL_IN, 0)
|
||||
#define Curl_pollset_add_out(data, ps, sock) \
|
||||
Curl_pollset_change((data), (ps), (sock), CURL_POLL_OUT, 0)
|
||||
#define Curl_pollset_add_inout(data, ps, sock) \
|
||||
Curl_pollset_change((data), (ps), (sock), \
|
||||
CURL_POLL_IN|CURL_POLL_OUT, 0)
|
||||
#define Curl_pollset_set_in_only(data, ps, sock) \
|
||||
Curl_pollset_change((data), (ps), (sock), \
|
||||
CURL_POLL_IN, CURL_POLL_OUT)
|
||||
#define Curl_pollset_set_out_only(data, ps, sock) \
|
||||
Curl_pollset_change((data), (ps), (sock), \
|
||||
CURL_POLL_OUT, CURL_POLL_IN)
|
||||
|
||||
/* return < = on error, 0 on timeout or how many sockets are ready */
|
||||
int Curl_pollset_poll(struct Curl_easy *data,
|
||||
struct easy_pollset *ps,
|
||||
timediff_t timeout_ms);
|
||||
|
||||
/**
|
||||
* Check if the pollset, as is, wants to read and/or write regarding
|
||||
* the given socket.
|
||||
*/
|
||||
void Curl_pollset_check(struct Curl_easy *data,
|
||||
struct easy_pollset *ps, curl_socket_t sock,
|
||||
bool *pwant_read, bool *pwant_write);
|
||||
|
||||
/**
|
||||
* Return TRUE if the pollset contains socket with CURL_POLL_IN.
|
||||
*/
|
||||
bool Curl_pollset_want_read(struct Curl_easy *data,
|
||||
struct easy_pollset *ps,
|
||||
curl_socket_t sock);
|
||||
|
||||
struct curl_pollfds {
|
||||
struct pollfd *pfds;
|
||||
unsigned int n;
|
||||
|
|
|
|||
29
lib/smb.c
29
lib/smb.c
|
|
@ -36,6 +36,7 @@
|
|||
#include "connect.h"
|
||||
#include "progress.h"
|
||||
#include "transfer.h"
|
||||
#include "select.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "curl_ntlm_core.h"
|
||||
#include "escape.h"
|
||||
|
|
@ -298,8 +299,8 @@ static CURLcode smb_connect(struct Curl_easy *data, bool *done);
|
|||
static CURLcode smb_connection_state(struct Curl_easy *data, bool *done);
|
||||
static CURLcode smb_do(struct Curl_easy *data, bool *done);
|
||||
static CURLcode smb_request_state(struct Curl_easy *data, bool *done);
|
||||
static int smb_getsock(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t *socks);
|
||||
static CURLcode smb_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
static CURLcode smb_parse_url_path(struct Curl_easy *data,
|
||||
struct smb_conn *smbc,
|
||||
struct smb_request *req);
|
||||
|
|
@ -316,10 +317,10 @@ const struct Curl_handler Curl_handler_smb = {
|
|||
smb_connect, /* connect_it */
|
||||
smb_connection_state, /* connecting */
|
||||
smb_request_state, /* doing */
|
||||
smb_getsock, /* proto_getsock */
|
||||
smb_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
smb_pollset, /* proto_pollset */
|
||||
smb_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -345,10 +346,10 @@ const struct Curl_handler Curl_handler_smbs = {
|
|||
smb_connect, /* connect_it */
|
||||
smb_connection_state, /* connecting */
|
||||
smb_request_state, /* doing */
|
||||
smb_getsock, /* proto_getsock */
|
||||
smb_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
smb_pollset, /* proto_pollset */
|
||||
smb_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -1204,12 +1205,10 @@ static CURLcode smb_request_state(struct Curl_easy *data, bool *done)
|
|||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static int smb_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks)
|
||||
static CURLcode smb_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
(void)data;
|
||||
socks[0] = conn->sock[FIRSTSOCKET];
|
||||
return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0);
|
||||
return Curl_pollset_add_inout(data, ps, data->conn->sock[FIRSTSOCKET]);
|
||||
}
|
||||
|
||||
static CURLcode smb_do(struct Curl_easy *data, bool *done)
|
||||
|
|
|
|||
30
lib/smtp.c
30
lib/smtp.c
|
|
@ -157,8 +157,8 @@ static CURLcode smtp_connect(struct Curl_easy *data, bool *done);
|
|||
static CURLcode smtp_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool dead);
|
||||
static CURLcode smtp_multi_statemach(struct Curl_easy *data, bool *done);
|
||||
static int smtp_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks);
|
||||
static CURLcode smtp_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
static CURLcode smtp_doing(struct Curl_easy *data, bool *dophase_done);
|
||||
static CURLcode smtp_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
|
@ -192,10 +192,10 @@ const struct Curl_handler Curl_handler_smtp = {
|
|||
smtp_connect, /* connect_it */
|
||||
smtp_multi_statemach, /* connecting */
|
||||
smtp_doing, /* doing */
|
||||
smtp_getsock, /* proto_getsock */
|
||||
smtp_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
smtp_pollset, /* proto_pollset */
|
||||
smtp_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
smtp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -223,10 +223,10 @@ const struct Curl_handler Curl_handler_smtps = {
|
|||
smtp_connect, /* connect_it */
|
||||
smtp_multi_statemach, /* connecting */
|
||||
smtp_doing, /* doing */
|
||||
smtp_getsock, /* proto_getsock */
|
||||
smtp_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
smtp_pollset, /* proto_pollset */
|
||||
smtp_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
smtp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -1413,12 +1413,12 @@ static CURLcode smtp_block_statemach(struct Curl_easy *data,
|
|||
}
|
||||
|
||||
/* For the SMTP "protocol connect" and "doing" phases only */
|
||||
static int smtp_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks)
|
||||
static CURLcode smtp_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct smtp_conn *smtpc = Curl_conn_meta_get(conn, CURL_META_SMTP_CONN);
|
||||
return smtpc ?
|
||||
Curl_pp_getsock(data, &smtpc->pp, socks) : GETSOCK_BLANK;
|
||||
struct smtp_conn *smtpc =
|
||||
Curl_conn_meta_get(data->conn, CURL_META_SMTP_CONN);
|
||||
return smtpc ? Curl_pp_pollset(data, &smtpc->pp, ps) : CURLE_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
|||
12
lib/socks.c
12
lib/socks.c
|
|
@ -1161,11 +1161,12 @@ static CURLcode socks_proxy_cf_connect(struct Curl_cfilter *cf,
|
|||
return result;
|
||||
}
|
||||
|
||||
static void socks_cf_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
static CURLcode socks_cf_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct socks_state *sx = cf->ctx;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(!cf->connected && sx) {
|
||||
/* If we are not connected, the filter below is and has nothing
|
||||
|
|
@ -1177,13 +1178,14 @@ static void socks_cf_adjust_pollset(struct Curl_cfilter *cf,
|
|||
case CONNECT_AUTH_READ:
|
||||
case CONNECT_REQ_READ:
|
||||
case CONNECT_REQ_READ_MORE:
|
||||
Curl_pollset_set_in_only(data, ps, sock);
|
||||
result = Curl_pollset_set_in_only(data, ps, sock);
|
||||
break;
|
||||
default:
|
||||
Curl_pollset_set_out_only(data, ps, sock);
|
||||
result = Curl_pollset_set_out_only(data, ps, sock);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void socks_proxy_cf_close(struct Curl_cfilter *cf,
|
||||
|
|
|
|||
|
|
@ -188,10 +188,10 @@ const struct Curl_handler Curl_handler_telnet = {
|
|||
ZERO_NULL, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* proto_pollset */
|
||||
ZERO_NULL, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
|
|||
27
lib/tftp.c
27
lib/tftp.c
|
|
@ -160,8 +160,8 @@ static CURLcode tftp_setup_connection(struct Curl_easy *data,
|
|||
struct connectdata *conn);
|
||||
static CURLcode tftp_multi_statemach(struct Curl_easy *data, bool *done);
|
||||
static CURLcode tftp_doing(struct Curl_easy *data, bool *dophase_done);
|
||||
static int tftp_getsock(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t *socks);
|
||||
static CURLcode tftp_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
static CURLcode tftp_translate_code(tftp_error_t error);
|
||||
|
||||
|
||||
|
|
@ -178,10 +178,10 @@ const struct Curl_handler Curl_handler_tftp = {
|
|||
tftp_connect, /* connect_it */
|
||||
tftp_multi_statemach, /* connecting */
|
||||
tftp_doing, /* doing */
|
||||
tftp_getsock, /* proto_getsock */
|
||||
tftp_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
tftp_pollset, /* proto_pollset */
|
||||
tftp_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
ZERO_NULL, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -1074,19 +1074,10 @@ static CURLcode tftp_done(struct Curl_easy *data, CURLcode status,
|
|||
return result;
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
*
|
||||
* tftp_getsock
|
||||
*
|
||||
* The getsock callback
|
||||
*
|
||||
**********************************************************/
|
||||
static int tftp_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks)
|
||||
static CURLcode tftp_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
(void)data;
|
||||
socks[0] = conn->sock[FIRSTSOCKET];
|
||||
return GETSOCK_READSOCK(0);
|
||||
return Curl_pollset_add_in(data, ps, data->conn->sock[FIRSTSOCKET]);
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
|
|
|
|||
|
|
@ -34,8 +34,6 @@ void Curl_init_CONNECT(struct Curl_easy *data);
|
|||
CURLcode Curl_pretransfer(struct Curl_easy *data);
|
||||
|
||||
CURLcode Curl_sendrecv(struct Curl_easy *data, struct curltime *nowp);
|
||||
int Curl_single_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks);
|
||||
CURLcode Curl_retry_request(struct Curl_easy *data, char **url);
|
||||
bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc);
|
||||
|
||||
|
|
|
|||
|
|
@ -471,15 +471,6 @@ struct hostname {
|
|||
#define FIRSTSOCKET 0
|
||||
#define SECONDARYSOCKET 1
|
||||
|
||||
/* Polling requested by an easy handle.
|
||||
* `action` is CURL_POLL_IN, CURL_POLL_OUT or CURL_POLL_INOUT.
|
||||
*/
|
||||
struct easy_pollset {
|
||||
curl_socket_t sockets[MAX_SOCKSPEREASYHANDLE];
|
||||
unsigned int num;
|
||||
unsigned char actions[MAX_SOCKSPEREASYHANDLE];
|
||||
};
|
||||
|
||||
/*
|
||||
* Specific protocol handler.
|
||||
*/
|
||||
|
|
@ -516,24 +507,24 @@ struct Curl_handler {
|
|||
|
||||
/* Called from the multi interface during the PROTOCONNECT phase, and it
|
||||
should then return a proper fd set */
|
||||
int (*proto_getsock)(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks);
|
||||
CURLcode (*proto_pollset)(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
/* Called from the multi interface during the DOING phase, and it should
|
||||
then return a proper fd set */
|
||||
int (*doing_getsock)(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks);
|
||||
CURLcode (*doing_pollset)(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
/* Called from the multi interface during the DO_MORE phase, and it should
|
||||
then return a proper fd set */
|
||||
int (*domore_getsock)(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks);
|
||||
CURLcode (*domore_pollset)(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
/* Called from the multi interface during the DO_DONE, PERFORM and
|
||||
WAITPERFORM phases, and it should then return a proper fd set. Not setting
|
||||
this will make libcurl use the generic default one. */
|
||||
int (*perform_getsock)(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks);
|
||||
CURLcode (*perform_pollset)(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
/* This function *MAY* be set to a protocol-dependent function that is run
|
||||
* by the curl_disconnect(), as a step in the disconnection. If the handler
|
||||
|
|
|
|||
|
|
@ -898,15 +898,16 @@ static CURLcode check_and_set_expiry(struct Curl_cfilter *cf,
|
|||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void cf_ngtcp2_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
static CURLcode cf_ngtcp2_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct cf_ngtcp2_ctx *ctx = cf->ctx;
|
||||
bool want_recv, want_send;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(!ctx->qconn)
|
||||
return;
|
||||
return CURLE_OK;
|
||||
|
||||
Curl_pollset_check(data, ps, ctx->q.sockfd, &want_recv, &want_send);
|
||||
if(!want_send && !Curl_bufq_is_empty(&ctx->q.sendbuf))
|
||||
|
|
@ -926,9 +927,10 @@ static void cf_ngtcp2_adjust_pollset(struct Curl_cfilter *cf,
|
|||
want_send = (!s_exhaust && want_send) ||
|
||||
!Curl_bufq_is_empty(&ctx->q.sendbuf);
|
||||
|
||||
Curl_pollset_set(data, ps, ctx->q.sockfd, want_recv, want_send);
|
||||
result = Curl_pollset_set(data, ps, ctx->q.sockfd, want_recv, want_send);
|
||||
CF_DATA_RESTORE(cf, save);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int cb_h3_stream_close(nghttp3_conn *conn, int64_t sid,
|
||||
|
|
|
|||
|
|
@ -2266,11 +2266,12 @@ out:
|
|||
return alive;
|
||||
}
|
||||
|
||||
static void cf_osslq_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
static CURLcode cf_osslq_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct cf_osslq_ctx *ctx = cf->ctx;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(!ctx->tls.ossl.ssl) {
|
||||
/* NOP */
|
||||
|
|
@ -2278,9 +2279,9 @@ static void cf_osslq_adjust_pollset(struct Curl_cfilter *cf,
|
|||
else if(!cf->connected) {
|
||||
/* during handshake, transfer has not started yet. we always
|
||||
* add our socket for polling if SSL wants to send/recv */
|
||||
Curl_pollset_set(data, ps, ctx->q.sockfd,
|
||||
SSL_net_read_desired(ctx->tls.ossl.ssl),
|
||||
SSL_net_write_desired(ctx->tls.ossl.ssl));
|
||||
result = Curl_pollset_set(data, ps, ctx->q.sockfd,
|
||||
SSL_net_read_desired(ctx->tls.ossl.ssl),
|
||||
SSL_net_write_desired(ctx->tls.ossl.ssl));
|
||||
}
|
||||
else {
|
||||
/* once connected, we only modify the socket if it is present.
|
||||
|
|
@ -2288,15 +2289,16 @@ static void cf_osslq_adjust_pollset(struct Curl_cfilter *cf,
|
|||
bool want_recv, want_send;
|
||||
Curl_pollset_check(data, ps, ctx->q.sockfd, &want_recv, &want_send);
|
||||
if(want_recv || want_send) {
|
||||
Curl_pollset_set(data, ps, ctx->q.sockfd,
|
||||
SSL_net_read_desired(ctx->tls.ossl.ssl),
|
||||
SSL_net_write_desired(ctx->tls.ossl.ssl));
|
||||
result = Curl_pollset_set(data, ps, ctx->q.sockfd,
|
||||
SSL_net_read_desired(ctx->tls.ossl.ssl),
|
||||
SSL_net_write_desired(ctx->tls.ossl.ssl));
|
||||
}
|
||||
else if(ctx->need_recv || ctx->need_send) {
|
||||
Curl_pollset_set(data, ps, ctx->q.sockfd,
|
||||
ctx->need_recv, ctx->need_send);
|
||||
result = Curl_pollset_set(data, ps, ctx->q.sockfd,
|
||||
ctx->need_recv, ctx->need_send);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode cf_osslq_query(struct Curl_cfilter *cf,
|
||||
|
|
|
|||
|
|
@ -1142,15 +1142,16 @@ static bool stream_is_writeable(struct Curl_cfilter *cf,
|
|||
ctx->qconn, (curl_uint64_t)stream->id, 1) > 0);
|
||||
}
|
||||
|
||||
static void cf_quiche_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
static CURLcode cf_quiche_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct cf_quiche_ctx *ctx = cf->ctx;
|
||||
bool want_recv, want_send;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(!ctx->qconn)
|
||||
return;
|
||||
return CURLE_OK;
|
||||
|
||||
Curl_pollset_check(data, ps, ctx->q.sockfd, &want_recv, &want_send);
|
||||
if(want_recv || want_send) {
|
||||
|
|
@ -1165,8 +1166,9 @@ static void cf_quiche_adjust_pollset(struct Curl_cfilter *cf,
|
|||
want_send = (!s_exhaust && want_send) ||
|
||||
!Curl_bufq_is_empty(&ctx->q.sendbuf);
|
||||
|
||||
Curl_pollset_set(data, ps, ctx->q.sockfd, want_recv, want_send);
|
||||
result = Curl_pollset_set(data, ps, ctx->q.sockfd, want_recv, want_send);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -125,8 +125,8 @@ CURLcode sftp_perform(struct Curl_easy *data,
|
|||
bool *connected,
|
||||
bool *dophase_done);
|
||||
|
||||
static int myssh_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *sock);
|
||||
static CURLcode myssh_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
static void myssh_block2waitfor(struct connectdata *conn,
|
||||
struct ssh_conn *sshc,
|
||||
bool block);
|
||||
|
|
@ -148,10 +148,10 @@ const struct Curl_handler Curl_handler_scp = {
|
|||
myssh_connect, /* connect_it */
|
||||
myssh_multi_statemach, /* connecting */
|
||||
scp_doing, /* doing */
|
||||
myssh_getsock, /* proto_getsock */
|
||||
myssh_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
myssh_getsock, /* perform_getsock */
|
||||
myssh_pollset, /* proto_pollset */
|
||||
myssh_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
myssh_pollset, /* perform_pollset */
|
||||
scp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -177,10 +177,10 @@ const struct Curl_handler Curl_handler_sftp = {
|
|||
myssh_connect, /* connect_it */
|
||||
myssh_multi_statemach, /* connecting */
|
||||
sftp_doing, /* doing */
|
||||
myssh_getsock, /* proto_getsock */
|
||||
myssh_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
myssh_getsock, /* perform_getsock */
|
||||
myssh_pollset, /* proto_pollset */
|
||||
myssh_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
myssh_pollset, /* perform_pollset */
|
||||
sftp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -2390,25 +2390,19 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
|
|||
|
||||
/* called by the multi interface to figure out what socket(s) to wait for and
|
||||
for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
|
||||
static int myssh_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
curl_socket_t *sock)
|
||||
static CURLcode myssh_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
int bitmap = GETSOCK_BLANK;
|
||||
(void)data;
|
||||
sock[0] = conn->sock[FIRSTSOCKET];
|
||||
|
||||
if(conn->waitfor & KEEP_RECV)
|
||||
bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
|
||||
|
||||
if(conn->waitfor & KEEP_SEND)
|
||||
bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
|
||||
|
||||
if(!conn->waitfor)
|
||||
bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
|
||||
|
||||
DEBUGF(infof(data, "ssh_getsock -> %x", bitmap));
|
||||
return bitmap;
|
||||
int flags = 0;
|
||||
if(data->conn->waitfor & KEEP_RECV)
|
||||
flags |= CURL_POLL_IN;
|
||||
if(data->conn->waitfor & KEEP_SEND)
|
||||
flags |= CURL_POLL_OUT;
|
||||
if(!data->conn->waitfor)
|
||||
flags |= CURL_POLL_OUT;
|
||||
return flags ?
|
||||
Curl_pollset_change(data, ps, data->conn->sock[FIRSTSOCKET], flags, 0) :
|
||||
CURLE_OK;
|
||||
}
|
||||
|
||||
static void myssh_block2waitfor(struct connectdata *conn,
|
||||
|
|
@ -2437,7 +2431,7 @@ static CURLcode myssh_multi_statemach(struct Curl_easy *data,
|
|||
struct connectdata *conn = data->conn;
|
||||
struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN);
|
||||
struct SSHPROTO *sshp = Curl_meta_get(data, CURL_META_SSH_EASY);
|
||||
bool block; /* we store the status and use that to provide a ssh_getsock()
|
||||
bool block; /* we store the status and use that to provide a ssh_pollset()
|
||||
implementation */
|
||||
CURLcode result;
|
||||
|
||||
|
|
|
|||
|
|
@ -99,8 +99,8 @@ static CURLcode sftp_disconnect(struct Curl_easy *data,
|
|||
struct connectdata *conn, bool dead);
|
||||
static CURLcode sftp_perform(struct Curl_easy *data, bool *connected,
|
||||
bool *dophase_done);
|
||||
static int ssh_getsock(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t *sock);
|
||||
static CURLcode ssh_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
static CURLcode ssh_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
static void ssh_attach(struct Curl_easy *data, struct connectdata *conn);
|
||||
|
|
@ -119,10 +119,10 @@ const struct Curl_handler Curl_handler_scp = {
|
|||
ssh_connect, /* connect_it */
|
||||
ssh_multi_statemach, /* connecting */
|
||||
scp_doing, /* doing */
|
||||
ssh_getsock, /* proto_getsock */
|
||||
ssh_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ssh_getsock, /* perform_getsock */
|
||||
ssh_pollset, /* proto_pollset */
|
||||
ssh_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ssh_pollset, /* perform_pollset */
|
||||
scp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -150,10 +150,10 @@ const struct Curl_handler Curl_handler_sftp = {
|
|||
ssh_connect, /* connect_it */
|
||||
ssh_multi_statemach, /* connecting */
|
||||
sftp_doing, /* doing */
|
||||
ssh_getsock, /* proto_getsock */
|
||||
ssh_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ssh_getsock, /* perform_getsock */
|
||||
ssh_pollset, /* proto_pollset */
|
||||
ssh_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ssh_pollset, /* perform_pollset */
|
||||
sftp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -3087,22 +3087,17 @@ static CURLcode ssh_statemachine(struct Curl_easy *data,
|
|||
|
||||
/* called by the multi interface to figure out what socket(s) to wait for and
|
||||
for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
|
||||
static int ssh_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
curl_socket_t *sock)
|
||||
static CURLcode ssh_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
int bitmap = GETSOCK_BLANK;
|
||||
(void)data;
|
||||
|
||||
sock[0] = conn->sock[FIRSTSOCKET];
|
||||
|
||||
if(conn->waitfor & KEEP_RECV)
|
||||
bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
|
||||
|
||||
if(conn->waitfor & KEEP_SEND)
|
||||
bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
|
||||
|
||||
return bitmap;
|
||||
int flags = 0;
|
||||
if(data->conn->waitfor & KEEP_RECV)
|
||||
flags |= CURL_POLL_IN;
|
||||
if(data->conn->waitfor & KEEP_SEND)
|
||||
flags |= CURL_POLL_OUT;
|
||||
return flags ?
|
||||
Curl_pollset_change(data, ps, data->conn->sock[FIRSTSOCKET], flags, 0) :
|
||||
CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -3139,7 +3134,7 @@ static CURLcode ssh_multi_statemach(struct Curl_easy *data, bool *done)
|
|||
struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN);
|
||||
struct SSHPROTO *sshp = Curl_meta_get(data, CURL_META_SSH_EASY);
|
||||
CURLcode result = CURLE_OK;
|
||||
bool block; /* we store the status and use that to provide a ssh_getsock()
|
||||
bool block; /* we store the status and use that to provide a ssh_pollset()
|
||||
implementation */
|
||||
if(!sshc || !sshp)
|
||||
return CURLE_FAILED_INIT;
|
||||
|
|
|
|||
|
|
@ -66,9 +66,8 @@ static CURLcode wsftp_doing(struct Curl_easy *data,
|
|||
static CURLcode wsftp_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool dead);
|
||||
static int wssh_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
curl_socket_t *sock);
|
||||
static CURLcode wssh_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
static CURLcode wssh_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
static void wssh_sshc_cleanup(struct ssh_conn *sshc);
|
||||
|
|
@ -87,10 +86,10 @@ const struct Curl_handler Curl_handler_scp = {
|
|||
wssh_connect, /* connect_it */
|
||||
wssh_multi_statemach, /* connecting */
|
||||
wscp_doing, /* doing */
|
||||
wssh_getsock, /* proto_getsock */
|
||||
wssh_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
wssh_getsock, /* perform_getsock */
|
||||
wssh_pollset, /* proto_pollset */
|
||||
wssh_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
wssh_pollset, /* perform_pollset */
|
||||
wscp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -118,10 +117,10 @@ const struct Curl_handler Curl_handler_sftp = {
|
|||
wssh_connect, /* connect_it */
|
||||
wssh_multi_statemach, /* connecting */
|
||||
wsftp_doing, /* doing */
|
||||
wssh_getsock, /* proto_getsock */
|
||||
wssh_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
wssh_getsock, /* perform_getsock */
|
||||
wssh_pollset, /* proto_pollset */
|
||||
wssh_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
wssh_pollset, /* perform_pollset */
|
||||
wsftp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
|
|
@ -932,7 +931,7 @@ static CURLcode wssh_multi_statemach(struct Curl_easy *data, bool *done)
|
|||
struct connectdata *conn = data->conn;
|
||||
struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN);
|
||||
CURLcode result = CURLE_OK;
|
||||
bool block; /* we store the status and use that to provide a ssh_getsock()
|
||||
bool block; /* we store the status and use that to provide a ssh_pollset()
|
||||
implementation */
|
||||
if(!sshc)
|
||||
return CURLE_FAILED_INIT;
|
||||
|
|
@ -1185,21 +1184,17 @@ static CURLcode wsftp_disconnect(struct Curl_easy *data,
|
|||
return result;
|
||||
}
|
||||
|
||||
static int wssh_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
curl_socket_t *sock)
|
||||
static CURLcode wssh_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
int bitmap = GETSOCK_BLANK;
|
||||
int dir = conn->waitfor;
|
||||
(void)data;
|
||||
sock[0] = conn->sock[FIRSTSOCKET];
|
||||
|
||||
if(dir == KEEP_RECV)
|
||||
bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
|
||||
else if(dir == KEEP_SEND)
|
||||
bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
|
||||
|
||||
return bitmap;
|
||||
int flags = 0;
|
||||
if(data->conn->waitfor & KEEP_RECV)
|
||||
flags |= CURL_POLL_IN;
|
||||
if(data->conn->waitfor & KEEP_SEND)
|
||||
flags |= CURL_POLL_OUT;
|
||||
return flags ?
|
||||
Curl_pollset_change(data, ps, data->conn->sock[FIRSTSOCKET], flags, 0) :
|
||||
CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_ssh_version(char *buffer, size_t buflen)
|
||||
|
|
|
|||
|
|
@ -503,26 +503,30 @@ void Curl_ssl_close_all(struct Curl_easy *data)
|
|||
Curl_ssl->close_all(data);
|
||||
}
|
||||
|
||||
void Curl_ssl_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
CURLcode Curl_ssl_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct ssl_connect_data *connssl = cf->ctx;
|
||||
|
||||
if(connssl->io_need) {
|
||||
curl_socket_t sock = Curl_conn_cf_get_socket(cf->next, data);
|
||||
CURLcode result = CURLE_OK;
|
||||
if(sock != CURL_SOCKET_BAD) {
|
||||
if(connssl->io_need & CURL_SSL_IO_NEED_SEND) {
|
||||
Curl_pollset_set_out_only(data, ps, sock);
|
||||
result = Curl_pollset_set_out_only(data, ps, sock);
|
||||
CURL_TRC_CF(data, cf, "adjust_pollset, POLLOUT fd=%" FMT_SOCKET_T,
|
||||
sock);
|
||||
}
|
||||
else {
|
||||
Curl_pollset_set_in_only(data, ps, sock);
|
||||
result = Curl_pollset_set_in_only(data, ps, sock);
|
||||
CURL_TRC_CF(data, cf, "adjust_pollset, POLLIN fd=%" FMT_SOCKET_T,
|
||||
sock);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* Selects an SSL crypto engine
|
||||
|
|
@ -902,13 +906,13 @@ static CURLcode multissl_connect(struct Curl_cfilter *cf,
|
|||
return Curl_ssl->do_connect(cf, data, done);
|
||||
}
|
||||
|
||||
static void multissl_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
static CURLcode multissl_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
if(multissl_setup(NULL))
|
||||
return;
|
||||
Curl_ssl->adjust_pollset(cf, data, ps);
|
||||
return CURLE_OK;
|
||||
return Curl_ssl->adjust_pollset(cf, data, ps);
|
||||
}
|
||||
|
||||
static void *multissl_get_internals(struct ssl_connect_data *connssl,
|
||||
|
|
@ -1545,16 +1549,18 @@ static CURLcode ssl_cf_shutdown(struct Curl_cfilter *cf,
|
|||
return result;
|
||||
}
|
||||
|
||||
static void ssl_cf_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
static CURLcode ssl_cf_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct ssl_connect_data *connssl = cf->ctx;
|
||||
struct cf_call_data save;
|
||||
CURLcode result;
|
||||
|
||||
CF_DATA_SAVE(save, cf, data);
|
||||
connssl->ssl_impl->adjust_pollset(cf, data, ps);
|
||||
result = connssl->ssl_impl->adjust_pollset(cf, data, ps);
|
||||
CF_DATA_RESTORE(cf, save);
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode ssl_cf_query(struct Curl_cfilter *cf,
|
||||
|
|
|
|||
|
|
@ -166,8 +166,8 @@ struct Curl_ssl {
|
|||
|
||||
/* During handshake/shutdown, adjust the pollset to include the socket
|
||||
* for POLLOUT or POLLIN as needed. Mandatory. */
|
||||
void (*adjust_pollset)(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
CURLcode (*adjust_pollset)(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
void *(*get_internals)(struct ssl_connect_data *connssl, CURLINFO info);
|
||||
void (*close)(struct Curl_cfilter *cf, struct Curl_easy *data);
|
||||
void (*close_all)(struct Curl_easy *data);
|
||||
|
|
@ -190,8 +190,9 @@ struct Curl_ssl {
|
|||
|
||||
extern const struct Curl_ssl *Curl_ssl;
|
||||
|
||||
void Curl_ssl_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
CURLcode Curl_ssl_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
/**
|
||||
* Get the SSL filter below the given one or NULL if there is none.
|
||||
|
|
|
|||
16
lib/ws.c
16
lib/ws.c
|
|
@ -1552,10 +1552,10 @@ const struct Curl_handler Curl_handler_ws = {
|
|||
Curl_http_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
Curl_http_getsock_do, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
ZERO_NULL, /* proto_pollset */
|
||||
Curl_http_do_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
ZERO_NULL, /* disconnect */
|
||||
Curl_http_write_resp, /* write_resp */
|
||||
Curl_http_write_resp_hd, /* write_resp_hd */
|
||||
|
|
@ -1579,10 +1579,10 @@ const struct Curl_handler Curl_handler_wss = {
|
|||
Curl_http_connect, /* connect_it */
|
||||
NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
NULL, /* proto_getsock */
|
||||
Curl_http_getsock_do, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
NULL, /* proto_pollset */
|
||||
Curl_http_do_pollset, /* doing_pollset */
|
||||
ZERO_NULL, /* domore_pollset */
|
||||
ZERO_NULL, /* perform_pollset */
|
||||
ZERO_NULL, /* disconnect */
|
||||
Curl_http_write_resp, /* write_resp */
|
||||
Curl_http_write_resp_hd, /* write_resp_hd */
|
||||
|
|
|
|||
|
|
@ -105,8 +105,10 @@ struct test_result {
|
|||
|
||||
static const struct test_case *current_tc;
|
||||
static struct test_result *current_tr;
|
||||
static int test_idx;
|
||||
|
||||
struct cf_test_ctx {
|
||||
int idx;
|
||||
int ai_family;
|
||||
int transport;
|
||||
char id[16];
|
||||
|
|
@ -151,13 +153,13 @@ static CURLcode cf_test_connect(struct Curl_cfilter *cf,
|
|||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void cf_test_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
static CURLcode cf_test_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
struct cf_test_ctx *ctx = cf->ctx;
|
||||
/* just for testing, give one socket with events back */
|
||||
(void)cf;
|
||||
Curl_pollset_set(data, ps, 1, TRUE, TRUE);
|
||||
return Curl_pollset_set(data, ps, ctx->idx, TRUE, TRUE);
|
||||
}
|
||||
|
||||
static CURLcode cf_test_create(struct Curl_cfilter **pcf,
|
||||
|
|
@ -196,6 +198,7 @@ static CURLcode cf_test_create(struct Curl_cfilter **pcf,
|
|||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
ctx->idx = test_idx++;
|
||||
ctx->ai_family = ai->ai_family;
|
||||
ctx->transport = transport;
|
||||
ctx->started = curlx_now();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue