Hi,

On Mon, Dec 20, 2021 at 6:41 PM Derick Rethans <der...@php.net> wrote:

> Literature since at least 2006 (Sara's Extending and Embedding PHP
> book), as well as numerous presentations that I have seen and given, and
> including the online PHP Internals Book
> (
> https://www.phpinternalsbook.com/php7/extensions_design/php_lifecycle.html),
>
> always expected that the MINIT (and MSHUTDOWN) functions are called once
> per worker process. However, PHP-FPM does not do that. It only calls
> extension's MINITs once in the main control process, but it *does* call
> an MSHUTDOWN for each worker process.


> In the past, this has already caused an issue where I couldn't create a
> monitoring thread in MINIT, and then wait for it to end in MSHUTDOWN, as
> MSHUTDOWN would wait on the same thread in each worker process, although
> only one was created in MINIT.
>
> The way how PHP-FPM handles this breaks the generally assumed "one
> MINIT, one MSHUTDOWN call" per process approach.
>

Yeah this is a bit unfortunate asymetry. It has got some slight advantages
like in case of preloading that is done just once instead of on each child
init. However there are most likely more disadvantages like the ones above
and also the fact that MINIT is often run under the root so it's not ideal
from the security point of view - especially when running 3rd party
extensions.


> In particular, in the case of Xdebug bug #2051 it creates a problem with
> the following set-up:
>
> 1. php.ini has a `xdebug.mode=off`
> 2. the pool configuration has a `php_admin_value[xdebug.mode] = debug`
>    directive
>
>
So this is actually mainly about the fact that fpm_php_apply_defines runs
after the MINIT. You might be able to tweak this but not sure if it
completely fixes the issue as there's another to way overwrite INI that
happens during the request. It is using FCGI env PHP_ADMIN_VALUE
(see fastcgi_ini_parser usage) so you might need to handle this case in
your code anyway. Basically you can't rely on the fact that INI stays the
same so you will probably have to add some logic to your RINIT to handle
this.


>
> My suggestion for a fix would be to emulate what Apache always did:
>
> One MINIT/MSHUTDOWN in the main control process (I think it needed that
> to be able to implement php_admin_value and php_value), and then
> additionally also in each worker process.
>

As I said above, it won't probably fully fix your problem but if you still
want to try to tackle it and move the MINIT, the way that I would do it is
to try to separate the whole sapi init logic and call it from the child
init as the first thing. If you want to experiment with using
php_admin_value before the module minit, then it might be worth to try put
fpm_php_init_child (or just the defines) to sapi startup callback before
calling php_module_startup so the main INIs are loads but it might be a bit
tricky to get worker pool config - it might need some extra globals maybe
for it. But not sure if that's gonna work (e.g. if the main INI files are
loaded at the sapi startup stage) and what will be impact on extensions.
I'd probably have to check it more and try it. Think it's also something
that could happen in master branch only as it's changing some fundamental
bits in FPM...

Regards

Jakub

Reply via email to