[Openmcl-devel] Voodoo: Callbacks and Closures

Gary Byers gb at clozure.com
Thu May 5 14:01:16 PDT 2005



On Thu, 5 May 2005, David Steuber wrote:

> On May 4, 2005, at 11:09 PM, Gary Byers wrote:
>
>> The callback code in the lisp kernel handles the transition between
>> foreign code and lisp code and calls the function in the INDEXth entry
>> in the %PASCAL-FUNCTIONS% vector.  (It actually calls the functional
>> value of the symbol %PASCAL-FUNCTIONS% to do the latter; static symbol
>> names were once in short supply ...)
>> 
>> The fact that the functions are referenced from a global variable
>> keeps them from getting GCed.  The GC can't in general run around
>> freeing these things, since it has no idea whether an individual
>> entry can be referenced from foreign code.  (If the application
>> "knows" when a callback pointer can no longer be referenced, it'd
>> be fairly simple to delete the entry associated with that pointer.)
>> 
>
> Does this mean that a CLOS object referenced by the callback is also 
> protected from getting GCed?

yes; it's transitively reachable from a global variable (%PASCAL-FUNCTIONS%).

>
> I also have a function for uninstalling an event handler.  Once this is done, 
> the callback will no longer by referenced.  What do I need to do to delete 
> the entry?
>
>
>

This is untested, assumes that it's defined in the CCL package, and continues
the confusing tradition of calling callbacks "Pascal functions".

(defun %delete-pascal-function (pointer)
   (with-lock-grabbed (*callback-lock*)
     (let* ((index (dotimes (i (length %pascal-function))
                     (when (eql (pfe.routine-descriptor (svref %pascal-functions%^ i)) pointer)
                       (return i)))))
       (when index
         (let* ((entry (svref %pascal-functions%^ index)))
           (setf (svref %pascal-functions%^ index) nil)
           (when (eql (symbol-value (pfe.sym entry))
                      (pfe.routine-descriptor entry))
             (set (symbol-value (pfe.sym entry)) nil))
           (free (pfe.routine-descriptor entry))
           t)))))



More information about the Openmcl-devel mailing list