- fixed the slow memory leak problem.
[codemux.git] / codemux.c
index 3ca9ba0..5ba4b01 100644 (file)
--- a/codemux.c
+++ b/codemux.c
 #include <unistd.h>
 #include <string.h>
 #include "codemuxlib.h"
+#include "debug.h"
+
+#ifdef DEBUG
+HANDLE hdebugLog;
+int defaultTraceSync;
+#endif
 
 #define CONF_FILE "/etc/codemux/codemux.conf"
 #define DEMUX_PORT 80
@@ -31,6 +37,8 @@
    among them */
 #define FAIRNESS_CUTOFF (MAX_CONNS * 0.85)
 
+/* codemux version */
+#define CODEMUX_VERSION "0.3"
 
 typedef struct FlowBuf {
   int fb_refs;                 /* num refs */
@@ -107,8 +115,10 @@ DumpStatus(int fd)
   int len;
 
   sprintf(start, 
+         "CoDemux version %s\n"
          "numForks %d, numActiveSlices %d, numTotalSliceConns %d\n"
          "numNeedingHeaders %d, anySliceXidsNeeded %d\n",
+         CODEMUX_VERSION,
          numForks, numActiveSlices, numTotalSliceConns,
          numNeedingHeaders, anySliceXidsNeeded);
   start += strlen(start);
@@ -162,14 +172,14 @@ GetSliceXids(void)
     int xid;
 
     if ((temp = strchr(line, ':')) == NULL)
-      continue;                        /* weird line */
+      goto next_line;                  /* weird line */
     *temp = '\0';              /* terminate slice name */
     temp++;
     if ((temp = strchr(temp+1, ':')) == NULL)
-      continue;                        /* weird line */
+      goto next_line;  /* weird line */
     if ((xid = atoi(temp+1)) < 1)
-      continue;                        /* weird xid */
-
+      goto next_line;  /* weird xid */
+    
     /* we've got a slice name and xid, let's try to match */
     for (i = 0; i < numSlices; i++) {
       if (slices[i].si_xid == 0 &&
@@ -178,6 +188,9 @@ GetSliceXids(void)
        break;
       }
     }
+  next_line:
+    if (line)
+      xfree(line);
   }
 
   /* assume service 0 is the root service, and don't check it since
@@ -234,11 +247,11 @@ WhichSlicePos(char *slice)
 
   if (numSlices >= numSlicesAlloc) {
     numSlicesAlloc = MAX(8, numSlicesAlloc * 2);
-    slices = realloc(slices, numSlicesAlloc * sizeof(SliceInfo));
+    slices = xrealloc(slices, numSlicesAlloc * sizeof(SliceInfo));
   }
 
   memset(&slices[numSlices], 0, sizeof(SliceInfo));
-  slices[numSlices].si_sliceName = strdup(slice);
+  slices[numSlices].si_sliceName = xstrdup(slice);
   numSlices++;
   return(numSlices-1);
 }
@@ -278,7 +291,7 @@ ReadConfFile(void)
     ServiceSig serv;
     int port;
     if (line != NULL)
-      free(line);
+      xfree(line);
     
     if ((line = GetNextLine(f)) == NULL)
       break;
@@ -305,7 +318,7 @@ ReadConfFile(void)
     }
     if (num >= numAlloc) {
       numAlloc = MAX(numAlloc * 2, 8);
-      servs = realloc(servs, numAlloc * sizeof(ServiceSig));
+      servs = xrealloc(servs, numAlloc * sizeof(ServiceSig));
     }
     serv.ss_slicePos = WhichSlicePos(serv.ss_slice);
     if (slices[serv.ss_slicePos].si_inUse == 0 &&
@@ -326,10 +339,10 @@ ReadConfFile(void)
   }
 
   for (i = 0; i < numServices; i++) {
-    free(serviceSig[i].ss_host);
-    free(serviceSig[i].ss_slice);
+    xfree(serviceSig[i].ss_host);
+    xfree(serviceSig[i].ss_slice);
   }
-  free(serviceSig);
+  xfree(serviceSig);
   serviceSig = servs;
   numServices = num;
   confFileReadTime = statBuf.st_mtime;
@@ -645,6 +658,10 @@ ReallyCloseSocks(void)
       SliceConnsDec(sockInfo[fd].si_whichService);
       sockInfo[fd].si_whichService = -1;
     }
+    /* KyoungSoo*/
+    if (sockInfo[fd].si_peerFd >= 0) {
+      sockInfo[sockInfo[fd].si_peerFd].si_peerFd = -1;
+    }
   }
   numSocksToClose = 0;
 }
@@ -664,7 +681,7 @@ SocketReadyToRead(int fd)
   }
 
   if ((fb = si->si_readBuf) == NULL) {
-    fb = si->si_readBuf = calloc(1, sizeof(FlowBuf));
+    fb = si->si_readBuf = xcalloc(1, sizeof(FlowBuf));
     fb->fb_refs = 1;
     if (si->si_peerFd >= 0) {
       sockInfo[si->si_peerFd].si_writeBuf = fb;
@@ -673,10 +690,10 @@ SocketReadyToRead(int fd)
   }
 
   if (fb->fb_buf == NULL)
-    fb->fb_buf = malloc(FB_ALLOCSIZE);
+    fb->fb_buf = xmalloc(FB_ALLOCSIZE);
 
   /* determine read buffer size - if 0, then block reads and return */
-  if ((spaceLeft = FB_SIZE - fb->fb_used) < 0) {
+  if ((spaceLeft = FB_SIZE - fb->fb_used) <= 0) {
     if (si->si_needsHeaderSince) {
       write(fd, err400BadRequest, strlen(err400BadRequest));
       CloseSock(fd);
@@ -686,8 +703,8 @@ SocketReadyToRead(int fd)
       ClearFd(fd, &masterReadSet);
       return;
     }
-  }
-
+  } 
+  
   /* read as much as allowed, and is available */
   if ((res = read(fd, &fb->fb_buf[fb->fb_used], spaceLeft)) == 0) {
     CloseSock(fd);
@@ -700,6 +717,7 @@ SocketReadyToRead(int fd)
   if (res == -1) {
     if (errno == EAGAIN)
       return;
+    TRACE("fd=%d errno=%d errstr=%s\n",fd, errno, strerror(errno));
     CloseSock(fd);
     if (fb->fb_used == 0 && si->si_peerFd >= 0) {
       CloseSock(si->si_peerFd);
@@ -709,7 +727,7 @@ SocketReadyToRead(int fd)
   }
   fb->fb_used += res;
   fb->fb_buf[fb->fb_used] = 0; /* terminate it for convenience */
-  printf("sock %d, read %d, total %d\n", fd, res, fb->fb_used);
+  //  printf("sock %d, read %d, total %d\n", fd, res, fb->fb_used);
 
   /* if we need header, check if we've gotten it. if so, do
      modifications and continue. if not, check if we've read the
@@ -738,6 +756,7 @@ SocketReadyToRead(int fd)
        (numTotalSliceConns > FAIRNESS_CUTOFF && 
         slice->si_numConns > MAX_CONNS/numActiveSlices)) {
       write(fd, err503TooBusy, strlen(err503TooBusy));
+      TRACE("CloseSock(): fd=%d too busy\n", fd);
       CloseSock(fd);
       return;
     }
@@ -758,6 +777,7 @@ SocketReadyToRead(int fd)
     numNeedingHeaders--;
     if (StartConnect(fd, whichService) != SUCCESS) {
       write(fd, err503Unavailable, strlen(err503Unavailable));
+      TRACE("CloseSock(): fd=%d StartConnect() failed\n", fd);
       CloseSock(fd);
       return;
     }
@@ -767,9 +787,13 @@ SocketReadyToRead(int fd)
   /* write anything possible */
   if (WriteAvailData(si->si_peerFd) != SUCCESS) {
     /* assume the worst and close */
+    TRACE("CloseSock(): fd=%d WriteAvailData() failed errno=%d errstr=%s\n", 
+         fd, errno, strerror(errno));
     CloseSock(fd);
-    CloseSock(si->si_peerFd);
-    si->si_peerFd = -1;
+    if (si->si_peerFd >=0) {
+      CloseSock(si->si_peerFd);
+      si->si_peerFd = -1;
+    }
   }
 }
 /*-----------------------------------------------------------------*/
@@ -790,6 +814,8 @@ SocketReadyToWrite(int fd)
   /* if we have data, write it */
   if (WriteAvailData(fd) != SUCCESS) {
    /* assume the worst and close */
+    TRACE("CloseSock(): fd=%d WriteAvailData() failed errno=%d errstr=%s\n", 
+         fd, errno, strerror(errno));
     CloseSock(fd);
     if (si->si_peerFd >= 0) {
       CloseSock(si->si_peerFd);
@@ -799,8 +825,9 @@ SocketReadyToWrite(int fd)
   }
 
   /* if peer is closed and we're done writing, we should close */
-  if (si->si_peerFd < 0 && si->si_writeBuf->fb_used == 0)
+  if (si->si_peerFd < 0 && si->si_writeBuf->fb_used == 0) {
     CloseSock(fd);
+  }
 }
 /*-----------------------------------------------------------------*/
 static void
@@ -836,7 +863,7 @@ CloseReqlessConns(void)
   /* if it's too old, close it */
   for (i = 0; i < highestSetFd+1; i++) {
     if (sockInfo[i].si_needsHeaderSince &&
-       (now - sockInfo[i].si_needsHeaderSince) > maxAge)
+       (now - sockInfo[i].si_needsHeaderSince) > maxAge) 
       CloseSock(i);
   }
 }
@@ -910,6 +937,11 @@ MainLoop(int lisSock)
       socklen_t lenAddr = sizeof(addr);
       if ((newSock = accept(lisSock, (struct sockaddr *) &addr, 
                            &lenAddr)) >= 0) {
+       /* make socket non-blocking */
+       if (fcntl(newSock, F_SETFL, O_NONBLOCK) < 0) {
+         close(newSock);
+         continue;
+       }
        memset(&sockInfo[newSock], 0, sizeof(SockInfo));
        sockInfo[newSock].si_needsHeaderSince = now;
        numNeedingHeaders++;
@@ -1025,6 +1057,10 @@ main(int argc, char *argv[])
   /* open the log file */
   logFd = OpenLogFile();
 
+
+  /* write down the version */
+  fprintf(stderr, "CoDemux version %s started\n", CODEMUX_VERSION);
+
   while (1) {
     numForks++;
     if (fork()) {