zend_list_delete() doesn't.

From: Date: Thu, 08 Sep 2005 00:33:19 +0000
Subject: zend_list_delete() doesn't.
Groups: php.internals 
Request: Send a blank email to internals+get-18704@lists.php.net to get a copy of this message
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

« previous php.internals (#18704) next »