87e42c2812e7a93ff6c52ae5148505373d7e0c6d
galt
  Wed Aug 30 15:15:14 2017 -0700
Added advisory lock to cdwMakeFileTags so two users cannot run it at exactly the same time.  If somebody else is running it, it aborts with a message explaining the conflict.  Multiple users should not be running this at the same time, or it can corrupt the cdwFileTags table build.

diff --git src/hg/lib/jksql.c src/hg/lib/jksql.c
index a0f1017..592c773 100644
--- src/hg/lib/jksql.c
+++ src/hg/lib/jksql.c
@@ -1521,53 +1521,89 @@
 }
 
 void sqlCopyTable(struct sqlConnection *sc, char *table1, char *table2)
 /* Copy table1 to table2 */
 {
 char query[256];
 
 if (table1 == NULL || table2 == NULL)
     return;
 sqlSafef(query, sizeof(query), "create table %s like %s", table2, table1);
 sqlUpdate(sc, query);
 sqlSafef(query, sizeof(query), "insert into %s select * from  %s", table2, table1);
 sqlUpdate(sc, query);
 }
 
-void sqlGetLock(struct sqlConnection *sc, char *name)
-/* Sets an advisory lock on the process for 1000s returns 1 if successful,*/
-/* 0 if name already locked or NULL if error occurred */
-/* blocks another client from obtaining a lock with the same name */
+void sqlGetLockWithTimeout(struct sqlConnection *sc, char *name, int wait)
+/* Tries to get an advisory lock on the process, waiting for wait seconds. */
+/* Blocks another client from obtaining a lock with the same name. */
 {
 char query[256];
 struct sqlResult *res;
 char **row = NULL;
 
-sqlSafef(query, sizeof(query), "select get_lock('%s', 1000)", name);
+sqlSafef(query, sizeof(query), "select get_lock('%s', %d)", name, wait);
 res = sqlGetResult(sc, query);
 while ((row=sqlNextRow(res)))
     {
-    if (sameWord(*row, "1"))
+    if (sameWord(*row, "1")) // success
         break;
-    else if (sameWord(*row, "0"))
+    else if (sameWord(*row, "0"))  // timed out
         errAbort("Attempt to GET_LOCK timed out.\nAnother client may have locked this name, %s\n.", name);
-    else if (*row == NULL)
+    else if (*row == NULL) // other error
+        errAbort("Attempt to GET_LOCK of name, %s, caused an error\n", name);
+    }
+sqlFreeResult(&res);
+}
+
+void sqlGetLock(struct sqlConnection *sc, char *name)
+/* Gets an advisory lock created by GET_LOCK in sqlGetLock. Waits up to 1000 seconds. */
+{
+sqlGetLockWithTimeout(sc, name, 1000);
+}
+
+boolean sqlIsLocked(struct sqlConnection *sc, char *name)
+/* Tests if an advisory lock on the given name has been set. 
+ * Returns true if lock has been set, otherwise returns false. */
+{
+char query[256];
+struct sqlResult *res;
+char **row = NULL;
+boolean result = FALSE;
+
+sqlSafef(query, sizeof(query), "select is_free_lock('%s')", name);
+res = sqlGetResult(sc, query);
+while ((row=sqlNextRow(res)))
+    {
+    if (sameWord(*row, "1")) // lock is free (not locked)
+	{
+	result = FALSE;
+        break;
+	}
+    else if (sameWord(*row, "0"))  // lock is not free (locked)
+	{
+	result = TRUE;
+        break;
+	}
+    else if (*row == NULL) // other error
         errAbort("Attempt to GET_LOCK of name, %s, caused an error\n", name);
     }
 sqlFreeResult(&res);
+return result;
 }
 
+
 void sqlReleaseLock(struct sqlConnection *sc, char *name)
 /* Releases an advisory lock created by GET_LOCK in sqlGetLock */
 {
 char query[256];
 
 sqlSafef(query, sizeof(query), "select release_lock('%s')", name);
 sqlUpdate(sc, query);
 }
 
 void sqlHardUnlockAll(struct sqlConnection *sc)
 /* Unlock any hard locked tables. */
 {
 if (sc->hasHardLock)
     {
     char query[32];