[Openmcl-devel] Re: [Bug-openmcl] NSViewHierarchyLock Assertion failure

Gary Byers gb at clozure.com
Wed May 12 19:00:17 PDT 2004

On Wed, 12 May 2004, Raffael Cavallaro wrote:

> On May 12, 2004, at 11:33 AM, Gary Byers wrote:
> > Does the problem remain if instead of doing:
> >
> > ? (tiny-setup)
> >
> > you do:
> >
> > ? (process-interrupt ccl::*cocoa-event-process* #'ccl::tiny-setup)
> >
> > (or otherwise arrange that everything that the window does happens
> > on that thread) ?
> Well this (process-interrupt ccl::*cocoa-event-process* #'animate)
> prevents me from closing the window at all. It also prevents me from
> entering a break in the IDE as well (i.e., control-c has no effect),
> and I'm forced to force-quit OpenMCL (Application Not Responding). The
> animation runs, but OpenMCL will not respond to any UI events, neither
> mouse nor keyboard.

> Is there another way to ensure that all the drawing happens in that
> thread, while still allowing that thread (ccl::*cocoa-event-process*)
> to respond to UI events, such as mouse clicks, and keyboard input? The
> drawing takes place in a pretty tight loop which apparently monopolizes
> the *cocoa-event-process* thread entirely.

I think that the general idea is to think of animation as being
a series of frames.  Periodically (perhaps in response to a timer
event), you decide what the next frame of the animation should look
like, store that information where drawRect: will find it, and
invalidate the view.  drawRect: then concentrates on drawing a
particular frame and is generally unaware of the fact that what it's
drawing this time is a little different from what it drew last time.
> If I use process-run-function, I still get a crash on window close
> (unless I explicitly check for isVisible before each and every
> re-drawing, of course).

Checking isVisible isn't 100% reliable: the fact that the window
was visible when you checked is no guarantee that it'll continue
to be visible a few cycles later (the user may have clicked the
close box in the interim.)

If all drawing happens in the event thread, you can generally
be confidient that the window isn't going to disappear while you're
drawing to it.   If drawing occurs in multiple threads, things
get more complicated:

a) you generally have to ensure that the view you're drawing to
"has its focus locked" (to ensure that graphics operations make
it out to the window server and to ensure that the calling thread
has the exclusive right to draw to the window.)   The drawing that
ordinarily takes place on the main thread handles all of these
details automatically.

b) you obviously have to reliably inform the drawing thread that
the party's over (when the window gets closed.)  Delegates (and
other interested observers) will get notifications (will have
methods invoked on the main thread) when a window's being closed;
the handlers for those notifications would presumably want to
tell a separate drawing thread that it's time to stop drawing.

If everything happened on the main thread, a "window will close"
message would be a good opportunity to kill a timer that's
driving animation.

> Here's a transcript including kernel debugger output:

It seems to indicate that ANIMATE is trying to draw to a window
that doesn't exist anymore.
> If this would be any clearer, I could send you the complete code to
> tiny-loop.lisp - it's only a dozen lines longer than tiny.lisp.

I'd be interested; I don't think that the ways that I'd want to change
it would obfuscate things too much ...

> Thanks for all your efforts,
> Ralph
> Raffael Cavallaro, Ph.D.
> raffaelcavallaro at mac.com

More information about the Openmcl-devel mailing list