Certain things you take for granted:
The sun will come up.
Politicians are dishonest.
Resource destruction functions (fclose(), mysql_disconnect(), etc...) will actually shutdown their resources.

Guess which of those three you can't count on.

Seems that zend_list_delete(), which I (and many other extension writers) have relied on to actually delete list_entry objects from the resource hash, doesn't actually delete so much as it delref's. In general use cases this isn't really a problem since most resource IDs are only referenced once (by the zval* they were initially stored into). So calling zend_list_delete() in those cases actually does destroy it since --le->refcount == 0.

Using a very simple (and not entirely unlikely) bit of userspace code to force zval separation however, means that the first call to zend_list_delete() won't actually delete the resource. Consider this reproduction snippet:

<?php
 $fp1 = fopen('test', 'w');
 $fp2 = $fp1; /* Still a single zval* and le->refcount == 1 */
 $fp3 = &$fp1; /* Two zval*s now and le->refcount == 2 */

 fclose($fp1);

 /* le->refcount now == 1, and the file is still open
     File operations on $fp1, $fp2, or $fp3 will all succeed */
?>

Calling either unset($fp1); or unset($fp3); at this point would not trigger the destruction, however calling either both of them or just unset($fp2); alone would. Calling fclose() a second time on any of the variables would also work.

This behavior isn't unique to fclose(), several extensions which implement the resource type rely on zend_list_delete() in this way, and the specific naming of this function makes me a little curious: Did zend_list_delete() used to behave differently? Is there a specific motivation against modifying it to act like a genuine delete, then implementing a zend_list_delref() which behaves like the current zend_list_delete(), and modifying zval_dtor() implementations to use that instead.

Am I the only one mislead by the purpose of zend_list_delete()?

-Sara
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to