Article View: comp.sys.mac
Article #26602Re: Quickergraf bugs...
From: Stew Rubenstein
Date: Mon, 21 Mar 1988 01:08
Date: Mon, 21 Mar 1988 01:08
75 lines
3797 bytes
3797 bytes
In article <7786@agate.BERKELEY.EDU> lippin@ragu.UUCP (Tom Lippincott, ..ucbvax!bosco!lippin) writes:
>Recently dplatt@coherent.com (Dave Platt) said:
>>Apple has apparently changed the MDEF so that it can recover gracefully
>>if it can't get a pixmap big enough to save the screen pixels;
>
>This causes a problem for me. Since there are so many ways for
>out-of-memory problems to screw up the toolbox, I've responded by
>writing a growzone function which, when it can't scrounge memory, will
>unload most segments, put up an alert, and then longjmp back into the
>main event loop. But this makes some menu choices fail even when
>MenuSelect could get by without the memory.
>
>What I want is a way to tell if a memory request is vital or not. I
>can write this into my side of the code, but I know of no way to test
>this when it's a toolbox call that needs the memory. Is there one?
>Will there be one eventually? (This is all grungy stuff that would be
>better handled by the OS anyway, I say.)
Low memory handling on the Mac is a bitch. There isn't any way to
know when a memory request is critical, except to know what the
toolbox needs the memory for. You have to assume that any request is
critical. This is not far from the truth - memory allocation failures
are handled very poorly by the toolbox. In my apps, I have routines
Critical() and NonCritical(), which clear and set a flag checked by
the growzone function. Then I have:
INT32 MyMenuSelect(thePoint)
Point thePoint;
{
INT32 result;
NonCritical();
saveGhost = GhostWindow; /* MenuSelect will not update properly */
GhostWindow = 0; /* if you use GhostWindow. */
result = MenuSelect(thePoint);
GhostWindow = saveGhost;
Critical();
return result;
}
I also have a NewHandleNC() which I use for noncritical memory
allocations in my own code. Another useful trick is to allocate a
couple of buffers at the start of your program so that you have
something to release when the growzone proc is called.
Finally, it's important to preflight every memory request that you
can. For example, before you call a routine in another segment, do a
GetResource on the right CODE segment and check to see it succeeds. A
failure to load a CODE segment causes an immediate system error. The
GetResource won't waste much time, but you have to identify all the
intersegment calls and have some way of telling what segment it's in.
In MPW it's easy because it names the resources. For example:
if (PreFlightCall(SEG_RotateFrob))
{
RotateFrob();
UnloadSeg(RotateFrobox);
}
else
{
Alert (ALRT_notEnoughMemToRotateFrob, (FilterProc) 0);
}
It's especially hard to preflight QuickDraw region operations. I
assume that an upper bound on the size of a region is proportional to
the area of the bounding rectangle times an empirically derived fudge
factor related to the likely complexity of the region. You can also
use MapRgn to do the operation on a scaled-down region first, as
suggested in Inside Macintosh, but I find this too time consuming for
most purposes.
Stew Rubenstein
Cambridge Scientific Computing, Inc.
UUCPnet: seismo!harvard!rubenstein CompuServe: 76525,421
Internet: rubenstein@harvard.harvard.edu MCIMail: CSC
Technical Details
Message-ID:
<4260@husc6.harvard.edu>Path:
arc1-ca.pugleaf.net!utzoo!mnetor!uunet!husc6!endor!stewReferences:
<293STORKEL@RICE> <779@trwcsed.trwrb.UUCP> <2411@coherent.com> <7786@agate.BERKELEY.EDU>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!husc6!endor!stew From: stew@endor.harvard.edu (Stew Rubenstein) Newsgroups: comp.sys.mac Subject: Re: Quickergraf bugs... Message-ID: <4260@husc6.harvard.edu> Date: 21 Mar 88 01:08:39 GMT References: <293STORKEL@RICE> <779@trwcsed.trwrb.UUCP> <2411@coherent.com> <7786@agate.BERKELEY.EDU> Sender: news@husc6.harvard.edu Reply-To: stew@endor.UUCP (Stew Rubenstein) Organization: Aiken Computation Lab Harvard, Cambridge, MA Lines: 75