[Openmcl-devel] termination question

Gary Byers gb at clozure.com
Sat Sep 11 15:38:28 PDT 2004



On Sat, 11 Sep 2004, Cyrus Harmon wrote:

> Ok, so I'm trying to get termination to work and failing:
>
> (progn
>    (defclass moose () ())
>    (defmethod terminate ((obj moose)) (print 'terminated!))
>    (setf g (make-instance 'moose))
>    (ccl:terminate-when-unreachable g)
>    (makunbound 'g)
>    (gc)
>    (drain-termination-queue))
>

To be honest, I'd forgotten that CCL:DRAIN-TERMINATION-QUEUE was
exported.  I'm not sure that it should be; it's sort of used as
a private mechanism by the thread that does periodic housekeeping
tasks (the initial thread, ordinarily.)

> Shouldn't this run my little termination function?

I find that it does.  If I change your example a little:

(defclass moose () ())

(defmethod terminate ((obj moose) (format t "~&~s in process ~s" 'terminated! *current-process*)))

(defvar *g* ())

(dotimes (i 10)
  (setq *g* (make-instance 'moose))
  (terminate-when-unreachable g)
  (makunbound '*g*)
  (gc)
  (drain-termination-queue))

I get output that looks like:

TERMINATED!, in process #<PROCESS Initial(0) [Active] #x6107476>
TERMINATED!, in process #<PROCESS Initial(0) [Active] #x6107476>
TERMINATED!, in process #<PROCESS listener(1) [Active] #x635F026>
TERMINATED!, in process #<PROCESS Initial(0) [Active] #x6107476>
TERMINATED!, in process #<PROCESS listener(1) [Active] #x635F026>
TERMINATED!, in process #<PROCESS Initial(0) [Active] #x6107476>
TERMINATED!, in process #<PROCESS listener(1) [Active] #x635F026>
TERMINATED!, in process #<PROCESS Initial(0) [Active] #x6107476>
TERMINATED!, in process #<PROCESS listener(1) [Active] #x635F026>
TERMINATED!, in process #<PROCESS Initial(0) [Active] #x6107476

In this case, the listener got 4 out of 10.  I'd ordinarily expect
it to get slightly more than half, but I wouldn't expect it to be
deterministic in either case.

There -is- a way to keep the housekeeping thread out of the picture:

? (setq CCL:*ENABLE-AUTOMATIC-TERMINATION* nil)

and, in that case, the listener gets 10/10 as expected.  I'd want
to think about this a little harder before proposing what gets
documented, but I think that I generally prefer:

a) termination happening as "automatically" as possible
b) no guarantees being offered about what thread a TERMINATE method
   is called on.

I have some concerns about how well the current scheme scales and
about race conditions with the GC, and those conditions might be
best addressed by doing some of this at a lower level and not exposing
CCL:DRAIN-TERMINATION-QUEUE.

>
> I have on certain occasions gotten terminate to be called, but not
> consistently and not on this simple example. Am I missing something
> here?

In some environmnents, different threads will have different bindings
of *TERMINAL-IO* and the other standard streams, and there may be
different handling of output-flushing on those streams.  If you're
running in such an environment, you may see that different "TERMINATED!"
messages were written to different streams.

Unless that explains why you're not seeing expected output, I'm not
sure what does.  (If there were typically thousands of objects enqueued
after each GC, there might be other explanations; the current scheme
seems to be able to reliably keep up with one such object per GC ...

>
> Thanks,
>
> Cyrus
>
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel
>
>



More information about the Openmcl-devel mailing list