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); +}