61e0f504ce56c9770a274f6ffcbc6e9ea09281d0
hiram
  Mon Jun 6 11:36:17 2011 -0700
add selfApoptosis here too now it needs to become a library function
diff --git src/hg/perf/hgTracksRandom.c src/hg/perf/hgTracksRandom.c
index 1676136..64c384d 100644
--- src/hg/perf/hgTracksRandom.c
+++ src/hg/perf/hgTracksRandom.c
@@ -1,28 +1,29 @@
 /* hgTracksRandom - For a given organism, view hgTracks (default tracks) in random position.
                     Record display time. */
 
 #include "common.h"
 #include "chromInfo.h"
 #include "dystring.h"
 #include "hash.h"
 #include "hdb.h"
 #include "htmlPage.h"
 #include "linefile.h"
 #include "jksql.h"
 #include "options.h"
 #include "portable.h"
+#include <signal.h>
 
 static char const rcsid[] = "$Id: hgTracksRandom.c,v 1.16 2009/07/09 20:10:05 mikep Exp $";
 
 static char *database = NULL;
 static boolean quiet = FALSE;
 static struct hash *chromHash = NULL;
 
 /* command line option specifications */
 static struct optionSpec optionSpecs[] = {
     {"machines", OPTION_STRING},
     {"quiet", OPTION_BOOLEAN},
     {NULL, 0}
 };
 
 struct machine 
@@ -33,30 +34,51 @@
 
 struct machine *machineList;
 
 void usage()
 /* Explain usage and exit. */
 {
 errAbort(
   "hgTracksRandom - Time default view for random position of default genome\n"
   "usage:\n"
   "  hgTracksRandom <machines> [options]\n"
   "options:\n"
   "   <machines> is a file listing the machines to test\n"
   "   -quiet - only outputs the timing numbers, no machine names\n");
 }
 
+/* this is the second instance of this, it needs to find its program
+ * name to become a generic function in the libs
+ */
+/* if this Apoptosis function becomes more popular, it can go into the libs
+ * there is a similar function in hg/lib/web.c cgiApoptosis()
+ */
+static unsigned long expireSeconds = 0;
+/* to avoid long running processes on the RR */
+static void selfApoptosis(int status)
+/* signal handler for SIGALRM expiration */
+{
+if (expireSeconds > 0)
+    {
+    /* want to see this error message in the apache error_log also */
+    fprintf(stderr, "hgTracksRandom selfApoptosis: %lu seconds\n", expireSeconds);
+    /* this message may show up somewhere */
+    errAbort("procedures have exceeded timeout: %lu seconds, function has ended.\n", expireSeconds);
+    }
+exit(0);
+}
+
 void getMachines(char *filename)
 /* Read in list of machines to use. */
 {
 struct lineFile *lf = lineFileOpen(filename, TRUE);
 char *line;
 int lineSize;
 struct machine *machine;
 
 while (lineFileNext(lf, &line, &lineSize))
     {
     AllocVar(machine);
     // is this equivalent to slAddHead?
     machine->name = line;
     machine->next = machineList;
     machineList = machine;
@@ -130,30 +152,34 @@
 int main(int argc, char *argv[])
 {
 struct dyString *dy = NULL;
 int startPos = 1;
 char *chrom = "chr1";
 int chromSize = 0;
 int windowSize = 100000;
 struct machine *machinePos;
 time_t now;
 char testTime[100];
 char testDate[100];
 long elapsedTime = 0;
 
 optionInit(&argc, argv, optionSpecs);
 
+expireSeconds = 300;	/* 5 minutes */
+(void) signal(SIGALRM, selfApoptosis);
+(void) alarm(expireSeconds);	/* CGI timeout */
+
 quiet = optionExists("quiet");
 now = time(NULL);
 strftime(testTime, 100, "%H:%M", localtime(&now));
 strftime(testDate, 100, "%B %d, %Y", localtime(&now));
 if (!quiet)
     printf("%s %s\n", testDate, testTime);
 
 if (argc != 2)
     usage();
 
 srand( (unsigned) time(NULL) );
 
 database = hDefaultDbForGenome(NULL); // default human db
 
 chromHash = loadAllChromInfo();