Next revision | Previous revision |
rfc:additional-context-in-pcntl-signal-handler [2016/06/16 02:13] – created bishop | rfc:additional-context-in-pcntl-signal-handler [2017/09/22 13:28] (current) – external edit 127.0.0.1 |
---|
====== PHP RFC: Additional Context in pcntl_signal Handler ====== | ====== PHP RFC: Additional Context in pcntl_signal Handler ====== |
* Version: 0.1 | * Version: 1.0 |
* Date: 2016-06-14 | * Date: 2016-06-14 |
* Author: David Walker <dave@mudsite.com>, Bishop Bettini <bishop@php.net> | * Authors: David Walker <dave@mudsite.com>, Bishop Bettini <bishop@php.net> |
* Status: Draft | * Status: Accepted |
* First Published at: http://wiki.php.net/rfc/additional-context-in-pcntl-signal-handler | * First Published at: http://wiki.php.net/rfc/additional-context-in-pcntl-signal-handler |
| |
| |
===== Introduction ===== | ===== Introduction ===== |
Modern UNIX kernels include additional context when delivering a signal, however the callable handler for [[http://php.net/manual/en/function.pcntl-signal.php|pcntl_signal]] does not receive this information. Developers coordinating multiple processes through signals must arrange to gather and send this same information using alternative channels, which is time-consuming, error-prone, and unnecessary. | Modern UNIX kernels include additional, contextual information when delivering a signal, however the callable handler for [[http://php.net/manual/en/function.pcntl-signal.php|pcntl_signal]] does not receive this information. Developers coordinating multiple processes through signals must arrange to gather and send this same information using alternative channels, which is time-consuming, error-prone, and unnecessary. |
| |
| |
===== Proposal ===== | ===== Proposal ===== |
Currently the signal handler receives only one formal argument, the [[http://man7.org/linux/man-pages/man7/signal.7.html|number of the signal]] sent. This proposal would add a second formal argument, an array of signal info as provided by the kernel, as seen here: | Currently the signal handler receives only one formal argument, the [[http://man7.org/linux/man-pages/man7/signal.7.html|number of the signal]] sent. This proposal would add a second formal argument, an array of signal info as provided by the underlying system's kernel. |
| |
| One possible use case is identifying the process ID of the signal //sender//, [[http://serverfault.com/a/94995/204816|described at the C level in this StackOverflow Q&A]] and implemented in PHP as seen here: |
| |
<file php> | <file php> |
<?php | <?php |
pcntl_signal(SIGUSR1, function ($signo, $siginfo) { | pcntl_signal(SIGUSR1, function ($signo, $siginfo) { |
print_r($siginfo); | printf('USR1 from %s', $siginfo['pid'] ?? 'unknown'); |
}); | }); |
posix_kill(0, SIGUSR1); | posix_kill(posix_getpid(), SIGUSR1); |
| pcntl_signal_dispatch(); |
</file> | </file> |
| |
| Other uses cases include identifying the cause of the signal (such as asynchronous I/O or timer expiration), identifying the sending user, and finding the consumed user & system time of an exited process. |
| |
The ''$siginfo'' array may contain [[https://www.mkssoftware.com/docs/man5/siginfo_t.5.asp|one or more of the following keys]], depending upon the system support for signal information and the nature of the sent signal: | The ''$siginfo'' array may contain [[https://www.mkssoftware.com/docs/man5/siginfo_t.5.asp|one or more of the following keys]], depending upon the system support for signal information and the nature of the sent signal: |
| |
* ''si_signo'', the signal number being sent (duplicates the first argument). | * **''signo''**, the signal number being sent (duplicates the first argument to the handler). |
* ''si_code'', the signal code, which depends upon the signal sent and provides context-specific reason //why// the signal was sent. | * **''code''**, the signal code, which depends upon the signal sent and provides context-specific reason //why// the signal was sent. |
* ''si_value'', the value for the code, if appropriate. | * **''value''**, the value for the code, if appropriate for the code. |
| * **'' errno''**, the error number associated with the signal, if appropriate for the signal //and// non-zero. |
| * **''pid''**, the process ID of the signal sender, if appropriate for the signal. |
| * **''uid''**, the real user ID of the signal sender, if appropriate for the signal. |
| * **''addr''**, the address at which the faulting signal occurred: only faulting signals like ''SIGFPE'' include this. |
| * **''status''**, the status code of an exiting process: only exiting signals like ''SIGCHLD'' include this. |
| * **''band''**, the asynchronous I/O band, if appropriate for the signal. |
| * **''mtime''**, the time of last data modification, if appropriate for the signal. |
| |
These are generally useful to a wide range of process interactions. | The naming of ''$siginfo'' and its keys comes from the ''pcntl_sigwaitinfo'' implementation. (So for example, "''signo''" in PHP comes from "''si_signo''" in the C structure, the leading "si_" having been removed by the PHP engine.) Name normalization does not apply to the values of the ''code'' field, as those represent system-specific values that follow no normative naming convention. |
| |
| Some older systems not conforming to [[https://standards.ieee.org/findstds/standard/1003.1-2001.html|POSIX.1-2001]] (where this structure was formally codified) may not support passing the additional context. In such case, PHP will pass ''null'' as the second argument to the handler. |
| |
| |
===== Proposed PHP Version(s) ===== | ===== Proposed PHP Version(s) ===== |
| |
Next PHP 7.x. | Next PHP 7.x, currently 7.1. |
| |
| |
==== To SAPIs ==== | ==== To SAPIs ==== |
| |
TODO | None. |
| |
| |
==== To Opcache ==== | ==== To Opcache ==== |
| |
TODO | None. |
| |
| ===== Discussion ===== |
| |
===== Open Issues ===== | Instead of updating ''pcntl_signal'', it was suggested to add a method ''pcntl_sigaction'', which would "keep maximum compatibility and eliminate unnecessary additional overhead". This suggestion was later withdrawn as perhaps adding more complication than the patch itself, though a later [[https://github.com/php/php-src/pull/1985|PR]] addressed parts of the suggestion. [[https://www.mail-archive.com/internals@lists.php.net/msg86504.html|Reference.]] |
| |
* Should we send ''null'' if the underlying system doesn't support ''siginfo_t'', or should we send ''array ()''? | Performance was raised as a concern. Having run tests through callgrind there is an additional 0.0001% cost for the feature. The profiled code defined an empty function, set the handler, and triggered the signal. Passing the additional information resulted in 2000 extra instructions, out of a total 13 million. This seems negligible compared to the cost of acquiring the same information through other means (eg message queues, temporary files, etc.). |
* Should we normalize the array keys (for example, ''si_signo'' is removed because it's a duplicate, and ''si_code'' becomes just ''code'')? | |
* Are there any effects to opcache or web SAPI? | |
| |
| ===== Open Issues ===== |
| |
| None. |
| |
===== Proposed Voting Choices ===== | ===== Proposed Voting Choices ===== |
Requires a 50%+1 majority. | Requires a 50%+1 majority. |
| |
| <doodle title="Provide additional context in pcntl signal handler?" auth="bishopb" voteType="single" closed="true"> |
| * Yes |
| * No |
| </doodle> |
| |
| Voting shall close one week after opening on Thursday, July 14, 2016 at 23:59 UTC. |
| |
===== Patches and Tests ===== | ===== Patches and Tests ===== |
| |
* [[https://github.com/bp1222/php-src|Work in Progress]] | * [[https://github.com/php/php-src/pull/1993|Implementation with tests.]] |
| |
| |
| |
* [[https://marc.info/?l=php-internals&m=146584196929126&w=2|Initial ping to php.internals]] | * [[https://marc.info/?l=php-internals&m=146584196929126&w=2|Initial ping to php.internals]] |
| * [[https://marc.info/?l=php-internals&m=146670242109688&w=2|Discussion]] |