home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #1 / NN_1993_1.iso / spool / comp / sys / amiga / programm / 18368 < prev    next >
Encoding:
Internet Message Format  |  1993-01-08  |  4.4 KB

  1. Path: sparky!uunet!zaphod.mps.ohio-state.edu!malgudi.oar.net!caen!nic.umass.edu!dime!barrett
  2. From: barrett@astro.cs.umass.edu (Daniel Barrett)
  3. Newsgroups: comp.sys.amiga.programmer
  4. Subject: Re: Enough talk.  FILE: server.c
  5. Message-ID: <58457@dime.cs.umass.edu>
  6. Date: 8 Jan 93 17:46:25 GMT
  7. References: <C0IyF5.9Gv@usenet.ucs.indiana.edu>
  8. Sender: news@dime.cs.umass.edu
  9. Reply-To: barrett@astro.cs.umass.edu (Daniel Barrett)
  10. Organization: BLAZEMONGER INCORPORATED
  11. Lines: 132
  12.  
  13. In article <C0IyF5.9Gv@usenet.ucs.indiana.edu> shulick@navajo.ucs.indiana.edu writes:
  14. >Well, I've complained enough about memory leaks.  =u)  Here's the server
  15. >I wrote that is faulty.  About 8k bytes are not freed, and I can't
  16. >figure out why.
  17.  
  18.     Someone else has mentioned the missing ReplyMsg(), but here are
  19. some more tips.
  20.  
  21. >   if (!(IntuitionBase = (struct Library *)
  22. >     OpenLibrary("intuition.library", 37)))
  23. >   {
  24. >      Alert(AG_OpenLib | AO_Intuition);
  25. >      exit(0);
  26. >   }
  27. >   if (!(GfxBase = (struct Library *)OpenLibrary("graphics.library", 37)))
  28. >   {
  29. >      Alert(AG_OpenLib | AO_GraphicsLib);
  30. =========
  31. =    ERROR:  Forgot to CloseLibrary(IntuitionBase) here.
  32. =========
  33. >      exit(0);
  34. =========
  35. =    "exit(0)" generally means that the program exited with a "success"
  36. =    return code.  But your program is failing.  Use the DOS return codes
  37. =    in (I think) <dos/dosextens.h>:  RETURN_OK, RETURN_FAIL, etc.
  38. =========
  39. >   }
  40.  
  41.  
  42. >   if (!(myport = CreateMsgPort()))  /* Create the port.. */
  43. >   {
  44. >      Alert(AN_CreatePort);
  45. =========
  46. =    ERROR:  Forgot to CloseLibrary() both IntuitionBase & GfxBase.
  47. =========
  48. >      exit(0);
  49. >   }
  50.  
  51.  
  52. >   while (!done) {
  53. >      WaitPort(myport); /* Wait for an incoming message. */
  54. >      while ((msg = (struct FooMsg *)GetMsg(myport)))  /* Got one...! */
  55. >      {
  56. =========
  57.     ERROR:  Missing ReplyMsg()
  58. =========
  59.  
  60.  
  61. >               strcpy(catmsg, "\0");
  62.  
  63.     Very, very slightly wasteful.  There is no such string as "\0"; that
  64. means two '\0' characters in a row (since all strings are null terminated),
  65. so the second (implicit) null will be ignored.  Either just use
  66.  
  67.         strcpy(catmsg, "");
  68. or
  69.         *catmsg = '\0';
  70. or
  71.         catmsg[0] = '\0';
  72. or even
  73.         #define CLEARSTRING(str)    (*(str) = '\0')
  74.         CLEARSTRING(catmsg);
  75.  
  76. >            if (!strcmp(msg->message, "QUIT"))
  77.  
  78.     From a software engineering standpoint, some people think it's
  79. preferable to define a macro for this string equivalence test, since the "!"
  80. is easy to misinterpret to mean string INequality:
  81.  
  82.         #define StrEqual(s1, s2)    (strcmp(s1, s2) == 0)
  83.  
  84.         if (StrEqual(msg->message, "QUIT"))
  85.  
  86. >void shutdown(struct MsgPort *victim)
  87. >{
  88. >  FlushPort(victim);  /* Empty the queue (see func below) */
  89. >  RemPort(victim);  /* We're no longer public.. */
  90. >  DeleteMsgPort(victim); /* And now we don't exist. :) */
  91. >  CloseLibrary(IntuitionBase);
  92. >  CloseLibrary(GfxBase);
  93. >  exit(0);
  94. >}
  95.  
  96.     You can avoid a bunch of your "forgetting to free libraries"
  97. problems above if you recode your shutdown() function and call it everywhere
  98. instead of exit().
  99.  
  100. /****************************************************************************
  101. * NewShutdown:  Close things and exit with the given return code.
  102. ****************************************************************************/
  103. void NewShutdown(struct MsgPort *victim, int returnCode)
  104. {
  105.     if (victim)
  106.     {
  107.         FlushPort(victim);
  108.         RemPort(victim);
  109.         DeleteMsgPort(victim);
  110.     }
  111.  
  112.     if (IntuitionBase)
  113.         CloseLibrary(IntuitionBase);
  114.  
  115.     if (GfxBase)
  116.         CloseLibrary(GfxBase);
  117.  
  118.     exit(returnCode);
  119. }
  120.  
  121. Now think about where, in your above code, you could place calls like
  122.  
  123.         NewShutdown(NULL, RETURN_OK);
  124.         NewShutdown(myport, RETURN_FAIL);
  125.         etc.
  126.  
  127. Since all pointers are tested before being freed, it's safe to call this
  128. function anytime.  (Make sure that IntuitionBase and GfxBase are initialized
  129. to NULL though!!)
  130.  
  131. >   char message[50];   /* so we can pass strings to the server */
  132.  
  133.     I realize this is a little throwaway program, but you shouldn't
  134. hard-code constants like "50" and "30+1" in your program.  It's just asking
  135. for trouble later, if this code ever needs to be incorporated into something
  136. real.  #define some constants instead.  A little effort beforehand will
  137. save heartaches later.
  138.  
  139.                                                         Dan
  140.  
  141.  //////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  142. | Dan Barrett -- Dept of Computer Science, Lederle Graduate Research Center |
  143. | University of Massachusetts, Amherst, MA  01003  --  barrett@cs.umass.edu |
  144.  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////////
  145.