Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!hellgate.utah.edu!helios.ee.lbl.gov!ux1.lbl.gov!beard From: beard@ux1.lbl.gov (Patrick C Beard) Newsgroups: comp.sys.mac.programmer Subject: Re: ROM doesn't unlock Handles (was: ROM unlocks Handles). LONG Summary: Temporary *Handle* variables. Message-ID: <4525@helios.ee.lbl.gov> X-Local-Date: 26 Dec 89 10:01:15 PST Date: 26 Dec 89 18:01:15 GMT References: <3875@atr-la.atr.co.jp> Sender: usenet@helios.ee.lbl.gov Reply-To: beard@ux1.lbl.gov (Patrick C Beard) Organization: Lawrence Berkeley Laboratory, Berkeley Lines: 68 In article <3875@atr-la.atr.co.jp> alain@atr-la.atr.co.jp (Alain de Cheveigne) writes: >My original posting had another aim: find the wisest way to deal with >locking and unlocking handles, especially in code that contains many >nested subroutines. [discussion of ways to avoid locking deleted] >Another way to avoid locking is to use a temp variable, as recommends >tim@hoptoad.uucp (Tim Maroney): > >>Handle h = NewHandle(WOMBAT_SIZE); >>(*marsup)->wombat = h; >> >>Slightly more stack overhead, but you avoid trap overhead for locking >>and unlocking, and also avoid all the state-restoration hassles that >>have been mentioned lately here. > >This scheme was recommended by many, and emerged as the best solution >for short fields. But it isn't obvious what to do if the field is >large: a string, or an array, or data for a BitMap or PixMap. Now wait one second. We are talking about _Handles_. The overhead required to keep a temporary copy of a Handle, regardless of how large the allocated memory block is, is 4 bytes! Therefore, your analysis is incorrect. You would never need more than one temporary handle variable to keep track of any size field (if that field is allocated as a Handle). Thus, Tim and everybody else who said this are correct. This is the best way to avoid locking handles. > >Temp variables for big data fields require space (stack? heap?) and >copying takes time. In the case of a string, copying with strcpy() >might move memory if strcpy() happened to be in an unloaded segment. >BlockMove() is said to be safe (but then who knows...). > >It seems better to lock a handle to access big fields. > Bogus conclusion. >This brings us to the question of state restoring. Suppose you have a >long piece of code that needs a pointer to data in a handle. You >don't want to keep locking and unlocking, so you call Hlock() once at >the beginning, and HUnlock() at the end. Now, if your code calls a >routine that also locks and unlocks the handle, then that handle is >left *unlocked* in the following code. This situation is difficult to >identify. Why are you passing this Handle around between more than a few routines? If you are writing fairly modular code, you should be able to minimize the number of places this is a problem. I've been programming the Mac for a couple of years and I've never thought memory management was so hard. I've just followed these simple rules: 1. Never lock a handle if possible. 2. Never, never, keep a copy of a dereferenced handle around, you might be tempted to use it. These cause a whole new breed of dangling references. 3. Allocate memory that is never going to be relocated as a pointer. For example, allocate lots of WindowRecords and GrafPorts early in a program as a single NewPtr call. This will keep the heap clean, and you don't have to worry about Handle states, and your code will be faster. With virtual memory on the horizon, Handles may not be long for this world. ------------------------------------------------------------------------------- - Patrick Beard, Macintosh Programmer (beard@lbl.gov) - - Berkeley Systems, Inc. "..............Good day!" - Paul Harvey - -------------------------------------------------------------------------------