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