]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
multi: fix pollset during RESOLVING phase
authorStefan Eissing <stefan@eissing.org>
Mon, 1 Jul 2024 12:56:27 +0000 (14:56 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 2 Jul 2024 09:17:38 +0000 (11:17 +0200)
- 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 #14047
Closes #14074

lib/cf-h2-proxy.c
lib/easy.c
lib/multi.c
lib/transfer.c
tests/unit/unit2600.c

index b944200f7ed6cbe84c7eeb7861c749b3967ee218..7613b7828d12803668e28bf043c1f5f7bbfd0bfe 100644 (file)
@@ -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;
 
index 22c51253999e2abbf40dc0242c63c8712eb72428..75bf091bcb72422715850cea7a8d841af7ee1d8a 100644 (file)
@@ -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
index 1a0cdeadac6ebfbb817b7ea6c2de6fc6e71a437e..273c1771ece4de2eb1043c4ae237aa0cb8cd6866 100644 (file)
@@ -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:
@@ -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);
   }
 }
 
index 3b554a81d926b643b086caa7febeb6a781a1b95b..4051f6743c784c8507efcf247b5d27a26417f2c8 100644 (file)
@@ -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
index 161e2cf19c63c554730511fdd24986f7e3c4c7a7..5c08d07d47aebf4bfc2fe5306f7b5058f7a907c0 100644 (file)
@@ -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,
@@ -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,