[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Rumors of dead macptrs



At 8:30 PM 4/8/95, Steve_Mitchell-R1946C@email.sps.mot.com wrote:
>Dear MCL Mavens;
>
>As usual, I'm turning to you when I have a problem that's
>hard to characterize, and has "bugged" me for awhile.
>
>I have a menu that pops up on option-click in a window
>(The GUI Police need not respond; it's "temporary", I swear).
>If the menu is created once and the application is saved,
>there is a problem when the saved application is run. Now
>option-click leads not to a menu of commands, but a
>DEAD-MACPTR error.

Sounds like you're storing the pop-up menu in a global variable,
but not clearing that global with either an entry in *save-exit-functions*,
*lisp-startup-functions* or a def-load-pointers function. Any
one of the above will likely fix the problem.

>
>This is easy to rationalize. When the application was
>saved, MCL didn't know about this menu, so it didn't
>deal with the menu object's macptr into the Mac heap,
>so the old macptr is invalid in the new application.
>This assumes that at save-application time, MCL recognizes
>and deals with installed menus, which I suspect is not
>what happens at all.

MCL deals correctly with the menus in the menubar, but the
pop-up-menu package is not designed that way. Since most
pop-up menus are static subviews of a view, and not stored
in a global variable, forcing them to be recreated when the
saved application is restarted, noone thought to add this
to the pop-up-menu design.

>
>I noticed that font-menus.lisp contains the line:
>(pushnew 'add-font-menus *lisp-startup-functions*).
>The fn should actually be called add-fonts-menu, because
>what it does is rebuild the Fonts heirarchical menu,
>just in case your font mix changed since the last time
>you ran your application. Anyway, using this technique
>made the error go away, but, as usual, I'm still not
>happy.

It will make the saved application slightly smaller if you
clear out all the dead macptrs (with a *save-exit-function*)
before saving. Often it's easier to just have a def-load-pointers
or *lisp-startup-functions* entry that will reinitialize at
startup. The final result is the same.

>
>A formerly-perfectly-good menu containing a destined-to-
>be-dead macptr still got saved in the application. I
>suspect that when the popup menu vanishes (unpops) from
>the screen its menu-handle slot's macptr should be
>deallocated and the slot set to nil. Similarly the
>menu-id slot should be set to nil.

Normally, you'd rather not need allocate the toolbox menu
each time the user clicks and deallocate it afterwards.

>
>Questions:
>
>1. Does this mean something more should be done when the
>   popup menu unpops? e.g. I don't think menu-deinstall
>   is being called.

menu-deinstall is called on a pop-up-menu when it is removed
from its window (see the remove-view-from-window method in
"pop-up-menu.lisp". Normally, this is sufficient. You could
use this method if it makes you feel better. Call
set-view-container before popping up your pop-up menu to
install it in the clicked-on window, and afterwards, to remove
it and deallocate the mac heap data.

>
>2. If my "solution" is basically correct, shouldn't a
>   *save-exit-functions* fn clean up before the save,
>   and what would that fn look like?

It would look like the following. if your code does
(set-view-container *pop-up-menu* clicked-on-window)
when the user option-clicks, you could use this
instead of the *lisp-startup-function*.

(defun cleanup-pop-up-menu ()
  (when *pop-up-menu* (set-view-container *pop-up-menu* nil)))

(pushnew 'cleanup-pop-up-menu *save-exit-functions*)

>
>3. I had a similar problem with the HIERARCHICAL menus in
>   Matt Cornell's fred-keystroke-macros; anyone know why?

Works fine for me. Maybe I'm using a different version of
that code.

>
>4. I had a similar problem (boy I have a lot of problems)
>   with a CHECK-MARK I put on a menu-item:
>    (add-new-item menu "Debugging"  nil 
>                  'debugging-menu-item-action
>                  :menu-item-checked *debugging*)
>   When the saved app started it called
>   set-menu-item-check-mark on a dead MacPtr in a tight
>   loop breaking a mile a minute. Does this mean check-mark
>   menu items have to be removed before a save? Doesn't
>   seem likely, but I haven't solved it.

I'd have to see your code to answer this one.

>   
>5. If the line above from font-menus.lisp allocates a
>   macptr, why is it using *lisp-startup-functions* vice
>   def-load-pointers? (MCL Reference p651).

Hard to say. It may be that the system is not sufficiently initialized
at def-load-pointers time to add menus. More likely is that the
writer of "font-menus.lisp" happenned to think of *lisp-startup-functions*
before def-load-pointers.

>
>6. Anyone got a meaty example of def-load-pointers usage?

My "define-interrupt-handler" contribution contains a def-load-pointers
to initialize its mac heap state. It should still be available for
anonymous FTP from digitool.com in the file
"/pub/mcl2/contrib/define-interrupt-handler.hqx".

Conclusion. There are two ways to handle this. The *lisp-startup-functions*
entry as you're doing now, or a *save-exit-function* that forces your
code to reinstall the menu the first time it's called.