rio: enforce flush reply ordering for all xfids

flushing isnt optional for concurrently handled requests.
we need to ensure that Rflush is replied *after* the
origianl request.

so we assign the flushtag for *every* xfid in xfidctl(),
and filsysrespond() checks if the xfid was flushed
*after* replying and wakes up the flushing xfid.
This commit is contained in:
cinap_lenrek 2013-11-01 21:21:24 +01:00
parent 413977c19b
commit f37ee95fbc
2 changed files with 9 additions and 11 deletions

View file

@ -270,6 +270,8 @@ filsysrespond(Filsys *fs, Xfid *x, Fcall *t, char *err)
free(x->buf); free(x->buf);
x->buf = nil; x->buf = nil;
x->flushtag = -1; x->flushtag = -1;
if(x->flushing)
recv(x->flushc, nil); /* wakeup flushing xfid */
return x; return x;
} }

View file

@ -80,6 +80,8 @@ xfidallocthread(void*)
fprint(2, "%p decref %ld\n", x, x->ref); fprint(2, "%p decref %ld\n", x, x->ref);
error("decref"); error("decref");
} }
if(x->flushing)
error("flushing in free");
if(x->flushtag != -1) if(x->flushtag != -1)
error("flushtag in free"); error("flushtag in free");
x->free = xfidfree; x->free = xfidfree;
@ -110,6 +112,7 @@ xfidctl(void *arg)
threadsetname(buf); threadsetname(buf);
for(;;){ for(;;){
f = recvp(x->c); f = recvp(x->c);
x->flushtag = x->tag;
(*f)(x); (*f)(x);
if(decref(x) == 0) if(decref(x) == 0)
sendp(cxfidfree, x); sendp(cxfidfree, x);
@ -127,12 +130,13 @@ xfidflush(Xfid *x)
incref(xf); /* to hold data structures up at tail of synchronization */ incref(xf); /* to hold data structures up at tail of synchronization */
if(xf->ref == 1) if(xf->ref == 1)
error("ref 1 in flush"); error("ref 1 in flush");
/* take over flushtag so follow up flushes wait for us */
x->flushtag = x->oldtag;
xf->flushtag = -1; xf->flushtag = -1;
break; break;
} }
/* take over flushtag so follow up flushes wait for us */
x->flushtag = x->oldtag;
/* /*
* wakeup filsysflush() in the filsysproc so the next * wakeup filsysflush() in the filsysproc so the next
* flush can come in. * flush can come in.
@ -257,7 +261,7 @@ xfidopen(Xfid *x)
w->ctlopen = TRUE; w->ctlopen = TRUE;
break; break;
case Qkbdin: case Qkbdin:
if(w != wkeyboard){ if(w != wkeyboard){
filsysrespond(x->fs, x, &t, Eperm); filsysrespond(x->fs, x, &t, Eperm);
return; return;
} }
@ -417,7 +421,6 @@ xfidwrite(Xfid *x)
memmove(x->f->rpart, x->data+nb, cnt-nb); memmove(x->f->rpart, x->data+nb, cnt-nb);
x->f->nrpart = cnt-nb; x->f->nrpart = cnt-nb;
} }
x->flushtag = x->tag;
alts[CWdata].c = w->conswrite; alts[CWdata].c = w->conswrite;
alts[CWdata].v = &cwm; alts[CWdata].v = &cwm;
@ -658,8 +661,6 @@ xfidread(Xfid *x)
cnt = x->count; cnt = x->count;
switch(qid){ switch(qid){
case Qcons: case Qcons:
x->flushtag = x->tag;
alts[CRdata].c = w->consread; alts[CRdata].c = w->consread;
alts[CRdata].v = &crm; alts[CRdata].v = &crm;
alts[CRdata].op = CHANRCV; alts[CRdata].op = CHANRCV;
@ -725,8 +726,6 @@ xfidread(Xfid *x)
break; break;
case Qmouse: case Qmouse:
x->flushtag = x->tag;
alts[MRdata].c = w->mouseread; alts[MRdata].c = w->mouseread;
alts[MRdata].v = &mrm; alts[MRdata].v = &mrm;
alts[MRdata].op = CHANRCV; alts[MRdata].op = CHANRCV;
@ -778,8 +777,6 @@ xfidread(Xfid *x)
break; break;
case Qkbd: case Qkbd:
x->flushtag = x->tag;
alts[MRdata].c = w->kbdread; alts[MRdata].c = w->kbdread;
alts[MRdata].v = &krm; alts[MRdata].v = &krm;
alts[MRdata].op = CHANRCV; alts[MRdata].op = CHANRCV;
@ -919,7 +916,6 @@ xfidread(Xfid *x)
filsysrespond(x->fs, x, &fc, Etooshort); filsysrespond(x->fs, x, &fc, Etooshort);
break; break;
} }
x->flushtag = x->tag;
alts[WCRdata].c = w->wctlread; alts[WCRdata].c = w->wctlread;
alts[WCRdata].v = &cwrm; alts[WCRdata].v = &cwrm;