Welcome! Log In Create A New Profile

Advanced

[PHP-DEV] object destruction php 5.6 vs. 7.2

Posted by Nicolai Scheer 
Nicolai Scheer
[PHP-DEV] object destruction php 5.6 vs. 7.2
August 08, 2018 11:20PM
Hi,

I'm currently facing difficulties to migrate one of our extension from php
5.6 to 7.2.

Basically everything works fine.
The extension defines its own resource, and since it's object oriented,
stores the resource inside a member variable, i.e. we register the custom
resource using zend_list_insert followed by calling zend_update_property.

Every method then fetches the resource using zend_read_property and
zend_fetch_resource.
The resource itself has a dtor, which is registered
through zend_register_list_destructors_ex.

The class itself does not have a __destruct method.

Using php 5.6, when unsetting the object in userspace the resource dtor was
called immediately.

In php 7.2 this does not seem to be the case anymore - i.e. I see that the
resource dtor is called at script end, but not when unsetting the object in
userspace.
This results in php holding a lot of connections (that's what the resource
is about) up to the point where no new connection can be created (which is
bad).

I implemented and registered a __destruct method for testing purposes -
this one indeed gets called on object destruction triggered by unsetting
the variable in userspace.

So my question here ist: Can anyone give me an insight what is happening
here? I know, I posted not quite much information, but there must be
something fundamental I'm missing.

Basically I would expect, even if I do not implement a custom __destruct
method, that upon object deletion all members variables are deleted as well
- this would include the resource, and as such, the resource destructor
would be called.
That seems to be what is happening in php 5.6 but does not work in 7.2
anymore.

Of course I could move the code from the resource dtor to a __destruct
method - but what's the point in providing a resource destructor then (in
my case)? What is the correct way for a class to hold a (protected)
resource and make sure that resource gets destroyed correctly upon object
deletion?

Thanks for your help!

Greetings

Nico
Nikita Popov
Re: [PHP-DEV] object destruction php 5.6 vs. 7.2
August 11, 2018 11:10AM
On Wed, Aug 8, 2018 at 11:09 PM, Nicolai Scheer <[email protected]>
wrote:

> Hi,
>
> I'm currently facing difficulties to migrate one of our extension from php
> 5.6 to 7.2.
>
> Basically everything works fine.
> The extension defines its own resource, and since it's object oriented,
> stores the resource inside a member variable, i.e. we register the custom
> resource using zend_list_insert followed by calling zend_update_property.
>
> Every method then fetches the resource using zend_read_property and
> zend_fetch_resource.
> The resource itself has a dtor, which is registered
> through zend_register_list_destructors_ex.
>
> The class itself does not have a __destruct method.
>
> Using php 5.6, when unsetting the object in userspace the resource dtor was
> called immediately.
>
> In php 7.2 this does not seem to be the case anymore - i.e. I see that the
> resource dtor is called at script end, but not when unsetting the object in
> userspace.
> This results in php holding a lot of connections (that's what the resource
> is about) up to the point where no new connection can be created (which is
> bad).
>
> I implemented and registered a __destruct method for testing purposes -
> this one indeed gets called on object destruction triggered by unsetting
> the variable in userspace.
>
> So my question here ist: Can anyone give me an insight what is happening
> here? I know, I posted not quite much information, but there must be
> something fundamental I'm missing.
>
> Basically I would expect, even if I do not implement a custom __destruct
> method, that upon object deletion all members variables are deleted as well
> - this would include the resource, and as such, the resource destructor
> would be called.
> That seems to be what is happening in php 5.6 but does not work in 7.2
> anymore.
>
> Of course I could move the code from the resource dtor to a __destruct
> method - but what's the point in providing a resource destructor then (in
> my case)? What is the correct way for a class to hold a (protected)
> resource and make sure that resource gets destroyed correctly upon object
> deletion?
>
> Thanks for your help!
>
> Greetings
>
> Nico
>

My guess would be some kind of refcounting issue. For example
zend_update_property will already increment the refcount of the assigned
value itself. So if you create a value with refcount 1 and then assign it
to an object property, you likely need to do an explicit delref. If you
don't, then the value is leaked and your resource destructor will not run
until shutdown.

Nikita
Nicolai Scheer
Re: [PHP-DEV] object destruction php 5.6 vs. 7.2
August 13, 2018 04:10PM
Hi Nikita,

On Sat, 11 Aug 2018 at 11:03, Nikita Popov <[email protected]> wrote:

> On Wed, Aug 8, 2018 at 11:09 PM, Nicolai Scheer <[email protected]>
> wrote:
>
>> [resource destructor does not get called until shutdown]
>
>
> My guess would be some kind of refcounting issue. For example
> zend_update_property will already increment the refcount of the assigned
> value itself. So if you create a value with refcount 1 and then assign it
> to an object property, you likely need to do an explicit delref. If you
> don't, then the value is leaked and your resource destructor will not run
> until shutdown.
>
>
Yes, you're absolutely right.

I switched from:

zval *rsrc = NULL;
rsrc = zend_list_insert( conn_data, le_wmqe_connection_rc );
zend_update_property( php_wmqe_connection_entry, getThis(), "connection",
sizeof( "connection" ) - 1, rsrc );

to:

zend_resource *rsrc = NULL;
rsrc = zend_register_resource( conn_data, le_wmqe_connection_rc );
add_property_resource( getThis(), "connection", rsrc );

Now the refcounting seems to be appropriate and the resource dtor gets
called on object destruction.

I guess it would be better to leave resources all alone and switch to
custom object storage for that matter...

Thanks!

Greetings

Nico
Sorry, only registered users may post in this forum.

Click here to login