c50d1616fc9f52b6cdb9f109865d4f7044e96a0f angie Thu Dec 8 23:45:40 2011 -0800 Feature #2823 (VCF+tabix track handler): found & fixed more non-reentrant code that can lead to race conditions when multiple VCF tracks are loaded in parallel. More than 1000 tries have been successful compared to 5 or 6 failures per 1000 tries before. diff --git src/hg/lib/pgSnp.c src/hg/lib/pgSnp.c index 1283a52..815bdd9 100644 --- src/hg/lib/pgSnp.c +++ src/hg/lib/pgSnp.c @@ -688,36 +688,31 @@ lineFileAbort(lf, "invalid allele frequency, %s with count of %d", row[5], item->alleleCount); /* scores, comma separated list of numbers with above # of items */ item->alleleScores = cloneString(row[6]); safef(pattern, sizeof(pattern), "^[0-9.]+(,[0-9.]+){%d}$", item->alleleCount - 1); if (! regexMatchNoCase(row[6], pattern)) lineFileAbort(lf, "invalid allele scores, %s with count of %d", row[6], item->alleleCount); return item; } #define VCF_MAX_ALLELE_LEN 80 static char *alleleCountsFromVcfRecord(struct vcfRecord *rec, int alDescCount) /* Build up comma-sep list of per-allele counts, if available, up to alDescCount * which may be less than rec->alleleCount: */ { -static struct dyString *dy = NULL; -if (dy == NULL) - dy = dyStringNew(0); -else - dyStringClear(dy); -dyStringClear(dy); +struct dyString *dy = dyStringNew(0); int alCounts[VCF_MAX_ALLELE_LEN]; boolean gotTotalCount = FALSE, gotAltCounts = FALSE; int i; for (i = 0; i < rec->infoCount; i++) if (sameString(rec->infoElements[i].key, "AN")) { gotTotalCount = TRUE; // Set ref allele to total count, subtract alt counts below. alCounts[0] = rec->infoElements[i].values[0].datInt; break; } for (i = 0; i < rec->infoCount; i++) if (sameString(rec->infoElements[i].key, "AC")) { if (rec->infoElements[i].count > 0) @@ -753,31 +748,31 @@ for (i = 0; i < alDescCount; i++) alCounts[i] = 0; for (i = 0; i < rec->file->genotypeCount; i++) { struct vcfGenotype *gt = &(rec->genotypes[i]); if (gt == NULL) uglyf("i=%d gt=NULL wtf?\n", i); alCounts[gt->hapIxA]++; if (! gt->isHaploid) alCounts[gt->hapIxB]++; } dyStringPrintf(dy, "%d", alCounts[0]); for (i = 1; i < alDescCount; i++) dyStringPrintf(dy, ",%d", alCounts[i]); } -return cloneStringZ(dy->string, dy->stringSize+1); +return dyStringCannibalize(&dy); } struct pgSnp *pgSnpFromVcfRecord(struct vcfRecord *rec) /* Convert VCF rec to pgSnp; don't free rec->file (vcfFile) until * you're done with pgSnp because pgSnp points to rec->chrom. */ { struct dyString *dy = dyStringNew(0); struct pgSnp *pgs; AllocVar(pgs); pgs->chrom = rec->chrom; pgs->chromStart = rec->chromStart; pgs->chromEnd = rec->chromEnd; // Build up slash-separated allele string from rec->alleles, starting with ref allele: dyStringAppend(dy, rec->alleles[0]); int alCount = rec->alleleCount, i;