@@ -1647,11 +1647,47 @@ function run_all_tests_parallel(array $test_files, array $env, $redir_tested): v
1647
1647
}
1648
1648
}
1649
1649
1650
+ /**
1651
+ * Calls fwrite and retries when network writes fail with errors such as "Resource temporarily unavailable"
1652
+ *
1653
+ * @param resource $stream the stream to fwrite to
1654
+ * @param string $data
1655
+ * @return int|false
1656
+ */
1657
+ function safe_fwrite ($ stream , string $ data )
1658
+ {
1659
+ // safe_fwrite was tested by adding $message['unused'] = str_repeat('a', 20_000_000); in send_message()
1660
+ // fwrites on tcp sockets can return false or less than strlen if the recipient is busy.
1661
+ // (e.g. fwrite(): Send of 577 bytes failed with errno=35 Resource temporarily unavailable)
1662
+ $ bytes_written = 0 ;
1663
+ while ($ bytes_written < strlen ($ data )) {
1664
+ $ n = @fwrite ($ stream , substr ($ data , $ bytes_written ));
1665
+ if ($ n === false ) {
1666
+ $ write_streams = [$ stream ];
1667
+ $ read_streams = [];
1668
+ $ except_streams = [];
1669
+ /* Wait for up to 10 seconds for the stream to be ready to write again. */
1670
+ $ result = stream_select ($ read_streams , $ write_streams , $ except_streams , 10 );
1671
+ if (!$ result ) {
1672
+ echo "ERROR: send_message() stream_select() failed \n" ;
1673
+ return false ;
1674
+ }
1675
+ $ n = @fwrite ($ stream , substr ($ data , $ bytes_written ));
1676
+ if ($ n === false ) {
1677
+ echo "ERROR: send_message() Failed to write chunk after stream_select: " . error_get_last ()['message ' ] . "\n" ;
1678
+ return false ;
1679
+ }
1680
+ }
1681
+ $ bytes_written += $ n ;
1682
+ }
1683
+ return $ bytes_written ;
1684
+ }
1685
+
1650
1686
function send_message ($ stream , array $ message ): void
1651
1687
{
1652
1688
$ blocking = stream_get_meta_data ($ stream )["blocked " ];
1653
1689
stream_set_blocking ($ stream , true );
1654
- fwrite ($ stream , base64_encode (serialize ($ message )) . "\n" );
1690
+ safe_fwrite ($ stream , base64_encode (serialize ($ message )) . "\n" );
1655
1691
stream_set_blocking ($ stream , $ blocking );
1656
1692
}
1657
1693
0 commit comments