[med-svn] [Git][med-team/ncbi-vdb][master] ncbi-vdb 2.10.9+dfsg-2: cherry-pick fix_2.10.9_refseq_race.patch.

Aaron M. Ucko gitlab at salsa.debian.org
Mon Jan 18 22:04:50 GMT 2021



Aaron M. Ucko pushed to branch master at Debian Med / ncbi-vdb


Commits:
fffde5db by Aaron M. Ucko at 2021-01-18T16:57:55-05:00
ncbi-vdb 2.10.9+dfsg-2: cherry-pick fix_2.10.9_refseq_race.patch.

Fix a new race in asynchronous RefSeq loading code, per upstream
(https://github.com/ncbi/ncbi-vdb) commits 06152a5, cf92dca, and b342af2.

- - - - -


3 changed files:

- debian/changelog
- + debian/patches/fix_2.10.9_refseq_race.patch
- debian/patches/series


Changes:

=====================================
debian/changelog
=====================================
@@ -1,3 +1,11 @@
+ncbi-vdb (2.10.9+dfsg-2) unstable; urgency=medium
+
+  * d/p/fix_2.10.9_refseq_race.patch: Fix a new race in asynchronous
+    RefSeq loading code, per upstream (https://github.com/ncbi/ncbi-vdb) 
+    commits 06152a5, cf92dca, and b342af2.
+
+ -- Aaron M. Ucko <ucko at debian.org>  Mon, 18 Jan 2021 16:57:54 -0500
+
 ncbi-vdb (2.10.9+dfsg-1) unstable; urgency=medium
 
   * New upstream version


=====================================
debian/patches/fix_2.10.9_refseq_race.patch
=====================================
@@ -0,0 +1,165 @@
+Author: Kenneth Durbrow <durbrowk at ncbi.nlm.nih.gov>
+Last-Update: Mon, 18 Jan 2021 14:50:24 -0500
+Description: Fix a new race in asynchronous RefSeq loading code.
+ Merge upstream (https://github.com/ncbi/ncbi-vdb) commits 06152a5,
+ cf92dca, and b342af2.
+
+--- a/libs/axf/refseq.c
++++ b/libs/axf/refseq.c
+@@ -31,6 +31,7 @@
+ #include <vdb/cursor.h>
+ #include <kproc/lock.h>
+ #include <kproc/thread.h>
++#include <klib/refcount.h>
+ #include "refseq.h"
+ 
+ #include <stdlib.h>
+@@ -45,6 +46,7 @@ typedef RefSeq Object;
+ #include "util.h"
+ 
+ struct RefSeqAsyncLoadInfo {
++    KRefcount refcount;
+     KThread *th;
+     KLock *mutex;               /**< mostly guards the cursor against concurrent use */
+     VCursor const *curs;        /**< can be used by either thread after acquiring the mutex */
+@@ -57,16 +59,38 @@ struct RefSeqAsyncLoadInfo {
+     unsigned volatile miss;     /**< ... how effective the bg thread was */
+ };
+ 
++static void RefSeqAsyncLoadInfo_Release(RefSeqAsyncLoadInfo *const self)
++{
++    switch (KRefcountDrop(&self->refcount, "RefSeqAsyncLoadInfo")) {
++    case krefWhack:
++        break;
++    case krefOkay:
++        return;
++    default:
++        assert(!"valid refcount");
++        abort();
++    }
++    VCursorRelease(self->curs);
++    KLockRelease(self->mutex);
++    KThreadRelease(self->th);
++    free(self);
++}
++
+ static rc_t RefSeqAsyncLoadInfoFree(RefSeqAsyncLoadInfo *const self)
+ {
+     rc_t rc = 0;
+     if (self) {
++        /* Synchronize with background thread in preparation for clean up */
++        KRefcountAdd(&self->refcount, "RefSeqAsyncLoadInfo"); // keep alive; let die at line 89
++        LOGMSG(klogDebug, "Foreground thread ending background thread");
+         KLockAcquire(self->mutex);
+         self->count = 0;
+         KLockUnlock(self->mutex);
+         KThreadWait(self->th, &rc);
++        LOGERR(klogDebug, rc, "Background thread ended");
++        RefSeqAsyncLoadInfo_Release(self);
+         if (rc)
+-            LOGERR(klogErr, rc, "async loader thread failed");
++            LOGERR(klogErr, rc, "asynchronous loader thread failed");
+     }
+     return rc;
+ }
+@@ -361,37 +385,37 @@ static rc_t runLoadThread(Object *self)
+         else if (!done && rc == 0)
+             rc = RC(rcXF, rcFunction, rcReading, rcData, rcInvalid);
+     }
+-    if (rc == 0 && i == count) {
+-        if (n != 0) {
+-            while (n < 4) {
+-                accum <<= 2;
+-                ++n;
+-            }
+-            self->bases[j++] = accum;
++    if (n != 0) {
++        while (n < 4) {
++            accum <<= 2;
++            ++n;
+         }
++        self->bases[j++] = accum;
++    }
++    free(buffer);
++    LOGMSG(klogDebug, "Done background loading of reference");
++    if (rc == 0 && i == count) {
+         KLockAcquire(async->mutex);
+         async->loaded = i + first; /* last row was loaded */
+         async->count = 0;
+         KLockUnlock(async->mutex);
+     }
+-    LOGMSG(klogDebug, "Done background loading of reference");
+ 
+     assert((atomic_read(&self->rwl) & 1) == 0); /* there is only one writer */
+     atomic_inc(&self->rwl); /* tell readers we want to update the state */
+     while (atomic_read(&self->rwl) != 1)
+         ;
++    /* readers are all waiting in the loop at line 445 */
+     self->reader = rc == 0 ? readNormal : readZero;
+     self->async = NULL;
+-    atomic_dec(&self->rwl); /* state is updated; readers can continue */
++    atomic_dec(&self->rwl); /* state is updated; readers continue to line 448 */
+     if (rc == 0 && i == count) {
+         double const pct = 100.0 * (async->hits - async->miss) / async->hits;
+ 
+         PLOGMSG(klogDebug, (klogDebug, "Done with background loading of reference; preload was $(pct)%", "pct=%5.1f", (float)pct));
+     }
+-    KLockRelease(async->mutex);
+-    free(buffer);
+-    VCursorRelease(async->curs);
+-    free(async);
++    RefSeqAsyncLoadInfo_Release(async);
++    LOGERR(klogDebug, rc, "Background thread exiting");
+ 
+     return rc;
+ }
+@@ -510,6 +534,7 @@ static RefSeqAsyncLoadInfo *RefSeqAsyncL
+         result->max_seq_len = readU32(&car[2], rr->first, curs, prc);
+         assert(result->max_seq_len % 4 == 0);
+         if (*prc == 0) {
++            KRefcountInit(&result->refcount, 1, "RefSeqAsyncLoadInfo", "init", "");
+             result->curs = curs;
+             VCursorAddRef(curs);
+             result->rr = *rr;
+--- a/libs/axf/restore-read.c
++++ b/libs/axf/restore-read.c
+@@ -325,6 +325,7 @@ static void RestoreReadSharedFree(Restor
+     KRWLockRelease(self->rwl);
+     KRefcountWhack(&self->refcount, "RestoreReadShared");
+     free(self);
++    LOGMSG(klogDebug, "Released shared global RestoreRead data object");
+ }
+ 
+ static void RestoreReadSharedRelease(RestoreReadShared *const self)
+@@ -361,6 +362,31 @@ static RestoreReadShared *getRestoreRead
+     return g_shared.ptr;
+ }
+ 
++unsigned RestoreReadShared_getState(unsigned *refSeqs, unsigned *wgs, unsigned *errors, unsigned *activeRefSeqs)
++{
++    if (g_shared.ptr) {
++        rc_t rc = 0;
++        RestoreReadShared *const ptr = getRestoreReadShared(&rc);
++
++        RestoreReadSharedReader(ptr);
++        *refSeqs = ptr->refSeqs.entries;
++        *wgs = ptr->wgs.entries;
++        *errors = ptr->errors.entries;
++        *activeRefSeqs = 0;
++        {
++            unsigned i;
++            for (i = 0; i < *refSeqs; ++i) {
++                if (ptr->refSeqs.entry[i].object->async != NULL)
++                    ++*activeRefSeqs;
++            }
++        }
++        RestoreReadSharedReaderDone(ptr);
++        RestoreReadSharedRelease(ptr);
++        return 1;
++    }
++    else return 0;
++}
++
+ struct RestoreRead {
+     VDBManager const *mgr;
+     RestoreReadShared *shared;


=====================================
debian/patches/series
=====================================
@@ -14,3 +14,4 @@ i386-uint64_msbit.patch
 fix_path_mbedtls.patch
 redefine_CALL_MBEDTLS.patch
 # fix_parallel_build.patch
+fix_2.10.9_refseq_race.patch



View it on GitLab: https://salsa.debian.org/med-team/ncbi-vdb/-/commit/fffde5db10e63c63ccbcd810892ecd1452b8d1f8

-- 
View it on GitLab: https://salsa.debian.org/med-team/ncbi-vdb/-/commit/fffde5db10e63c63ccbcd810892ecd1452b8d1f8
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20210118/cfa8ca9e/attachment-0001.html>


More information about the debian-med-commit mailing list