I am upgrading a php extension to php 7, and I want to remove a resource that is been registered in the regular list using zend_register_resourceand later I am closing the resource using zend_list_close. the closing function looks like this:
PHP_FUNCTION(myFunc_cleanAndExit)
{
zval* rsrc = NULL;
...
int res = zend_parse_parameters(ZEND_NUM_ARGS() , "r", &rsrc );
if (res == FAILURE)
{
//handle it
}
...
zend_fetch_resource(Z_RES_P(rsrc), ./other args/..)
...
zend_list_close(Z_RES_P(rsrc));
...
}
originally in PHP 5, rsrc is removed using zend_hash_index_del( &EG( regular_list ), Z_RESVAL_P( rsrc)), so if this function is called twice, zend_parse_parameter returns FAILURE, because the resource is removed from the regular list and doesn't exist.
In PHP7, zend_list_close calls zend_resource_dtor (rsrc refcount is 2(why is is incremented? after registering resource it was 1)) and cleans any memory that rsrc is holding up. But, the fun happens when we call it twice like this:
myFunc_cleanAndExit($var-rsrc);
myFunc_cleanAndExit($var-rsrc);
the second time zend_parse_parameter doesn't return FAILURE(cause the resource hasn't been removed from the regular list), and the refcount of the rsrc is incremented to 3 after parsing it, the type is -1 and ptr is NULL(assigned in zend_resource_dtor in the first call). When I call get_resources() in PHP script, I get the rsrc with its id and the type UNKOWN, which in PHP5 rsrc becomes NULL. Here are my questions:
1- when are the resources removed from regular list? (if I manually remove it from regular list using zend_hash_index_del, it breaks in the zend_alloc)
2- Is this Ok to have the resource active with type UNKOWN after closing it once? doesn't eat up the memory? If not, what should I do to have it as NULL?
3- When I register the resource, and check its refcount, it is 1, but when I call the closing function, after zend_parse_parameter the refcount gets incremented, why?
Thanks
sample PHP script:
<?php
$var_rsrc = myFunc_startUp();
var_dump($var_rsrc); // resource(2) of type 'MyFunc'
myFunc_cleanAndExit($var_rsrc);
var_dump($var_rsrc); // resource(2) of type 'UNKOWN' (originally this was NULL)
myFunc_cleanAndExit($var_rsrc);
var_dump($var_rsrc); // resource(2) of type 'UNKOWN'