[comp.sys.mac.programmer] ATP/Init question

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