Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/fifofs/fifo_vnops.c
Show First 20 Lines • Show All 168 Lines • ▼ Show 20 Lines | fifo_open(ap) | ||||
* and still avoiding missed wakeups. | * and still avoiding missed wakeups. | ||||
*/ | */ | ||||
PIPE_LOCK(fpipe); | PIPE_LOCK(fpipe); | ||||
if (ap->a_mode & FREAD) { | if (ap->a_mode & FREAD) { | ||||
fip->fi_readers++; | fip->fi_readers++; | ||||
fip->fi_rgen++; | fip->fi_rgen++; | ||||
if (fip->fi_readers == 1) { | if (fip->fi_readers == 1) { | ||||
fpipe->pipe_state &= ~PIPE_EOF; | fpipe->pipe_state &= ~PIPE_EOF; | ||||
if (fip->fi_writers > 0) | if (fip->fi_writers > 0) { | ||||
wakeup(&fip->fi_writers); | wakeup(&fip->fi_writers); | ||||
pipeselwakeup(fpipe); | |||||
markj: One side effect of calling pipeselwakeup() is that SIGIO will be sent if the application… | |||||
jan.kokemueller_gmail.comAuthorUnsubmitted Done Inline ActionsI must admit that I haven't tested with SIGIO at all... In the old socket based FIFO implementation there was a "sowwakeup" call here (which sends a SIGIO I think). I don't know why it was removed. Do you know if programs that use SIGIO are supposed to deal with those kinds of spurious signals? I would guess so, but I'm not super familiar with this programming model. jan.kokemueller_gmail.com: I must admit that I haven't tested with SIGIO at all... In the old socket based FIFO… | |||||
} | } | ||||
} | |||||
fp->f_pipegen = fpipe->pipe_wgen - fip->fi_writers; | fp->f_pipegen = fpipe->pipe_wgen - fip->fi_writers; | ||||
} | } | ||||
if (ap->a_mode & FWRITE) { | if (ap->a_mode & FWRITE) { | ||||
if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0) { | if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0) { | ||||
PIPE_UNLOCK(fpipe); | PIPE_UNLOCK(fpipe); | ||||
if (fip->fi_writers == 0) | if (fip->fi_writers == 0) | ||||
fifo_cleanup(vp); | fifo_cleanup(vp); | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
fip->fi_writers++; | fip->fi_writers++; | ||||
fip->fi_wgen++; | fip->fi_wgen++; | ||||
if (fip->fi_writers == 1) { | if (fip->fi_writers == 1) { | ||||
fpipe->pipe_state &= ~PIPE_EOF; | fpipe->pipe_state &= ~PIPE_EOF; | ||||
if (fip->fi_readers > 0) | if (fip->fi_readers > 0) { | ||||
wakeup(&fip->fi_readers); | wakeup(&fip->fi_readers); | ||||
pipeselwakeup(fpipe); | |||||
} | } | ||||
} | } | ||||
} | |||||
if ((ap->a_mode & O_NONBLOCK) == 0) { | if ((ap->a_mode & O_NONBLOCK) == 0) { | ||||
if ((ap->a_mode & FREAD) && fip->fi_writers == 0) { | if ((ap->a_mode & FREAD) && fip->fi_writers == 0) { | ||||
gen = fip->fi_wgen; | gen = fip->fi_wgen; | ||||
VOP_UNLOCK(vp); | VOP_UNLOCK(vp); | ||||
stops_deferred = sigdeferstop(SIGDEFERSTOP_OFF); | stops_deferred = sigdeferstop(SIGDEFERSTOP_OFF); | ||||
error = msleep(&fip->fi_readers, PIPE_MTX(fpipe), | error = msleep(&fip->fi_readers, PIPE_MTX(fpipe), | ||||
PDROP | PCATCH | PSOCK, "fifoor", 0); | PDROP | PCATCH | PSOCK, "fifoor", 0); | ||||
sigallowstop(stops_deferred); | sigallowstop(stops_deferred); | ||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); | vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); | ||||
if (error != 0 && gen == fip->fi_wgen) { | if (error != 0 && gen == fip->fi_wgen) { | ||||
fip->fi_readers--; | fip->fi_readers--; | ||||
if (fip->fi_readers == 0) { | if (fip->fi_readers == 0) { | ||||
PIPE_LOCK(fpipe); | PIPE_LOCK(fpipe); | ||||
fpipe->pipe_state |= PIPE_EOF; | fpipe->pipe_state |= PIPE_EOF; | ||||
if (fpipe->pipe_state & PIPE_WANTW) | if (fpipe->pipe_state & PIPE_WANTW) | ||||
wakeup(fpipe); | wakeup(fpipe); | ||||
pipeselwakeup(fpipe); | |||||
PIPE_UNLOCK(fpipe); | PIPE_UNLOCK(fpipe); | ||||
fifo_cleanup(vp); | fifo_cleanup(vp); | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
PIPE_LOCK(fpipe); | PIPE_LOCK(fpipe); | ||||
/* | /* | ||||
* We must have got woken up because we had a writer. | * We must have got woken up because we had a writer. | ||||
Show All 12 Lines | if ((ap->a_mode & FWRITE) && fip->fi_readers == 0) { | ||||
if (error != 0 && gen == fip->fi_rgen) { | if (error != 0 && gen == fip->fi_rgen) { | ||||
fip->fi_writers--; | fip->fi_writers--; | ||||
if (fip->fi_writers == 0) { | if (fip->fi_writers == 0) { | ||||
PIPE_LOCK(fpipe); | PIPE_LOCK(fpipe); | ||||
fpipe->pipe_state |= PIPE_EOF; | fpipe->pipe_state |= PIPE_EOF; | ||||
if (fpipe->pipe_state & PIPE_WANTR) | if (fpipe->pipe_state & PIPE_WANTR) | ||||
wakeup(fpipe); | wakeup(fpipe); | ||||
fpipe->pipe_wgen++; | fpipe->pipe_wgen++; | ||||
pipeselwakeup(fpipe); | |||||
PIPE_UNLOCK(fpipe); | PIPE_UNLOCK(fpipe); | ||||
fifo_cleanup(vp); | fifo_cleanup(vp); | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* We must have got woken up because we had | * We must have got woken up because we had | ||||
* a reader. That (and not still having one) | * a reader. That (and not still having one) | ||||
▲ Show 20 Lines • Show All 115 Lines • Show Last 20 Lines |
One side effect of calling pipeselwakeup() is that SIGIO will be sent if the application requested it, but in these cases there is no I/O to be done. I'm not sure if this is really worth handling given that we also call pipeselwakeup() in pipe_close().