mikeoro@hubcap.clemson.edu (Michael K O'Rourke) (07/05/89)
I am trying to write an init which will queue up an ATPGetRequest. It has a completion routine which does minor processing and then queues up another ATPGetRequest. The code resource has the locked and sysheap bits set. However, my machine bombs a few seconds after the init is loaded and i can't figure out why. My guess is that i am trying to have global data in a way which isn't kosher. I don't know what the correct or standard way is. If someone could take a look at the following code and tell me if they see anything jump out at them, i greatly appreciate it. Michael O'Rourke Clemson University #include "Appletalk.h" #include "nAppletalk.h" #include "SetUpA4.h" static ATPPBptr NewPBPtr; static Ptr NTE; static Byte Socket; static int RecBuff; Receive() { OSErr err; RememberA0(); SetUpA4(); if (RecBuff == 666) SysError(1); else if (RecBuff == 999) ShutDwnPower(); NewPBPtr->atpSocket = Socket; NewPBPtr->reqLength = sizeof(RecBuff); NewPBPtr->reqPointer = (Ptr) &RecBuff; NewPBPtr->ioCompletion = &Receive; err = PGetRequest(NewPBPtr,1); RestoreA4(); } main() { MPPPBptr OldPBPtr; EntityName Entity; OSErr err; RememberA0(); SetUpA4(); err = ATPLoad(); if (err==noErr) { err = MPPOpen(); if (err==noErr) { NewPBPtr = (ATPPBptr) NewPtr(sizeof(ATPParamBlock)); OldPBPtr = (MPPPBptr) NewPtr(sizeof(MPPParamBlock)); NTE = NewPtr(120); NewPBPtr->addrBlock.aNet = 0; NewPBPtr->addrBlock.aNode = 0; NewPBPtr->addrBlock.aSocket = 0; NewPBPtr->atpSocket = 0; err = POpenATPSkt(NewPBPtr, 0); Socket = NewPBPtr->atpSocket; NBPSetNTE(NTE,"\pComputer", "\pLABdown", "\p*", Socket); OldPBPtr->MPPinterval = 2; OldPBPtr->MPPcount = 2; OldPBPtr->MPPentityPtr = NTE; err = PRegisterName(OldPBPtr,0); NewPBPtr->atpSocket = Socket; NewPBPtr->reqLength = sizeof(RecBuff); NewPBPtr->reqPointer = (Ptr) &RecBuff; NewPBPtr->ioCompletion = 0L/*&Receive*/; err = PGetRequest(NewPBPtr,1); DisposPtr(OldPBPtr); } } RestoreA4(); }
tim@hoptoad.uucp (Tim Maroney) (07/06/89)
In article <5916@hubcap.clemson.edu> mikeoro@hubcap.clemson.edu (Michael K O'Rourke) writes: >However, my machine bombs a few seconds after the init is loaded and i can't >figure out why. My guess is that i am trying to have global data in a way >which isn't kosher. I don't know what the correct or standard way is. > >Receive() >{ >OSErr err; > > RememberA0(); Here's the problem -- see below. > SetUpA4(); > if (RecBuff == 666) > SysError(1); > else if (RecBuff == 999) > ShutDwnPower(); > NewPBPtr->atpSocket = Socket; > NewPBPtr->reqLength = sizeof(RecBuff); > NewPBPtr->reqPointer = (Ptr) &RecBuff; > NewPBPtr->ioCompletion = &Receive; > err = PGetRequest(NewPBPtr,1); > RestoreA4(); >} Your problem is straightforward. RememberA0() depends on A0 being set up by LSC glue code to point to the start of the code resource. When Receive is called, it is called directly from the Macintosh OS, since it is a completion routine. A0 points to your parameter block, not the code resource, because that's how completion routines are called. Your globals operations go off into outer space and crash the system. The proper way to do this is to delete the RememberA0() call in Receive. The code that stashes the globals register in your main() is correct and needs no changes: >main() >{ >MPPPBptr OldPBPtr; >EntityName Entity; >OSErr err; > > RememberA0(); > SetUpA4(); > [routine body deleted] > RestoreA4(); >} I also have a few qualms about reusing the parameter block from inside a completion routine. I'm not sure whether or not this is safe; I would use two parameter blocks and alternate them just to feel secure. If it's not safe, you risk crash or deadlock with a corrupted request queue. Can someone answer this issue authoritatively? Inside Mac doesn't seem to mention whether the block has already been dequeued when the completion routine is called. In the absence of documentation, it's not safe to depend on empirical evidence, since things could change with the next system release. -- Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com Postal: 424 Tehama, SF CA 94103; Phone: (415) 495-2934 "Skip, witches! Hop, toads! Take your pleasure!" -- Aleister Crowley, THE BOOK OF LIES