--- ntop/globals-structtypes.h 2003-04-14 12:49:10.000000000 -0500
+++ ntop/globals-structtypes.h 2003-06-05 10:24:16.000000000 -0500
@@ -170,7 +170,7 @@
 
 typedef struct pthreadMutex {
   pthread_mutex_t mutex;
-  char   isLocked, isInitialized;
+  char   isLocked, isInitialized, isValid;
   char   lockFile[64];
   int    lockLine;
   pid_t  lockPid;
@@ -1366,6 +1366,9 @@
   int basentoppid;         /* Used for writing to /var/run/ntop.pid (or whatever) */
                            /*XML n basentoppid          Execenv          "" */
 
+  int childntoppid;        /* Zero unless we're in a child */
+                           /*XMLNOTE ignore this - transient */
+
 #ifdef MAKE_WITH_XMLDUMP
   char hostName[MAXHOSTNAMELEN];
                            /*XMLNOTE skip - it's in the header */
--- ntop/http.c 2003-05-29 15:49:26.000000000 -0500
+++ ntop/http.c 2003-06-05 14:58:35.000000000 -0500
@@ -1111,6 +1113,8 @@
 /* ************************* */
 
 static RETSIGTYPE quitNow(int signo _UNUSED_) {
+  traceEvent(CONST_TRACE_ERROR, "http generation failed, alarm() tripped. Please report this to ntop list!");
+  returnHTTPrequestTimedOut();
   exit(0);
 }
 
@@ -1573,6 +1577,11 @@
 	  return(0);
 	} else {
 
+          /* This is zero in the parent copy of the structure,
+             make it non-zero here so we can tell later on  (BMS 2003-06)
+           */
+          myGlobals.childntoppid = getpid();
+
 #ifdef MAKE_WITH_HTTPSIGTRAP
           signal(SIGSEGV, httpcleanup);
           signal(SIGHUP,  httpcleanup);
@@ -1583,7 +1593,6 @@
           signal(SIGFPE,  httpcleanup);
           signal(SIGKILL, httpcleanup);
           signal(SIGPIPE, httpcleanup);
-          signal(SIGALRM, httpcleanup);
           signal(SIGTERM, httpcleanup);
           signal(SIGUSR1, httpcleanup);
           signal(SIGUSR2, httpcleanup);
@@ -1611,7 +1620,7 @@
 	  if(myGlobals.webPort > 0) closeNwSocket(&myGlobals.sock);
 
 	  signal(SIGALRM, quitNow);
-	  alarm(120); /* Don't freeze */
+	  alarm(15); /* Don't freeze */
 	}
       }
     }
--- ntop/initialize.c 2003-04-14 03:57:32.000000000 -0500
+++ ntop/initialize.c 2003-06-05 11:24:10.000000000 -0500
@@ -850,6 +850,19 @@
 
 /* ************************************************************ */
 
+#ifdef CFG_MULTITHREADED
+void InvalidateMutexes (void) {
+  myGlobals.gdbmMutex.isValid = 0;
+  myGlobals.tcpSessionsMutex.isValid = 0;
+  myGlobals.packetQueueMutex.isValid = 0;
+  myGlobals.hostsHashMutex.isValid = 0;
+ #ifdef MAKE_ASYNC_ADDRESS_RESOLUTION
+  myGlobals.addressResolutionMutex.isValid = 0;
+ #endif
+  createMutex(&myGlobals.graphMutex);  /* data to synchronize thread access to graph generation */
+}
+#endif /* CFG_MULTITHREADED */
+
 /*
  * Initialize all the threads used by ntop to:
  * a) sniff packets from NICs and push them in internal data structures
@@ -862,6 +875,9 @@
 
 #ifdef CFG_MULTITHREADED
 
+  i = pthread_atfork(NULL, NULL, &InvalidateMutexes);
+  traceEvent(CONST_TRACE_INFO, "NOTE: atfork() handler registered for mutexes, rc %d", i);
+
   /*
    * Create two variables (semaphores) used by functions in pbuf.c to queue packets
    */
@@ -884,7 +900,6 @@
 #endif
 
   createMutex(&myGlobals.gdbmMutex);        /* data to synchronize thread access to db files */
-  createMutex(&myGlobals.graphMutex);       /* data to synchronize thread access to graph generation */
   createMutex(&myGlobals.tcpSessionsMutex); /* data to synchronize TCP sessions access */
 
   /*
--- ntop/main.c 2003-04-11 15:05:04.000000000 -0500
+++ ntop/main.c 2003-06-05 10:30:52.000000000 -0500
@@ -757,10 +757,10 @@
   
   if((argc == 2) && (argv[1][0] != '-')) {
     /* Options specified on a configuration file */
-    FILE *fd = fopen(argv[optind], "r");
-
-    if(fd != NULL) {
+    FILE *cfd = fopen(argv[optind], "r");
 
+    if(cfd != NULL) {
+      fclose(cfd); 
 
     } else {
       printf("FATAL ERROR: unable to open configuration file '%s'\n", argv[optind]);
--- ntop/ntop.c 2003-04-01 09:43:06.000000000 -0600
+++ ntop/ntop.c 2003-06-05 11:26:02.000000000 -0500
@@ -947,7 +947,6 @@
     deleteMutex(&myGlobals.addressResolutionMutex);
 #endif
   deleteMutex(&myGlobals.hostsHashMutex);
-  deleteMutex(&myGlobals.graphMutex);
 
   if(myGlobals.isLsofPresent)
     deleteMutex(&myGlobals.lsofMutex);
--- ntop/util.c 2003-05-20 10:18:32.000000000 -0500
+++ ntop/util.c 2003-06-05 14:55:26.000000000 -0500
@@ -949,6 +949,7 @@
   } else {
 
     mutexId->isInitialized = 1;
+    mutexId->isValid       = 1;
 
   }
 
@@ -993,6 +994,13 @@
     return(-1);
   }
 
+  if(!mutexId->isValid) {
+    traceEvent(CONST_TRACE_ERROR,
+	       "ERROR: accessMutex() call with an INVALID mutex [%s:%d]\n",
+	       fileName, fileLine);
+    return(-1);
+  }
+
   if(!mutexId->isInitialized) {
     traceEvent(CONST_TRACE_ERROR,
 	       "ERROR: accessMutex() call with an UN-INITIALIZED mutex [%s:%d]\n",
@@ -1067,6 +1075,13 @@
     return(-1);
   }
 
+  if(!mutexId->isValid) {
+    traceEvent(CONST_TRACE_ERROR,
+	       "ERROR: tryLockMutex() call with an INVALID mutex [%s:%d]\n",
+	       fileName, fileLine);
+    return(-1);
+  }
+
   if(!mutexId->isInitialized) {
     traceEvent(CONST_TRACE_ERROR,
 	       "ERROR: tryLockMutex() call with an UN-INITIALIZED mutex [%s:%d]\n",
@@ -1145,6 +1160,13 @@
     return(-1);
   }
 
+  if(!mutexId->isValid) {
+    traceEvent(CONST_TRACE_ERROR,
+	       "ERROR: isMutexLocked() call with an INVALID mutex [%s:%d]\n",
+	       fileName, fileLine);
+    return(-1);
+  }
+
   if(!mutexId->isInitialized) {
     traceEvent(CONST_TRACE_ERROR,
 	       "ERROR: isMutexLocked() call with an UN-INITIALIZED mutex [%s:%d]\n",
@@ -1186,6 +1208,13 @@
     return(-1);
   }
 
+  if(!mutexId->isValid) {
+    traceEvent(CONST_TRACE_ERROR,
+	       "ERROR: releaseMutex() call with an INVALID mutex [%s:%d]\n",
+	       fileName, fileLine);
+    return(-1);
+  }
+
   if(!mutexId->isInitialized) {
     traceEvent(CONST_TRACE_ERROR,
 	       "ERROR: releaseMutex() call with an UN-INITIALIZED mutex [%s:%d]\n",
@@ -4241,6 +4270,9 @@
      || (strlen(srcHost->fingerprint) < 28))
     return;
 
+  if(myGlobals.childntoppid != 0)
+    return; /* Reporting fork()ed child, don't update! */
+
   accessAddrResMutex("makeHostLink");
 
   snprintf(fingerprint, sizeof(fingerprint), "%s", srcHost->fingerprint);
@@ -4414,14 +4446,16 @@
   datum theData;
 
 #ifdef CFG_MULTITHREADED
-  if(myGlobals.gdbmMutex.isInitialized == 1) /* Mutex not yet initialized ? */
+  if((myGlobals.childntoppid == 0)            /* This is the base thread */ &&
+     (myGlobals.gdbmMutex.isInitialized == 1) /* and Mutex is initialized */ )
     accessMutex(&myGlobals.gdbmMutex, "ntop_gdbm_fetch");
 #endif
 
   theData = gdbm_fetch(g, d);
   
 #ifdef CFG_MULTITHREADED
-  if(myGlobals.gdbmMutex.isInitialized == 1) /* Mutex not yet initialized ? */
+  if((myGlobals.childntoppid == 0)            /* This is the base thread */ &&
+     (myGlobals.gdbmMutex.isInitialized == 1) /* and Mutex is initialized */ )
     releaseMutex(&myGlobals.gdbmMutex);
 #endif
 
