@@ -106,9 +106,7 @@ public function __construct(CurlClientState $multi, $ch, array $options = null,
106106 if (0 < $ duration ) {
107107 if ($ execCounter === $ multi ->execCounter ) {
108108 $ multi ->execCounter = !\is_float ($ execCounter ) ? 1 + $ execCounter : \PHP_INT_MIN ;
109- foreach ($ multi ->handles as $ mh ) {
110- curl_multi_remove_handle ($ mh , $ ch );
111- }
109+ curl_multi_remove_handle ($ multi ->handle , $ ch );
112110 }
113111
114112 $ lastExpiry = end ($ multi ->pauseExpiries );
@@ -120,7 +118,7 @@ public function __construct(CurlClientState $multi, $ch, array $options = null,
120118 } else {
121119 unset($ multi ->pauseExpiries [(int ) $ ch ]);
122120 curl_pause ($ ch , \CURLPAUSE_CONT );
123- curl_multi_add_handle ($ multi ->handles [ 0 ] , $ ch );
121+ curl_multi_add_handle ($ multi ->handle , $ ch );
124122 }
125123 };
126124
@@ -174,7 +172,7 @@ public function __construct(CurlClientState $multi, $ch, array $options = null,
174172 // Schedule the request in a non-blocking way
175173 $ multi ->lastTimeout = null ;
176174 $ multi ->openHandles [$ id ] = [$ ch , $ options ];
177- curl_multi_add_handle ($ multi ->handles [ 0 ] , $ ch );
175+ curl_multi_add_handle ($ multi ->handle , $ ch );
178176
179177 $ this ->canary = new Canary (static function () use ($ ch , $ multi , $ id ) {
180178 unset($ multi ->pauseExpiries [$ id ], $ multi ->openHandles [$ id ], $ multi ->handlesActivity [$ id ]);
@@ -184,9 +182,7 @@ public function __construct(CurlClientState $multi, $ch, array $options = null,
184182 return ;
185183 }
186184
187- foreach ($ multi ->handles as $ mh ) {
188- curl_multi_remove_handle ($ mh , $ ch );
189- }
185+ curl_multi_remove_handle ($ multi ->handle , $ ch );
190186 curl_setopt_array ($ ch , [
191187 \CURLOPT_NOPROGRESS => true ,
192188 \CURLOPT_PROGRESSFUNCTION => null ,
@@ -268,7 +264,7 @@ public function __destruct()
268264 */
269265 private static function schedule (self $ response , array &$ runningResponses ): void
270266 {
271- if (isset ($ runningResponses [$ i = (int ) $ response ->multi ->handles [ 0 ] ])) {
267+ if (isset ($ runningResponses [$ i = (int ) $ response ->multi ->handle ])) {
272268 $ runningResponses [$ i ][1 ][$ response ->id ] = $ response ;
273269 } else {
274270 $ runningResponses [$ i ] = [$ response ->multi , [$ response ->id => $ response ]];
@@ -301,47 +297,39 @@ private static function perform(ClientState $multi, array &$responses = null): v
301297 try {
302298 self ::$ performing = true ;
303299 ++$ multi ->execCounter ;
300+ $ active = 0 ;
301+ while (\CURLM_CALL_MULTI_PERFORM === ($ err = curl_multi_exec ($ multi ->handle , $ active ))) {
302+ }
304303
305- foreach ($ multi ->handles as $ i => $ mh ) {
306- $ active = 0 ;
307- while (\CURLM_CALL_MULTI_PERFORM === ($ err = curl_multi_exec ($ mh , $ active ))) {
308- }
304+ if (\CURLM_OK !== $ err ) {
305+ throw new TransportException (curl_multi_strerror ($ err ));
306+ }
309307
310- if (\CURLM_OK !== $ err ) {
311- throw new TransportException (curl_multi_strerror ($ err ));
308+ while ($ info = curl_multi_info_read ($ multi ->handle )) {
309+ if (\CURLMSG_DONE !== $ info ['msg ' ]) {
310+ continue ;
312311 }
312+ $ result = $ info ['result ' ];
313+ $ id = (int ) $ ch = $ info ['handle ' ];
314+ $ waitFor = @curl_getinfo ($ ch , \CURLINFO_PRIVATE ) ?: '_0 ' ;
313315
314- while ($ info = curl_multi_info_read ($ mh )) {
315- if (\CURLMSG_DONE !== $ info ['msg ' ]) {
316- continue ;
317- }
318- $ result = $ info ['result ' ];
319- $ id = (int ) $ ch = $ info ['handle ' ];
320- $ waitFor = @curl_getinfo ($ ch , \CURLINFO_PRIVATE ) ?: '_0 ' ;
321-
322- if (\in_array ($ result , [\CURLE_SEND_ERROR , \CURLE_RECV_ERROR , /*CURLE_HTTP2*/ 16 , /*CURLE_HTTP2_STREAM*/ 92 ], true ) && $ waitFor [1 ] && 'C ' !== $ waitFor [0 ]) {
323- curl_multi_remove_handle ($ mh , $ ch );
324- $ waitFor [1 ] = (string ) ((int ) $ waitFor [1 ] - 1 ); // decrement the retry counter
325- curl_setopt ($ ch , \CURLOPT_PRIVATE , $ waitFor );
326- curl_setopt ($ ch , \CURLOPT_FORBID_REUSE , true );
327-
328- if (0 === curl_multi_add_handle ($ mh , $ ch )) {
329- continue ;
330- }
331- }
316+ if (\in_array ($ result , [\CURLE_SEND_ERROR , \CURLE_RECV_ERROR , /*CURLE_HTTP2*/ 16 , /*CURLE_HTTP2_STREAM*/ 92 ], true ) && $ waitFor [1 ] && 'C ' !== $ waitFor [0 ]) {
317+ curl_multi_remove_handle ($ multi ->handle , $ ch );
318+ $ waitFor [1 ] = (string ) ((int ) $ waitFor [1 ] - 1 ); // decrement the retry counter
319+ curl_setopt ($ ch , \CURLOPT_PRIVATE , $ waitFor );
320+ curl_setopt ($ ch , \CURLOPT_FORBID_REUSE , true );
332321
333- if (\ CURLE_RECV_ERROR === $ result && ' H ' === $ waitFor [ 0 ] && 400 <= ( $ responses [( int ) $ ch ]-> info [ ' http_code ' ] ?? 0 )) {
334- $ multi -> handlesActivity [ $ id ][] = new FirstChunk () ;
322+ if (0 === curl_multi_add_handle ( $ multi -> handle , $ ch )) {
323+ continue ;
335324 }
336-
337- $ multi ->handlesActivity [$ id ][] = null ;
338- $ multi ->handlesActivity [$ id ][] = \in_array ($ result , [\CURLE_OK , \CURLE_TOO_MANY_REDIRECTS ], true ) || '_0 ' === $ waitFor || curl_getinfo ($ ch , \CURLINFO_SIZE_DOWNLOAD ) === curl_getinfo ($ ch , \CURLINFO_CONTENT_LENGTH_DOWNLOAD ) ? null : new TransportException (sprintf ('%s for "%s". ' , curl_strerror ($ result ), curl_getinfo ($ ch , \CURLINFO_EFFECTIVE_URL )));
339325 }
340326
341- if (!$ active && 0 < $ i ) {
342- curl_multi_close ($ mh );
343- unset($ multi ->handles [$ i ]);
327+ if (\CURLE_RECV_ERROR === $ result && 'H ' === $ waitFor [0 ] && 400 <= ($ responses [(int ) $ ch ]->info ['http_code ' ] ?? 0 )) {
328+ $ multi ->handlesActivity [$ id ][] = new FirstChunk ();
344329 }
330+
331+ $ multi ->handlesActivity [$ id ][] = null ;
332+ $ multi ->handlesActivity [$ id ][] = \in_array ($ result , [\CURLE_OK , \CURLE_TOO_MANY_REDIRECTS ], true ) || '_0 ' === $ waitFor || curl_getinfo ($ ch , \CURLINFO_SIZE_DOWNLOAD ) === curl_getinfo ($ ch , \CURLINFO_CONTENT_LENGTH_DOWNLOAD ) ? null : new TransportException (sprintf ('%s for "%s". ' , curl_strerror ($ result ), curl_getinfo ($ ch , \CURLINFO_EFFECTIVE_URL )));
345333 }
346334 } finally {
347335 self ::$ performing = false ;
@@ -371,11 +359,11 @@ private static function select(ClientState $multi, float $timeout): int
371359
372360 unset($ multi ->pauseExpiries [$ id ]);
373361 curl_pause ($ multi ->openHandles [$ id ][0 ], \CURLPAUSE_CONT );
374- curl_multi_add_handle ($ multi ->handles [ 0 ] , $ multi ->openHandles [$ id ][0 ]);
362+ curl_multi_add_handle ($ multi ->handle , $ multi ->openHandles [$ id ][0 ]);
375363 }
376364 }
377365
378- if (0 !== $ selected = curl_multi_select ($ multi ->handles [ array_key_last ( $ multi -> handles )] , $ timeout )) {
366+ if (0 !== $ selected = curl_multi_select ($ multi ->handle , $ timeout )) {
379367 return $ selected ;
380368 }
381369
0 commit comments