/* * save away a lump, and return it's score. * doesn't store duplicates, but checks that the data is really the same. */ int writelump(Packet *p, u8int *score, int type, u32int creator, uint ms) { Lump *u; int ok; /* qlock(&stats.lock); stats.lumpwrites++; qunlock(&stats.lock); */ packetsha1(p, score); if(packetsize(p) == 0 || writestodevnull==1){ packetfree(p); return 0; } u = lookuplump(score, type); if(u->data != nil){ ok = 0; if(packetcmp(p, u->data) != 0){ uchar nscore[VtScoreSize]; packetsha1(u->data, nscore); if(scorecmp(u->score, score) != 0) seterr(EStrange, "lookuplump returned bad score %V not %V", u->score, score); else if(scorecmp(u->score, nscore) != 0) seterr(EStrange, "lookuplump returned bad data %V not %V", nscore, u->score); else seterr(EStrange, "score collision %V", score); ok = -1; } packetfree(p); putlump(u); return ok; } if(writestodevnull==2){ packetfree(p); return 0; } if(queuewrites) return queuewrite(u, p, creator, ms); ok = writeqlump(u, p, creator, ms); putlump(u); return ok; }
static void queueproc(void *vq) { LumpQueue *q; Lump *u; Packet *p; int creator; uint ms; threadsetname("queueproc"); q = vq; for(;;){ qlock(&q->lock); while(q->w == q->r){ trace(TraceProc, "queueproc sleep empty"); rsleep(&q->empty); } u = q->q[q->r].u; p = q->q[q->r].p; creator = q->q[q->r].creator; ms = q->q[q->r].ms; q->r = (q->r + 1) & (MaxLumpQ - 1); trace(TraceProc, "queueproc wakeup flush"); rwakeupall(&q->flush); trace(TraceProc, "queueproc wakeup full"); rwakeup(&q->full); qunlock(&q->lock); trace(TraceProc, "queueproc writelump %V", u->score); if(writeqlump(u, p, creator, ms) < 0) fprint(2, "failed to write lump for %V: %r", u->score); trace(TraceProc, "queueproc wrotelump %V", u->score); putlump(u); } }