From: barrett@astro.cs.umass.edu (Daniel Barrett)
Newsgroups: comp.sys.amiga.programmer
Subject: Re: Enough talk.  FILE: server.c
Date: 8 Jan 93 17:46:25 GMT
Reply-To: barrett@astro.cs.umass.edu (Daniel Barrett)
Organization: BLAZEMONGER INCORPORATED

In article <C0IyF5.9Gv@usenet.ucs.indiana.edu> shulick@navajo.ucs.indiana.edu writes:
>Well, I've complained enough about memory leaks.  =u)  Here's the server
>I wrote that is faulty.  About 8k bytes are not freed, and I can't
>figure out why.

	Someone else has mentioned the missing ReplyMsg(), but here are
some more tips.

>   if (!(IntuitionBase = (struct Library *)
>     OpenLibrary("intuition.library", 37)))
>   {
>      Alert(AG_OpenLib | AO_Intuition);
>      exit(0);
>   }
>   if (!(GfxBase = (struct Library *)OpenLibrary("graphics.library", 37)))
>   {
>      Alert(AG_OpenLib | AO_GraphicsLib);
=========
=	ERROR:  Forgot to CloseLibrary(IntuitionBase) here.
=========
>      exit(0);
=========
=	"exit(0)" generally means that the program exited with a "success"
=	return code.  But your program is failing.  Use the DOS return codes
=	in (I think) <dos/dosextens.h>:  RETURN_OK, RETURN_FAIL, etc.
=========
>   }


>   if (!(myport = CreateMsgPort()))  /* Create the port.. */
>   {
>      Alert(AN_CreatePort);
=========
=	ERROR:  Forgot to CloseLibrary() both IntuitionBase & GfxBase.
=========
>      exit(0);
>   }


>   while (!done) {
>      WaitPort(myport); /* Wait for an incoming message. */
>      while ((msg = (struct FooMsg *)GetMsg(myport)))  /* Got one...! */
>      {
=========
	ERROR:  Missing ReplyMsg()
=========


>               strcpy(catmsg, "\0");

	Very, very slightly wasteful.  There is no such string as "\0"; that
means two '\0' characters in a row (since all strings are null terminated),
so the second (implicit) null will be ignored.  Either just use

		strcpy(catmsg, "");
or
		*catmsg = '\0';
or
		catmsg[0] = '\0';
or even
		#define CLEARSTRING(str)	(*(str) = '\0')
		CLEARSTRING(catmsg);

>            if (!strcmp(msg->message, "QUIT"))

	From a software engineering standpoint, some people think it's
preferable to define a macro for this string equivalence test, since the "!"
is easy to misinterpret to mean string INequality:

		#define StrEqual(s1, s2)	(strcmp(s1, s2) == 0)

		if (StrEqual(msg->message, "QUIT"))

>void shutdown(struct MsgPort *victim)
>{
>  FlushPort(victim);  /* Empty the queue (see func below) */
>  RemPort(victim);  /* We're no longer public.. */
>  DeleteMsgPort(victim); /* And now we don't exist. :) */
>  CloseLibrary(IntuitionBase);
>  CloseLibrary(GfxBase);
>  exit(0);
>}

	You can avoid a bunch of your "forgetting to free libraries"
problems above if you recode your shutdown() function and call it everywhere
instead of exit().

/****************************************************************************
* NewShutdown:  Close things and exit with the given return code.
****************************************************************************/
void NewShutdown(struct MsgPort *victim, int returnCode)
{
	if (victim)
	{
		FlushPort(victim);
		RemPort(victim);
		DeleteMsgPort(victim);
	}

	if (IntuitionBase)
		CloseLibrary(IntuitionBase);

	if (GfxBase)
		CloseLibrary(GfxBase);

	exit(returnCode);
}

Now think about where, in your above code, you could place calls like

		NewShutdown(NULL, RETURN_OK);
		NewShutdown(myport, RETURN_FAIL);
		etc.

Since all pointers are tested before being freed, it's safe to call this
function anytime.  (Make sure that IntuitionBase and GfxBase are initialized
to NULL though!!)

>   char message[50];   /* so we can pass strings to the server */

	I realize this is a little throwaway program, but you shouldn't
hard-code constants like "50" and "30+1" in your program.  It's just asking
for trouble later, if this code ever needs to be incorporated into something
real.  #define some constants instead.  A little effort beforehand will
save heartaches later.

                                                        Dan

 //////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
| Dan Barrett -- Dept of Computer Science, Lederle Graduate Research Center |
| University of Massachusetts, Amherst, MA  01003  --  barrett@cs.umass.edu |
 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////////
Newsgroups: comp.sys.amiga.programmer