Req #60938 [Fbk->NoF]: xp_socket.c functions should respect pcntl signal handlers
| From: | php-bugs at lists dot php dot net | Date: | Sun, 05 Sep 2021 04:22:08 +0000 |
| Subject: | Req #60938 [Fbk->NoF]: xp_socket.c functions should respect pcntl signal handlers | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-236407@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=60938&edit=1
ID: 60938
Updated by: php-bugs@lists.php.net
Reported by: nasretdinov at gmail dot com
Summary: xp_socket.c functions should respect pcntl signal
handlers
-Status: Feedback
+Status: No Feedback
Type: Feature/Change Request
Package: PCNTL related
Operating System: *nix
PHP Version: 5.3.9
Assigned To: cmb
Private report: N
New Comment:
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
Previous Comments:
------------------------------------------------------------------------
[2021-08-24 14:18:12] cmb@php.net
Isn't this obsolete with the availability of pcntl_async_signals()
as of PHP 7.1.0?
------------------------------------------------------------------------
[2012-01-31 13:41:30] nasretdinov at gmail dot com
Description:
------------
Socket functions in xp_socket.c read and write indefinitely in case they received
any
signal (read/write returned EINTR). Example, from
php_sock_stream_wait_for_data():
while(1) {
retval = php_pollfd_for(sock->socket, PHP_POLLREADABLE, ptimeout);
if (retval == 0) sock->timeout_event = 1;
if (retval >= 0) break;
if (php_socket_errno() != EINTR) break;
}
The problem here is that this behavior is not compatible with pcntl signal
handling
because pcntl signals are implemented using ticks and this code actually does not
exit
even if we need to call signal handler.
Suggested fix for read() is to take into account existence of PCNTL and do the
following check:
if (php_socket_errno() != EINTR) break;
#ifdef PCNTL_G
else if(PCNTL_G(head)) break;
#endif
/* PCNTL_G(head) is pointer to a queue of signals
that were caught and will be processed after next tick.
This queue is empty if we do not register handlers for received signal.
*/
This fix (and adding ZEND_EXTERN_MODULE_GLOBALS(pcntl) to pcntl.c) gives the
expected result below
Test script:
---------------
<?php
declare(ticks = 1);
function sighandler($sig) {
echo "Caught signal $sig, exiting correctly\n";
exit(1);
}
pcntl_signal(SIGINT, 'sighandler', false);
pcntl_signal(SIGHUP, 'sighandler', false);
mysql_connect(); // assumes 'mysqlnd' as MySQL driver
mysql_query('SELECT SLEEP(100)'); // ignores SIGINT and SIGHUP for 100 sec
Expected result:
----------------
$ php test.php
^C
Warning: mysql_query(): MySQL server has gone away in test.php on line 14
Warning: mysql_query(): Error reading result set's header in
/Users/nasretdinov/test.php on line 14
Caught signal 2, exiting correctly
Actual result:
--------------
$ php
^C
# ...after 100 sec...
Caught signal 2, exiting correctly
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=60938&edit=1