Hi,
as mentioned on this list CLisp has some problems with the finalization code provided by CFFI. I guess this is due to accessing the weak hash table within the finalizer. The following code works around this problem by closing the "main finalizer" over the list of the "sub finalizers".
(in-package :cffi-sys)
(defvar *finalizers* (make-hash-table :test 'eq :weak :key) "Weak hashtable that holds registered finalizers.")
(defun finalize (object function) "Pushes a new FUNCTION to the OBJECT's list of finalizers. FUNCTION should take no arguments. Returns OBJECT.
For portability reasons, FUNCTION should not attempt to look at OBJECT by closing over it because, in some lisps, OBJECT will already have been garbage collected and is therefore not accessible when FUNCTION is invoked." (multiple-value-bind (finalizers present-p) (gethash object *finalizers* (cons 'finalizers nil)) (unless present-p (setf (gethash object *finalizers*) finalizers) (ext:finalize object (lambda (obj) (declare (ignore obj)) (mapc #'funcall (cdr finalizers))))) (push function (cdr finalizers))) object)
(defun cancel-finalization (object) "Cancels all of OBJECT's finalizers, if any." (multiple-value-bind (finalizers present-p) (gethash object *finalizers*) (when present-p (setf (cdr finalizers) nil))) (remhash object *finalizers*))
While this code isn't as short and elegant as the original code, at least it works ;-)
Regards,
Marco
On 04/02/07, Marco Gidde marco.gidde@tiscali.de wrote:
While this code isn't as short and elegant as the original code, at least it works ;-)
Indeed it does. It passes the trivial-garbage tests without crashing. Thanks!
Anyway, I didn't feel like changing and testing the finalization code in both CFFI and trivial-garbage (what was I thinking?) so I just wiped out CFFI's finalization code. People can use trivial-garbage if they're interested in portable finalizers: http://cliki.net/trivial-garbage
Luís Oliveira <luismbo <at> gmail.com> writes:
On 04/02/07, Marco Gidde <marco.gidde <at> tiscali.de> wrote:
While this code isn't as short and elegant as the original code, at least it works
Indeed it does. It passes the trivial-garbage tests without crashing. Thanks!
Anyway, I didn't feel like changing and testing the finalization code in both CFFI and trivial-garbage (what was I thinking?) so I just wiped out CFFI's finalization code. People can use trivial-garbage if they're interested in portable finalizers: http://cliki.net/trivial-garbage
Luís, just to clarify; the CFFI finalization code has been removed from CFFI from this point on?
- Luke
On 14/02/07, Luke Crook luke@balooga.com wrote:
Luís, just to clarify; the CFFI finalization code has been removed from CFFI from this point on?
That was my idea, yes. But I'm all ears if there are any objections. It just doesn't make sense for me to maintain the same code in two different places.
Luís Oliveira <luismbo <at> gmail.com> writes:
On 14/02/07, Luke Crook <luke <at> balooga.com> wrote:
Luís, just to clarify; the CFFI finalization code has been removed from CFFI from this point on?
That was my idea, yes. But I'm all ears if there are any objections. It just doesn't make sense for me to maintain the same code in two different places.
No objections. Icurrently #-clisp the CFFI finalizer code in lispbuilder-sdl anyway.
I would like to distribute the the TRIVIAL-GARBAGE package with LISPBUILDER-SDL as a single bundle. Is this OK?
- Luke
"Luís Oliveira" luismbo@gmail.com writes:
On 04/02/07, Marco Gidde marco.gidde@tiscali.de wrote:
While this code isn't as short and elegant as the original code, at least it works ;-)
Indeed it does. It passes the trivial-garbage tests without crashing. Thanks!
Anyway, I didn't feel like changing and testing the finalization code in both CFFI and trivial-garbage (what was I thinking?) so I just wiped out CFFI's finalization code. People can use trivial-garbage if they're interested in portable finalizers: http://cliki.net/trivial-garbage
While I would like to see the finalizer code in CFFI because I never felt like using them in another context, it is certainly better to keep the code consistent in only one place.
And for that matter: when ECL is compiled with the boehm garbage collector (is it even possible without?) the following code should work a bit better than the simple ERROR :-):
(defun finalize (object function) #-boehm-gc (error "ECLli does not support finalizers.") #+boehm-gc (let ((old-finalizer (si:get-finalizer object))) (si:set-finalizer object (if old-finalizer (lambda (obj) (funcall function) (funcall old-finalizer obj)) (lambda (obj) (funcall function))))))
(defun cancel-finalization (object) #-boehm-gc (error "ECLli does not support finalizers.") #+boehm-gc (si:set-finalizer object nil))
Just noticed that there is no ECL specific code in trivial-garbage. Any ideas where this code should be placed now?
Regards,
Marco
On 15/02/07, Marco Gidde marco.gidde@tiscali.de wrote:
And for that matter: when ECL is compiled with the boehm garbage collector (is it even possible without?) the following code should work a bit better than the simple ERROR :-):
[...]
Just noticed that there is no ECL specific code in trivial-garbage. Any ideas where this code should be placed now?
There isn't any ECL code in trivial-garbage because last time I checked (0.9i) ECL didn't support any of the stuff trivial-garbage provides. At least not on OSX anyway.
Feel free to send me a patch adding ECL support to trivial-garbage!