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];