Re: [gdome]reference counts and freeDoc



Luca Padovani wrote:
> I think that, at least at present, the different memory management
> adopted in gdome2 (think of gdome_di_freeDoc) makes sense in a language
> without garbage collector as C++

I disagree. Regarding this issue, I don't think that it matters wether a
language has a garbage collecting feature or not. 

My main programming experience is in C++. Here is how I imagine a C++
wrapper around Gdome: DOM API interfaces are represented by small classes
containing just one pointer to the apropriate gdome2 object. All API calls
returning a DOM object would have to return a pointer to a newly allocated
C++ wrapper object (see end of message for rationale). These API calls
would then act as factory methods. Users know they must delete objects
created factory methods themselves. So a check wether an Element has an
attribute "Version" with a value of at least a provided version number 
could look like this in C++

bool check_proper_version (const Dom::Element * e, int version) {
  const Dom::Attr * a = e->getAttributeNode("Version");
  bool is_proper_version =
          a ? (atoi(a->value().c_str()) >= version) : false;
  delete a;
  return is_proper_version;
}

And this pattern is repeated everywhere -- the toolkit creates a DOM
object, the programmer deletes it. I don't see any reason to force him to
call the completely different freeDoc method.

I suppose you want to be on the safe side and ensure the libxml tree is
really really deleted at some point in the program (since probably in most
programs you know when you are finished with a document). Is this what you
want? Then simply add method to Node that checks wether the libxml tree
will be deleted from memory when the programmer unrefs this node,
something like
GdomeBoolean gdome_n_unrefFreesDocument(GdomeNode * self,...)
and call

 assert(gdome_n_unrefFreesDocument(node, NULL));
 gdome_n_unref(node, NULL);

when you are sure this is this is the last node alive.

>                                  and in a language with g.c. as ruby,
> though, in the second case, the user is required to manage the
> allocation of the whole document explicitly. The point is that if a more
> uniform interface is adopted (where gdome_doc_unref behaves like all the
> other unrefs), in a g.c. language the user is then forced to keep a live
> reference to the document, to prevent the whole document to be freed
> while one has a live reference to an inner node. And this is in

As I wrote, I could implement the reference to the document element in the
wrapper code. This would not be very difficult, and it would not make any
difference to the ruby programmer wether this feature (freeing the
libxml tree when the last node in the document dies) is implemented in the
wrapper or in libgdome itself.

It does however make a difference to the C or C++ programmer using gdome2
directly. As I wrote, I think it is bad style to force him to free the
document explicitly. It should be enough to unref all used nodes. 

And BTW I think it would be a really bad idea to implement gdome_doc_unref
in a way that it frees the document while other nodes are still being
referenced. Please don't implement this.

> contrast with the policy of garbage collecting, because in principle the
> whole document is accessible by means of any inner reference.
> Even worse, this is also wrong is the context of a functional language,
> because one is required to retain somewhere a reference to the document
> (very imperative).  

Garbage collected or not is really not the point IMHO.

> > How about that (modified 2.): All existing node objects also increase
> > the reference count of the doc object, and unref it on destruction.
> > When doc's refcount reaches zero, free the document. This way, doc is
> > guaranteed to be the last node alive, and when it dies, the libxml
> > tree should go with it.
> This approach works fine, in the sense described above, but I cannot
> consider it much more than a trick.

I think you can call it a trick because you reuse GdomeDocument for a
purpose for which it was not designed. Any other reason why you dislike
it?

I have not yet looked deep into gdome's source code, so I'm just guessing
here: I once saw that GdomeNodeList or GdomeNamedNodeMap store a pointer
to a GdomeNode. Aren't you doing the very same thing at this level, and
prevent this node from being destroyed by increasing its reference count?
If so, what is the difference between this behaviour and the proposed
trick?


Now back to the C++-Wrapper topic: Above I wrote: All API calls returning
a DOM object would have to return a pointer to a newly allocated C++
wrapper object.
The alternatives would be returning references or returning (=copying)
objects. The latter disqualifies because of C++'s static type system: A
DOM method returning a Node should in fact return an Element or an Attr,
or whatever the real type of the corresponing XML node is. This can only
be done with references or pointers. References are not well suited for
returning NULL as required by some DOM methods, and are in general less
flexible than pointers.

Maybe I could change my script that currently produces ruby wrapper code
to also produce c++ wrapper code. Should not be too difficult. Just
achieving const correctness would be a major issue.

Greetings, Tobias.





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]