[Openmcl-cvs-notifications] r15145 - /trunk/source/level-1/l1-lisp-threads.lisp
gb at clozure.com
gb at clozure.com
Sat Dec 17 23:24:52 CST 2011
Author: gb
Date: Sat Dec 17 23:24:51 2011
New Revision: 15145
Log:
Try to address ticket:896 (at least the parts that aren't "this isn't
Smalltalk.") For the time being, do so by holding strong references
to termination functions while they're on the finalization alist; it
might be preferable to do this in the GC, but this approach is better
than forcing the user to do it themselves.
It's now the case that if a termination function (transitively) refers
to the associated object the object won't be terminated (or even GCed.)
Modified:
trunk/source/level-1/l1-lisp-threads.lisp
Modified: trunk/source/level-1/l1-lisp-threads.lisp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/source/level-1/l1-lisp-threads.lisp (original)
+++ trunk/source/level-1/l1-lisp-threads.lisp Sat Dec 17 23:24:51 2011
@@ -1020,6 +1020,23 @@
=
(defvar *enable-automatic-termination* t)
=
+(defstatic *termination-functions-lock* (make-lock))
+(defstatic *termination-functions* (make-hash-table :test #'eq :lock-free =
nil))
+
+(defun register-termination-function (f)
+ (with-lock-grabbed (*termination-functions-lock*)
+ (without-interrupts
+ (incf (gethash f *termination-functions* 0)))))
+
+(defun deregister-termination-function (f) =
+ (with-lock-grabbed (*termination-functions-lock*)
+ (without-interrupts
+ (let* ((count (gethash f *termination-functions*)))
+ (when count
+ (if (eql 0 (decf count))
+ (remhash f *termination-functions*)
+ (setf (gethash f *termination-functions*) count)))))))
+
(defun terminate-when-unreachable (object &optional (function 'terminate))
"The termination mechanism is a way to have the garbage collector run a
function right before an object is about to become garbage. It is very
@@ -1031,6 +1048,7 @@
(let ((new-cell (cons object function))
(population *termination-population*))
(without-interrupts
+ (register-termination-function function)
(with-lock-grabbed (*termination-population-lock*)
(atomic-push-uvector-cell population population.data new-cell)))
function))
@@ -1046,7 +1064,9 @@
(atomic-pop-uvector-cell population population.termination-lis=
t)
(if (not existed)
(return)
- (funcall (cdr cell) (car cell))))))))
+ (let* ((f (cdr cell)))
+ (deregister-termination-function f)
+ (funcall f (car cell)))))))))
=
(defun cancel-terminate-when-unreachable (object &optional (function nil f=
unction-p))
(let* ((found nil))
@@ -1065,6 +1085,7 @@
(when (and (eq o object)
(or (null function-p)
(eq function f)))
+ (deregister-termination-function f)
(if prev
(setf (cdr prev) (cdr spine))
(setf (population.data population) (cdr spine)))
More information about the Openmcl-cvs-notifications
mailing list