From: Rupert Swarbrick
Subject: CLOS question
Date: 
Message-ID: <5Yx7j.3444$1j1.1629@newsfe7-gui.ntli.net>
Hi,

I've been writing a wrapper to libbz2 using trivial-gray-streams and 
cffi. It is a stream you create by giving it another stream, then read 
from as usual and it decompresses on the fly. Finally, calling close on 
it cleans up state and also deallocates some foreign buffers which I 
allocated with cffi.

The question is whether the "close" bit can be made optional. I 
understand that clos doesn't have destructors on purpose because lisp is 
supposed to hide the memory management from you, but clearly there's some 
cleanup that my code has to do in order not to leak memory (unless 
buffers created with cffi:foreign-alloc are automatically GC'ed, but I 
can't find that in the docs).

Is there any way to do this? It seems ugly to force users to call close 
on the stream in order to avoid memory leaks - so C-like! :D

Rupert

From: Pascal Costanza
Subject: Re: CLOS question
Date: 
Message-ID: <5s7pj1F17q7diU1@mid.individual.net>
Rupert Swarbrick wrote:
> Hi,
> 
> I've been writing a wrapper to libbz2 using trivial-gray-streams and 
> cffi. It is a stream you create by giving it another stream, then read 
> from as usual and it decompresses on the fly. Finally, calling close on 
> it cleans up state and also deallocates some foreign buffers which I 
> allocated with cffi.
> 
> The question is whether the "close" bit can be made optional. I 
> understand that clos doesn't have destructors on purpose because lisp is 
> supposed to hide the memory management from you, but clearly there's some 
> cleanup that my code has to do in order not to leak memory (unless 
> buffers created with cffi:foreign-alloc are automatically GC'ed, but I 
> can't find that in the docs).

No, the real reason is that destructors are not guaranteed to ever be 
called at all (because a garbage collector cannot guarantee to ever 
collect an object at all). This means that destructors don't provide 
enough semantic guarantees, so should be used sparingly.

> Is there any way to do this? It seems ugly to force users to call close 
> on the stream in order to avoid memory leaks - so C-like! :D

http://www.cliki.net/trivial-garbage


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rupert Swarbrick
Subject: Re: CLOS question
Date: 
Message-ID: <SXy7j.3456$1j1.496@newsfe7-gui.ntli.net>
On Tue, 11 Dec 2007 16:44:32 +0100, Pascal Costanza wrote:
> No, the real reason is that destructors are not guaranteed to ever be
> called at all (because a garbage collector cannot guarantee to ever
> collect an object at all). This means that destructors don't provide
> enough semantic guarantees, so should be used sparingly.

Oh, ok. That makes sense.

>> Is there any way to do this? It seems ugly to force users to call close
>> on the stream in order to avoid memory leaks - so C-like! :D
> 
> http://www.cliki.net/trivial-garbage

I'm probably being stupid, but I can't see how this would help! Can you 
give a pseudo-code explanation maybe? I'm confused...

Rupert
From: Luís Oliveira
Subject: Re: CLOS question
Date: 
Message-ID: <m1bq8xupjj.fsf@deadspam.com>
Rupert Swarbrick <··········@gmail.com> writes:
>>> Is there any way to do this? It seems ugly to force users to call close
>>> on the stream in order to avoid memory leaks - so C-like! :D
>> 
>> http://www.cliki.net/trivial-garbage
>
> I'm probably being stupid, but I can't see how this would help! Can you 
> give a pseudo-code explanation maybe? I'm confused...

You can attach a finalizer (a function) to your stream (or any other
object). That function will be invoked when the stream is garbage
collected and you can use it to free your foreign memory at that point.

SBCL's manual has some examples:
<http://www.sbcl.org/manual/Garbage-Collection.html>

-- 
Luís Oliveira
http://student.dei.uc.pt/~lmoliv/
From: Pascal Costanza
Subject: Re: CLOS question
Date: 
Message-ID: <5s7urnF1874taU1@mid.individual.net>
Rupert Swarbrick wrote:
> On Tue, 11 Dec 2007 16:44:32 +0100, Pascal Costanza wrote:
>> No, the real reason is that destructors are not guaranteed to ever be
>> called at all (because a garbage collector cannot guarantee to ever
>> collect an object at all). This means that destructors don't provide
>> enough semantic guarantees, so should be used sparingly.
> 
> Oh, ok. That makes sense.
> 
>>> Is there any way to do this? It seems ugly to force users to call close
>>> on the stream in order to avoid memory leaks - so C-like! :D
>> http://www.cliki.net/trivial-garbage
> 
> I'm probably being stupid, but I can't see how this would help! Can you 
> give a pseudo-code explanation maybe? I'm confused...

trivial-garbage doesn't only give you a common API for weak pointers, 
but also for finalizers. Finalizers are the things you're looking for, 
they allow you to add functions to objects that are triggered once they 
are garbage collected.

There are some test cases in the download. You can probably also find 
examples in the documentations of the several CL implementations (and 
the source code of trivial-garbage helps you to find out about the names 
to look for in the documentations).

Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Maciej Katafiasz
Subject: Re: CLOS question
Date: 
Message-ID: <fjn2fo$86e$2@news.net.uni-c.dk>
Den Tue, 11 Dec 2007 15:23:45 +0000 skrev Rupert Swarbrick:

> Is there any way to do this? It seems ugly to force users to call close
> on the stream in order to avoid memory leaks - so C-like! :D

In addition to what's been said in the other responses, WITH-OPEN-STREAM, 
which is infinitely better an interface than anything C could provide. It 
makes getting streams management right fairly trivial.

Cheers,
Maciej
From: Rainer Joswig
Subject: Re: CLOS question
Date: 
Message-ID: <joswig-51FC69.00183712122007@news-europe.giganews.com>
In article <············@news.net.uni-c.dk>,
 Maciej Katafiasz <········@gmail.com> wrote:

> Den Tue, 11 Dec 2007 15:23:45 +0000 skrev Rupert Swarbrick:
> 
> > Is there any way to do this? It seems ugly to force users to call close
> > on the stream in order to avoid memory leaks - so C-like! :D
> 
> In addition to what's been said in the other responses, WITH-OPEN-STREAM, 
> which is infinitely better an interface than anything C could provide. It 
> makes getting streams management right fairly trivial.
> 
> Cheers,
> Maciej

Right. That's similar to a destructor that gets called in C++
when you leave a dynamic scope. In Common Lisp one uses
UNWIND-PROTECT, which is used in WITH-OPEN-STREAM. Using
macros, one can create new WITH-... constructs which
do some cleanup when the program leaves the enclosed scope.

-- 
http://lispm.dyndns.org/