Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!purdue!decwrl!ucbvax!hoptoad!tim From: tim@hoptoad.uucp (Tim Maroney) Newsgroups: comp.sys.mac.programmer Subject: Re: ROM doesn't unlock Handles (was: ROM unlocks Handles). LONG Message-ID: <9419@hoptoad.uucp> Date: 27 Dec 89 22:38:18 GMT References: <3875@atr-la.atr.co.jp> <4525@helios.ee.lbl.gov> <3888@atr-la.atr.co.jp> Reply-To: tim@hoptoad.UUCP (Tim Maroney) Organization: Eclectic Software, San Francisco Lines: 71 In article <3875@atr-la.atr.co.jp> alain@atr-la.atr.co.jp (Alain de Cheveigne) writes: >>>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; >>>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. In article <4525@helios.ee.lbl.gov>$@$G(Jbeard@ux1.lbl.gov (Patrick C Beard) writes: >>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). In article <3888@atr-la.atr.co.jp> alain@atr-la.atr.co.jp (Alain de Cheveigne) writes: >Groan! Why on earth should one want to copy the _Handle_ itself? > >I must not have made myself clear: what needs copying is not the 4 >byte Handle, but the *contents* of the block. That's the stuff that >can move. You still haven't made yourself clear; I really haven't the faintest idea what you're talking about. Could you provide a code example? >But I admit that Tim's example was unfortunate, as it involves two >Handles: wombat, that needs locking, and h, the 4 byte value of which >needs copying because HewHandle() moves memory. Well, it's big of you to "admit" this. However, you are wrong. That was what the example was all about -- assigning into a relocatable structure can fail if the assignment may have the side effect of moving memory. If the "copying" does not involve anything that moves memory -- for instance, if you are doing a BlockMove on a string, or a conventional "=" assignment on a structure -- then you don't have to either lock the handle or use a temporary variable. And after reading the above quoted paragraph five times, I have to wonder if *you* know what you mean. wombat does not require locking. You can't lock a structure field; that makes no sense. h does not "require copying because NewHandle moves memory"; I don't even know what that is supposed to mean. It is there because the statement (*marsup)->wombat = NewHandle(WOMBAT_SIZE); may be evaluated left to right. First, the address of (*marsup)->wombat is calculated. Second, NewHandle() is called. This second step may cause the first step's address to become invalid, since (*marsup) may change. The way around this is to use a temporary variable, because this inverts the order. First NewHandle() is called and its result saved on the stack; then the address of (*marsup)->wombat is taken and the saved value is assigned into it. >>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. >What you're telling me is that the safe way to use Handles is to use >Pointers instead. No he isn't. WindowRecords and GrafPorts *have* to be pointers in the Mac OS. -- Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com "God must be a Boogie Man." -- Joni Mitchell