2e15b699069d147795f3b4bcdf50aa9d099be9ff
max
  Thu Mar 6 02:31:47 2014 -0800
moving the phoneHome business into cgiApoptosis.c/.h to make it callablefrom cart.c. We need to call it from cart.c as otherwise
cgiApoptosisSetup (originally: phoneHome) will be called after mysql
connections are opened. This leads to "mysql server has gone away" if
any CGI is not faster than the child process forked here. The child will
close all mysql connections of the parent process. With the new setup,
the childi is forked before any mysql connections are opened. Ideally
this would be all done in cheapcgi, but cheapcgi is not in the hg/lib
part of the code.

diff --git src/hg/lib/web.c src/hg/lib/web.c
index 1a676e3..760a229 100644
--- src/hg/lib/web.c
+++ src/hg/lib/web.c
@@ -3,63 +3,55 @@
 #include "hCommon.h"
 #include "obscure.h"
 #include "dnautil.h"
 #include "errabort.h"
 #include "htmshell.h"
 #include "web.h"
 #include "hPrint.h"
 #include "hdb.h"
 #include "hui.h"
 #include "hgConfig.h"
 #include "cheapcgi.h"
 #include "dbDb.h"
 #include "hgColors.h"
 #include "hubConnect.h"
 #include "search.h"
+#include "geoMirror.h"
+#include "trackHub.h"
+#include "versionInfo.h"
+
 #ifndef GBROWSE
 #include "axtInfo.h"
 #include "wikiLink.h"
 #include "googleAnalytics.h"
 #include "jsHelper.h"
 #endif /* GBROWSE */
-/* phoneHome business */
-#include <utime.h>
-#include <htmlPage.h>
-#include <signal.h>
-#include "geoMirror.h"
-#include <regex.h>
-#include "trackHub.h"
-#include <unistd.h>
-/* phoneHome business */
 
 
 /* flag that tell if the CGI header has already been outputed */
 boolean webHeadAlreadyOutputed = FALSE;
 /* flag that tell if text CGI header hsa been outputed */
 boolean webInTextMode = FALSE;
 static char *dbCgiName = "db";
 static char *orgCgiName = "org";
 static char *cladeCgiName = "clade";
 static char *extraStyle = NULL;
 
 /* globals: a cart and db for use in error handlers. */
 static struct cart *errCart = NULL;
 static char *errDb = NULL;
 
-// forward declaration to keep function ordering
-static void phoneHome();
-
 void textVaWarn(char *format, va_list args)
 {
 vprintf(format, args);
 puts("\n");
 }
 
 void softAbort()
 {
 exit(0);
 }
 
 void webPushErrHandlers(void)
 /* Push warn and abort handler for errAbort(). */
 {
 if (webInTextMode)
@@ -800,172 +792,51 @@
 
 if ((retDb == NULL) || !hDbExists(retDb))
     {
     retDb = hDefaultDb();
     }
 
 /* If genomes don't match, then get the default db for that genome */
 if (differentWord(genome, hGenome(retDb)))
     {
     retDb = hDefaultDbForGenome(genome);
     }
 
 return retDb;
 }
 
-static unsigned long expireSeconds = 0;
-static boolean lazarus = FALSE;
-void lazarusLives(unsigned long newExpireSeconds)
-/* Long running process requests more time */
-{
-lazarus = TRUE;
-expireSeconds = newExpireSeconds;
-}
-
-/* phoneHome business */
-static void cgiApoptosis(int status)
-/* signal handler for SIGALRM for phoneHome function and CGI expiration */
-{
-if (lazarus)
-    {
-    (void) alarm(expireSeconds);    /* CGI timeout */
-    lazarus = FALSE;
-    return;
-    }
-if (expireSeconds > 0)
-    {
-    /* want to see this error message in the apache error_log also */
-    fprintf(stderr, "cgiApoptosis: %lu seconds\n", expireSeconds);
-    /* most of our CGIs post a polite non-fatal message with this errAbort */
-    errAbort("procedures have exceeded timeout: %lu seconds, function has ended.\n", expireSeconds);
-    }
-exit(0);
-}
-
-static void phoneHome()
-{
-static boolean beenHere = FALSE;
-if (beenHere)  /* one at a time please */
-    return;
-beenHere = TRUE;
-
-char *expireTime = cfgOptionDefault("browser.cgiExpireMinutes", "20");
-unsigned expireMinutes = sqlUnsigned(expireTime);
-expireSeconds = expireMinutes * 60;
-
-char trashFile[PATH_LEN];
-safef(trashFile, sizeof(trashFile), "%s/registration.txt", trashDir());
-
-/* trashFile does not exist during command line execution */
-if(fileExists(trashFile))	/* update access time for trashFile */
-    {
-    struct utimbuf ut;
-    struct stat mystat;
-    ZeroVar(&mystat);
-    if (stat(trashFile,&mystat)==0)
-	{
-	ut.actime = clock1();
-	ut.modtime = mystat.st_mtime;
-	}
-    else
-	{
-	ut.actime = ut.modtime = clock1();
-	}
-    (void) utime(trashFile, &ut);
-    if (expireSeconds > 0)
-	{
-	(void) signal(SIGALRM, cgiApoptosis);
-	(void) alarm(expireSeconds);	/* CGI timeout */
-	}
-    return;
-    }
-
-char *scriptName = cgiScriptName();
-char *ip = getenv("SERVER_ADDR");
-if (scriptName && ip)  /* will not be true from command line execution */
-    {
-    FILE *f = fopen(trashFile, "w");
-    if (f)		/* rigamarole only if we can get a trash file */
-	{
-	time_t now = time(NULL);
-	char *localTime;
-	extern char *tzname[2];
-	struct tm *tm = localtime(&now);
-	localTime = sqlUnixTimeToDate(&now,FALSE); /* FALSE == localtime */
-	fprintf(f, "%s, %s, %s %s, %s\n", scriptName, ip, localTime,
-	    tm->tm_isdst ? tzname[1] : tzname[0], trashFile);
-	fclose(f);
-	chmod(trashFile, 0666);
-	pid_t pid0 = fork();
-	if (0 == pid0)	/* in child */
-	    {
-	    close(STDOUT_FILENO); /* do not hang up Apache finish for parent */
-	    expireSeconds = 0;	/* no error message from this exit */
-	    (void) signal(SIGALRM, cgiApoptosis);
-	    (void) alarm(30);	/* timeout here in 30 seconds */
-#include "versionInfo.h"
-	    char url[1024];
-            char *browserName = "browser.v";
-            if (hHostHasPrefix("browserbox"))
-                browserName = "browserBox.v";
-
-	    safef(url, sizeof(url), "%s%s%s%s%s%s%s", "http://",
-	"genomewiki.", "ucsc.edu/", "cgi-bin/useCount?", "version=", browserName,
-		CGI_VERSION);
-
-	    /* 30 second alarm will exit this page fetch if it does not work */
-	    (void) htmlPageGetWithCookies(url, NULL); /* ignore return */
-
-            // make sure we don't exit if we complete before 30 seconds, as
-            // otherwise we will close the mysql connections that the parent is
-            // still using
-            sleep(30); 
-            exit(0);
-            }	/* child of fork has done exit(0) normally or via alarm */
-	}		/* trash file open OK */
-    if (expireSeconds > 0)
-	{
-	(void) signal(SIGALRM, cgiApoptosis);
-	(void) alarm(expireSeconds);	/* CGI timeout */
-	}
-    }			/* an actual CGI binary */
-}			/* phoneHome()	*/
-/* phoneHome business */
-
 void getDbGenomeClade(struct cart *cart, char **retDb, char **retGenome,
 		      char **retClade, struct hash *oldVars)
 /* Examine CGI and cart variables to determine which db, genome, or clade
  *  has been selected, and then adjust as necessary so that all three are
  * consistent.  Detect changes and reset db-specific cart variables.
  * Save db, genome and clade in the cart so it will be consistent hereafter.
  * The order of preference here is as follows:
  * If we got a request that explicitly names the db, that takes
  * highest priority, and we synch the organism to that db.
  * If we get a cgi request for a specific organism then we use that
  * organism to choose the DB.  If just clade, go from there.
 
  * In the cart only, we use the same order of preference.
  * If someone requests an Genome we try to give them the same db as
  * was in their cart, unless the Genome doesn't match.
  */
 {
 boolean gotClade = hGotClade();
 *retDb = cgiOptionalString(dbCgiName);
 *retGenome = cgiOptionalString(orgCgiName);
 *retClade = cgiOptionalString(cladeCgiName);
-/* phoneHome business */
-phoneHome();
 
 /* Was the database passed in as a cgi param?
  * If so, it takes precedence and determines the genome. */
 if (*retDb && hDbExists(*retDb))
     {
     *retGenome = hGenome(*retDb);
     }
 /* If no db was passed in as a cgi param then was the organism (a.k.a. genome)
  * passed in as a cgi param?
  * If so, the we use the proper database for that genome. */
 else if (*retGenome && !sameWord(*retGenome, "0"))
     {
     *retDb = getDbForGenome(*retGenome, cart);
     *retGenome = hGenome(*retDb);
     }