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

Reply via email to