Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:18704 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 13260 invoked by uid 1010); 8 Sep 2005 00:34:32 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 13245 invoked from network); 8 Sep 2005 00:34:32 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 8 Sep 2005 00:34:32 -0000 X-Host-Fingerprint: 69.12.155.130 69-12-155-130.dsl.static.sonic.net Linux 2.4/2.6 Received: from ([69.12.155.130:1631] helo=pigeon.alphaweb.net) by pb1.pair.com (ecelerity 2.0 beta r(6323M)) with SMTP id C5/7A-23233-7178F134 for ; Wed, 07 Sep 2005 20:34:31 -0400 Received: from localhost ([127.0.0.1] helo=lighthammer) by pigeon.alphaweb.net with smtp (Exim 4.10) id 1ED9iT-0006qZ-00 for internals@lists.php.net; Wed, 07 Sep 2005 16:52:34 -0700 Message-ID: <002301c5b40d$0f75a570$85901a44@lighthammer> To: Date: Wed, 7 Sep 2005 17:33:19 -0700 MIME-Version: 1.0 Content-Type: text/plain; format=flowed; charset="iso-8859-1"; reply-type=original Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2900.2180 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2180 Subject: zend_list_delete() doesn't. From: pollita@php.net ("Sara Golemon") 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: 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