[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