On 9/8/05, Stanislav Malyshev <[EMAIL PROTECTED]> 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. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php