17a171a4b239e6e761e8f73a9b49451d7c918811 braney Wed Jun 19 17:14:25 2019 -0700 changes in response to code review (thanks Jonathan!) diff --git src/hg/lib/trackDbCustom.c src/hg/lib/trackDbCustom.c index f66a738..9ebf2e6 100644 --- src/hg/lib/trackDbCustom.c +++ src/hg/lib/trackDbCustom.c @@ -1638,30 +1638,36 @@ lmAllocArray(lm, newTdb->restrictList, newTdb->restrictCount); int ii; for(ii=0; ii < newTdb->restrictCount; ii++) newTdb->restrictList[ii] = lmCloneString(lm, tdb->restrictList[ii]); } newTdb->url = lmCloneString(lm, tdb->url); newTdb->html = lmCloneString(lm, tdb->html); newTdb->grp = lmCloneString(lm, tdb->grp); newTdb->parentName = lmCloneString(lm, tdb->parentName); newTdb->viewHash = NULL; newTdb->children = NULL; newTdb->overrides = NULL; newTdb->tdbExtras = NULL; +// at this point the settingsHash has values in it that aren't recorded in the static settings +// string, and there are a couple of values in the settings string that for some reason aren't in the hash, +// soo.... rebuild the settings string to have both its original contents, as well as everything that's +// been added to the hash since it was first read in. This string will be converted back into a hash +// (allocated in non-shared memory) the first time trackDbSetting() is called. There will be some duplications, +// but that won't cause problems. struct dyString *dy = newDyString(1000); struct hashEl *hel = hashElListHash(tdb->settingsHash); dyStringPrintf(dy,"%s\n", tdb->settings); for(; hel; hel = hel->next) dyStringPrintf(dy,"%s %s\n", hel->name, (char *)hel->val); newTdb->settings = lmCloneString(lm, dy->string); newTdb->settingsHash = NULL; return newTdb; } struct trackDb *lmCloneTdbList(struct lm *lm, struct trackDb *list, struct trackDb *parent, struct hash *superHash) /* clone a list of tdb structures. */ { struct trackDb *tdb, *prevTdb = NULL, *newList = NULL; @@ -1669,51 +1675,51 @@ { struct trackDb *newTdb = lmCloneTdb(lm, tdb, parent, superHash); if (prevTdb) prevTdb->next = newTdb; else newList = newTdb; prevTdb = newTdb; } return newList; } -static struct trackDb *checkCache(char *string, time_t time) +static struct trackDb *checkCache(char *string, time_t time, char *trackDbCacheDir) /* Check to see if this db or hub has a cached trackDb. string is either a db * or a SHA1 calculated from a hubUrl. Use time to see if cache should be flushed. */ { char dirName[4096]; -safef(dirName, sizeof dirName, "/dev/shm/trackDbCache/%s", string); +safef(dirName, sizeof dirName, "/dev/shm/%s/%s", trackDbCacheDir, string); if (!isDirectory(dirName)) { - cacheLog("abandonig cache search for %s, no directory", string); + cacheLog("abandoning cache search for %s, no directory", string); return NULL; } // look for files named by the address they use struct slName *files = listDir(dirName, "*"); char fileName[4096]; for(; files; files = files->next) { char sharedMemoryName[4096]; - safef(sharedMemoryName, sizeof sharedMemoryName, "trackDbCache/%s/%s", string, files->name); - safef(fileName, sizeof fileName, "/dev/shm/trackDbCache/%s/%s", string, files->name); + safef(sharedMemoryName, sizeof sharedMemoryName, "%s/%s/%s", trackDbCacheDir, string, files->name); + safef(fileName, sizeof fileName, "/dev/shm/%s/%s/%s", trackDbCacheDir, string, files->name); cacheLog("checking cache file %s", fileName); struct stat statBuf; if (stat(fileName, &statBuf) < 0) { // if we can't stat the shared memory, let's just toss it cacheLog("can't stat file %s, unlinking", fileName); unlink(fileName); continue; } if (statBuf.st_mtime < time) { // if the cache is older than the data, toss it cacheLog("cache is older than source, unlinking"); @@ -1734,70 +1740,70 @@ u_char *mem = (u_char *) mmap((void *)address, size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); cacheLog("asked for memory %lx of size %ld, got %lx",address, size, mem); if ((unsigned long)mem == address) // make sure we can get this address { u_char *ret = mem + lmBlockHeaderSize(); cacheLog("using cache memory at %lx", ret); return (struct trackDb *)ret; } cacheLog("unmapping cache memory at %lx", mem); munmap((void *)mem, size); close(fd); } -cacheLog("abandonig cache search for %s", string); +cacheLog("abandoning cache search for %s", string); return NULL; } -struct trackDb *trackDbCache(char *db, time_t time) +struct trackDb *trackDbCache(char *db, time_t time, char *trackDbCacheDir) /* Check to see if this db has a cached trackDb. */ { cacheLog("checking for cache for db %s at time %ld", db, time); -return checkCache(db, time); +return checkCache(db, time, trackDbCacheDir); } -struct trackDb *trackDbHubCache(char *trackDbUrl, time_t time) +struct trackDb *trackDbHubCache(char *trackDbUrl, time_t time, char *trackDbCacheDir) { cacheLog("checking for cache for hub %s at time %ld", trackDbUrl, time); unsigned char hash[SHA_DIGEST_LENGTH]; SHA1((const unsigned char *)trackDbUrl, strlen(trackDbUrl), hash); char newName[(SHA_DIGEST_LENGTH + 1) * 2]; hexBinaryString(hash, SHA_DIGEST_LENGTH, newName, (SHA_DIGEST_LENGTH + 1) * 2); -return checkCache(newName, time); +return checkCache(newName, time, trackDbCacheDir); } -static void cloneTdbListToSharedMem(char *string, struct trackDb *list, unsigned long size) +static void cloneTdbListToSharedMem(char *string, struct trackDb *list, unsigned long size, char *trackDbCacheDir) /* Allocate shared memory and clone trackDb list into it. */ { int oflags=O_RDWR | O_CREAT; char dirName[4096]; -safef(dirName, sizeof dirName, "/dev/shm/trackDbCache/%s", string); +safef(dirName, sizeof dirName, "/dev/shm/%s/%s", trackDbCacheDir, string); if (!isDirectory(dirName)) { cacheLog("making directory %s", dirName); makeDir(dirName); chmod(dirName, 0777); } char sharedMemoryName[4096]; -safef(sharedMemoryName, sizeof sharedMemoryName, "trackDbCache/%s", rTempName(string, "temp", "")); +safef(sharedMemoryName, sizeof sharedMemoryName, "%s/%s", trackDbCacheDir, rTempName(string, "temp", "")); char tempFileName[4096]; safef(tempFileName, sizeof tempFileName, "/dev/shm/%s", sharedMemoryName); int fd = open(tempFileName, oflags, 0666 ); if (fd < 0) { unlink(tempFileName); cacheLog("unable to open shared memory %s errno %d", tempFileName, errno); return; } else { cacheLog("open shared memory %s", tempFileName); } @@ -1831,43 +1837,43 @@ lmCloneTdbList(lm, list, NULL, superHash); unsigned long memUsed = lmUsed(lm) + lmBlockHeaderSize(); cacheLog("cloning tdbList %p used %ld bytes called with %ld", list, memUsed, size); msync((void *)paddress, memUsed, MS_SYNC); ftruncate(fd, memUsed); // for the moment we're not unmapping these so multiple attached hubs will get // different addresses //munmap((void *)paddress, size); //close(fd); char fileName[4096]; -safef(fileName, sizeof fileName, "/dev/shm/trackDbCache/%s/%ld", string, paddress); +safef(fileName, sizeof fileName, "/dev/shm/%s/%s/%ld", trackDbCacheDir, string, paddress); cacheLog("renaming %s to %s", tempFileName, fileName); mustRename(tempFileName, fileName); } -void trackDbCloneTdbListToSharedMem(char *db, struct trackDb *list, unsigned long size) +void trackDbCloneTdbListToSharedMem(char *db, struct trackDb *list, unsigned long size, char *trackDbCacheDir) /* For this native db, allocate shared memory and clone trackDb list into it. */ { cacheLog("cloning memory for db %s %ld", db, size); -cloneTdbListToSharedMem(db, list, size); +cloneTdbListToSharedMem(db, list, size, trackDbCacheDir); } -void trackDbHubCloneTdbListToSharedMem(char *trackDbUrl, struct trackDb *list, unsigned long size) +void trackDbHubCloneTdbListToSharedMem(char *trackDbUrl, struct trackDb *list, unsigned long size, char *trackDbCacheDir) /* For this hub, Allocate shared memory and clone trackDb list into it. */ { if ((*trackDbUrl == '.') || (list == NULL)) // don't cache empty lists or collections return; cacheLog("cloning memory for hub %s %ld", trackDbUrl, size); unsigned char hash[SHA_DIGEST_LENGTH]; SHA1((const unsigned char *)trackDbUrl, strlen(trackDbUrl), hash); char newName[(SHA_DIGEST_LENGTH + 1) * 2]; hexBinaryString(hash, SHA_DIGEST_LENGTH, newName, (SHA_DIGEST_LENGTH + 1) * 2); -cloneTdbListToSharedMem(newName, list, size); +cloneTdbListToSharedMem(newName, list, size, trackDbCacheDir); }