[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