Skip to content

Commit

Permalink
multi: fix pollset during RESOLVING phase
Browse files Browse the repository at this point in the history
- add a DEBUGASSERT for when a transfer's pollset should not be empty.
- move write unpausing from transfer loop into curl_easy_pause. This
  make sure that the url_updatesocket() finds the correct state when
  updating socket events.
- fix HTTP/2 proxy during connect phase to set sockets correctly
- fix test2600 to simulate a socket set
- move write unpausing from transfer loop into curl_easy_pause. This
  make sure that the url_updatesocket() finds the correct state when
  updating socket events.
- waiting for the resolver to deliver might not involve any sockets to
  wait for. Do not generate a warning.

Fixes curl#14047
Closes curl#14074
  • Loading branch information
icing authored and bagder committed Jul 2, 2024
1 parent 75763a3 commit 480883c
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 12 deletions.
8 changes: 7 additions & 1 deletion lib/cf-h2-proxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -1230,7 +1230,13 @@ static void cf_h2_proxy_adjust_pollset(struct Curl_cfilter *cf,
curl_socket_t sock = Curl_conn_cf_get_socket(cf, data);
bool want_recv, want_send;

Curl_pollset_check(data, ps, sock, &want_recv, &want_send);
if(!cf->connected && ctx->h2) {
want_send = nghttp2_session_want_write(ctx->h2);
want_recv = nghttp2_session_want_read(ctx->h2);
}
else
Curl_pollset_check(data, ps, sock, &want_recv, &want_send);

if(ctx->h2 && (want_recv || want_send)) {
bool c_exhaust, s_exhaust;

Expand Down
5 changes: 5 additions & 0 deletions lib/easy.c
Original file line number Diff line number Diff line change
Expand Up @@ -1143,6 +1143,11 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
goto out;
}

if(!(k->keepon & KEEP_RECV_PAUSE) && Curl_cwriter_is_paused(data)) {
Curl_conn_ev_data_pause(data, FALSE);
result = Curl_cwriter_unpause(data);
}

out:
if(!result && !data->state.done && keep_changed)
/* This transfer may have been moved in or out of the bundle, update the
Expand Down
8 changes: 6 additions & 2 deletions lib/multi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1144,7 +1144,9 @@ static void multi_getsock(struct Curl_easy *data,

case MSTATE_RESOLVING:
Curl_pollset_add_socks(data, ps, Curl_resolv_getsock);
/* connection filters are not involved in this phase */
/* 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;
break;

case MSTATE_CONNECTING:
Expand Down Expand Up @@ -1195,8 +1197,10 @@ static void multi_getsock(struct Curl_easy *data,
break;
}

if(expect_sockets && !ps->num && !Curl_xfer_is_blocked(data)) {
if(expect_sockets && !ps->num &&
!(data->req.keepon & (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE))) {
infof(data, "WARNING: no socket in pollset, transfer may stall!");
DEBUGASSERT(0);
}
}

Expand Down
8 changes: 0 additions & 8 deletions lib/transfer.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,14 +414,6 @@ CURLcode Curl_readwrite(struct Curl_easy *data)
int didwhat = 0;
int select_bits;

/* Check if client writes had been paused and can resume now. */
if(!(k->keepon & KEEP_RECV_PAUSE) && Curl_cwriter_is_paused(data)) {
Curl_conn_ev_data_pause(data, FALSE);
result = Curl_cwriter_unpause(data);
if(result)
goto out;
}

if(data->state.select_bits) {
if(select_bits_paused(data, data->state.select_bits)) {
/* leave the bits unchanged, so they'll tell us what to do when
Expand Down
11 changes: 10 additions & 1 deletion tests/unit/unit2600.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,15 @@ 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)
{
/* just for testing, give one socket with events back */
(void)cf;
Curl_pollset_set(data, ps, 1, TRUE, TRUE);
}

static struct Curl_cftype cft_test = {
"TEST",
CF_TYPE_IP_CONNECT,
Expand All @@ -161,7 +170,7 @@ static struct Curl_cftype cft_test = {
Curl_cf_def_close,
Curl_cf_def_shutdown,
Curl_cf_def_get_host,
Curl_cf_def_adjust_pollset,
cf_test_adjust_pollset,
Curl_cf_def_data_pending,
Curl_cf_def_send,
Curl_cf_def_recv,
Expand Down

0 comments on commit 480883c

Please sign in to comment.