Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:26810 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 33887 invoked by uid 1010); 6 Dec 2006 08:41:38 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 33872 invoked from network); 6 Dec 2006 08:41:38 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 6 Dec 2006 08:41:38 -0000 Authentication-Results: pb1.pair.com header.from=rquadling@googlemail.com; sender-id=pass; domainkeys=good Authentication-Results: pb1.pair.com smtp.mail=rquadling@googlemail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain googlemail.com designates 64.233.166.176 as permitted sender) DomainKey-Status: good X-DomainKeys: Ecelerity dk_validate implementing draft-delany-domainkeys-base-01 X-PHP-List-Original-Sender: rquadling@googlemail.com X-Host-Fingerprint: 64.233.166.176 py-out-1112.google.com Linux 2.4/2.6 Received: from [64.233.166.176] ([64.233.166.176:34457] helo=py-out-1112.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id EC/A5-26699-CF186754 for ; Wed, 06 Dec 2006 03:41:03 -0500 Received: by py-out-1112.google.com with SMTP id a25so80936pyi for ; Wed, 06 Dec 2006 00:40:26 -0800 (PST) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=googlemail.com; h=received:message-id:date:from:reply-to:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=krdgzqkSGuJBCLxYgh6sLB44SOC4RVe810hhOAbOZoePhzK4jbNyTEUHjqzc5Vr9rprDhLKvKGGpTmkU4Iz0gS7iWrKabD7/QZx7t0RJ/+KMHsIMkga84LuVSWUfSGXGGwyNRga5+bIzta2ZqbXI5/PdAITfckYeXhUK9XEaDes= Received: by 10.35.18.4 with SMTP id v4mr911957pyi.1165394426384; Wed, 06 Dec 2006 00:40:26 -0800 (PST) Received: by 10.35.93.18 with HTTP; Wed, 6 Dec 2006 00:40:26 -0800 (PST) Message-ID: <10845a340612060040g7b04b612vf4a89873a2478473@mail.gmail.com> Date: Wed, 6 Dec 2006 08:40:26 +0000 Reply-To: RQuadling@GoogleMail.com To: "Arnold Daniels" Cc: ceo@l-i-e.com, internals@lists.php.net In-Reply-To: <4575F689.3000709@adaniels.nl> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <4574C97F.8020507@adaniels.nl> <22319.204.16.229.245.1165342794.squirrel@www.l-i-e.com> <4575F689.3000709@adaniels.nl> Subject: Re: [PHP-DEV] destruction of cross-referenced objects From: rquadling@googlemail.com ("Richard Quadling") In user land, I have an abstract_object like this (http://rquadling.php1h.com/abstract_object.html). I've come from a Delphi environment so some of the code you see is based upon some of the ideas I see in the TObject class. There are some comments, but the basic idea is there. On 05/12/06, Arnold Daniels wrote: > > > Richard Lynch schreef: > > On Mon, December 4, 2006 7:21 pm, Arnold Daniels wrote: > > > >> I'm struggling with the problem that cross-referenced objects don't > >> get > >> destroyed. I can off course write a method to break the > >> cross-reference, > >> but that's kind of a pain in the butt, especially if the > >> cross-reference > >> is not strait forward. > >> > > > > Seems to me that a simple unset() on the data members in userland > > coude so PHPs refcount is decremented ought to do it... > > > > If a user creates a monstrous data structure and doesn't prune it, how > > much responsibility can PHP take for that? > > > > But maybe I'm just being naive. > > > > > I myself run into problems when implementing parent/child relationships > within object. I probably use PHP a bit different than the regular user > and therefor run into different problems, but with more elaborate > frameworks being build, I think more people will run into these kind of > problems. > Think about a DOM implementation fully in PHP (I'm not building that, > but just to give you an idea). Using uset() on each child wouldn't do > much good, since each also holds a parent/child relationship with its > children and therefor the child is not destroyed, meaning the parent is > not destroyed. To overcome this you need implement a method destroy(), > which runs through all property to see if it is a DOM object and call > the destroy() on it. But now imagine another class which has properties > with objects of all kinds of classes, some of which have parent/child > relationships. Now you need all these classes to implement some sort of > destroyable interface. I don't really like a solution like this. With > the destroy function you would still need to walk through the children > and call destroy forcing an unset in the destructor of the class, but > it's a step up. > > >> To solve this I'm thinking of building one of 2 thing: > >> 1.) Write a destroy() function which works much like a close function > >> on > >> a recourse, changing the object to a zval of type 'unknown'. > >> 2.) Specify that a property of an object does not count for the > >> reference count of a zval. > >> > > > > I don't think this is a Good Idea... > > > > Seems like it would be WAY too easy for userland code to end up with a > > 0 for the refcount and then GC kicks in. > > > > > Yes, that is what I want. If the parent object is unset, the parent > property of the child object should be set to unknown or something. But > I guess that the memory is freed and the zval isn't set to unknown and > you would just get unexpected results. > >> 3.) Write code to find cross-references and destroy the objects still. > >> > >> The first solution should be quite easy to implement, but you need to > >> call destroy() to free the object, introducing the whole alloc/free > >> responsibility thing to PHP. > >> > > > > Just use unset() for this, rather than introduce yet another confusing > > function. > > > > > >> The second solution would require some extra keyword within the class, > >> but require no special code within the code using the object. Though I > >> wouldn't have a clue how how to implement this or what would be the > >> consequences. > >> > > > > > >> I don't think the third solution is really possible or would at least > >> cause performance problems. > >> > > > > Finding a "dead branch" of cyclic structures is basic CS stuff. > > > > Add a second temp "refcount" and start walking the graph. > > > > Either you end up with something known to be in the GLOBAL scope, or > > you don't. > > > > It can take a long time, depending on the size of the graph, but it's > > just pointer-chasing and integer arithmetic, so shouldn't be THAT > > slow. > > > > > I don't really see this solution. I wouldn't unnecessarily find anything > in the GLOBAL scope. When using unset or returning from a function, a > check should be made to find if the variable is used within the scope of > the call stack, global or statically. To my knowledge (which is small > on the PHP internals subject) it is only possible to see how many > references to the object there are, not where there references are. > > Thank you for commenting on my e-mail. I hope you understand where I'm > coming from with this problem and understand why unset will not do. I > hope that you or perhaps someone else might have some other comments or > solutions I haven't yet thought of. > > Best regards, > Arnold > > -- ----- Richard Quadling Zend Certified Engineer : http://zend.com/zce.php?c=ZEND002498&r=213474731 "Standing on the shoulders of some very clever giants!"