Re: zend_list_delete() doesn't.

From: Date: Thu, 08 Sep 2005 12:18:19 +0000
Subject: Re: zend_list_delete() doesn't.
References: 1 2  Groups: php.internals 
Request: Send a blank email to internals+get-18718@lists.php.net to get a copy of this message
On 9/8/05, Stanislav Malyshev <stas@zend.com> wrote: > SG>><?php > SG>> $fp1 = fopen('test', 'w'); > SG>> $fp2 = $fp1; /* Still a single zval* and le->refcount == 1 */ > SG>> $fp3 = &$fp1; /* Two zval*s now and le->refcount == 2 */ > SG>> > SG>> fclose($fp1); > > I think this was discussed before, though I may be mistaken. We talked about this for the revised oci8 code; we adopted the practice of ZVAL_NULL()ing the zval just after we zend_list_delete() it, because the updated oci8 codebase can return zvals that reference the same underlying list resource. You could arrive at a similar kind of problem that Sara pointed out by doing this: $a = oci_connect(...); $b = oci_connect(...); // $b is a different zval from $a, but refs the same resource oci_close($a); // kills $a, but $b still owns a ref oci_close($a); // since $a still contains the resource id, this now kills the resource, // breaking $b We made oci_close() set $a to NULL before returning, to avoid this refcount skewing. > The problem > here is that you expect fclose to kill the resource, however $fp2 still > refers it. Looks like there should be two operations for resource - one is > usual delref called when variable is destroyed and second is "hard kill" > called when something like fclose is used and invalidating all referring > variables. I remember there were some issues with that, but I can't > rememebr what they were... IMO, "hard kill" doesn't really fit in a system that uses reference counts; you either use reference counts, or don't. There are cases (particularly in streams) where we hold the resource ID to guarantee that a pointer remains valid. Hard kill would break the reference counting contract and lead to a segv. --Wez.

« previous php.internals (#18718) next »