bb0c928c8f742748411ec50a2e155880b2d57e49
kent
  Thu Sep 12 14:09:25 2013 -0700
Adding parallelFetchInterruptable, which has a callback that checks for interrupt.
diff --git src/lib/paraFetch.c src/lib/paraFetch.c
index 354a320..e6e0189 100644
--- src/lib/paraFetch.c
+++ src/lib/paraFetch.c
@@ -147,33 +147,37 @@
 
 if (pPcList != NULL)
     *pPcList = pcList;
 if (pUrl != NULL)
     *pUrl = url;
 if (pFileSize != NULL)
     *pFileSize = fileSize;
 if (pDateString != NULL)
     *pDateString = dateString;
 if (pTotalDownloaded != NULL)
     *pTotalDownloaded = totalDownloaded;
 
 return TRUE;
 }
 
-
-boolean parallelFetch(char *url, char *outPath, int numConnections, int numRetries, boolean newer, boolean progress)
-/* Open multiple parallel connections to URL to speed downloading */
+boolean parallelFetchInterruptable(char *url, char *outPath, int numConnections, int numRetries, 
+    boolean newer, boolean progress,
+    boolean (*interrupt)(void *context),  void *context)
+/* Open multiple parallel connections to URL to speed downloading.  If interrupt function 
+ * is non-NULL,  then it gets called passing the context parameter,  and if it returns
+ * TRUE the fetch is interrupted.   Overall the parallelFetchInterruptable returns TRUE
+ * when the function succeeds without interrupt, FALSE otherwise. */
 {
 char *origPath = outPath;
 char outTemp[1024];
 safef(outTemp, sizeof(outTemp), "%s.paraFetch", outPath);
 outPath = outTemp;
 /* get the size of the file to be downloaded */
 off_t fileSize = 0;
 off_t totalDownloaded = 0;
 ssize_t sinceLastStatus = 0;
 char *dateString = "";
 int star = 1;  
 int starMax = 20;  
 int starStep = 1;
 // TODO handle case-sensitivity of protocols input
 if (startsWith("http://",url) || startsWith("https://",url))
@@ -370,32 +374,36 @@
 #define BUFSIZE 65536 * 4
 char buf[BUFSIZE];
 
 /* create paraFetchStatus right away for monitoring programs */
 paraFetchWriteStatus(origPath, pcList, url, fileSize, dateString, FALSE);
 sinceLastStatus = 0;
 
 int retryCount = 0;
 
 time_t startTime = time(NULL);
 
 #define SELTIMEOUT 5
 #define RETRYSLEEPTIME 30    
 while (TRUE)
     {
-
     verbose(2,"Top of big loop\n");
+    if (interrupt != NULL && (*interrupt)(context))
+	{
+	verbose(1, "Interrupted paraFetch.\n");
+	return FALSE;
+	}
 
     if (progress)
 	{
 	while (totalDownloaded >= star * starStep)
 	    {
 	    printf("*");fflush(stdout);
 	    ++star;
 	    }
 	}
 
     /* are we done? */
     if (connOpen == 0)
 	{
 	boolean done = TRUE;
 	for(pc = pcList; pc; pc = pc->next)
@@ -658,16 +666,23 @@
 	printf(" %0.1f MB/sec", mbpersec);
 	}
     printf("\n");fflush(stdout);
     }
 
 if (fileSize != -1 && totalDownloaded != fileSize)
     {
     warn("Unexpected result: Total downloaded bytes %lld is not equal to fileSize %lld"
 	, (long long) totalDownloaded
 	, (long long) fileSize);
     return FALSE;
     }
 return TRUE;
 }
 
+boolean parallelFetch(char *url, char *outPath, int numConnections, int numRetries, 
+    boolean newer, boolean progress)
+/* Open multiple parallel connections to URL to speed downloading */
+{
+return parallelFetchInterruptable(url, outPath, numConnections, numRetries, 
+    newer, progress, NULL, NULL);
+}