[Openmcl-devel] add-gc-hook / drain-termination-queue
Carlos Ungil
carlos.ungil at gmail.com
Thu Sep 5 17:39:18 PDT 2013
Hello,
to ensure that finalizers are run from the main thread, I'm doing the
following:
(setq ccl:*enable-automatic-termination* nil)
(ccl::add-gc-hook
(let ((process ccl:*current-process*))
(lambda ()
(ccl:process-interrupt process #'ccl:drain-termination-queue)))
:post-gc))
Is this a good idea? The fact that add-gc-hook is not exported makes me
doubt...
The context is the following: RCL embeds R in Common Lisp (using CFFI, the
rf-protect and rf-unprotect-ptr functions below are foreign functions).
When I need to hold a foreign pointer in the lisp side I wrap it in an
object: I "protect" it to prevent it from being garbage-collected in the R
side and I set up a finalizer to "unprotect" it when it's no longer in use.
(defun make-r-pointer (ptr)
(let ((r-pointer (make-instance 'r-pointer :pointer ptr)))
(rf-protect ptr)
(trivial-garbage:finalize r-pointer (lambda () (rf-unprotect-ptr ptr)))
r-pointer))
However, a function triggering garbage collection like the following one
crashes the program (because the protect and unprotect functions will run
concurrently, I think).
(ql:quickload :rcl)
(rcl:r-init)
(reduce #'+ (loop repeat 10000 append (rcl:r "runif" 1)))
The workaround mentioned above seems to solve the problem, but I wonder if
there might be some undesirable effects.
I also tried to let the automatic termination enabled, forcing the
finalizer to run each time from the main thread
(trivial-garbage:finalize r-pointer (let
((process ccl:*current-process*)) (lambda () (process-interrupt process
#'rf-unprotect-ptr ptr))))
but I couldn't make it work (the program hangs).
Cheers,
Carlos
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.clozure.com/pipermail/openmcl-devel/attachments/20130906/337a033b/attachment.htm>
More information about the Openmcl-devel
mailing list