From 6f6c90d4068c8f3cf044f8f8644e9e23dec70f2b Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 24 Apr 2009 20:10:00 +0200 Subject: [PATCH] Make io_output() return a sane value Return number of bytes written on success, -1 on error. In particular, return zero when nothing was written because the queue was empty, or because the write slept and got woken up, or because the write refused to sleep. Before, it instead returned the number of bytes remaining to be written when empth_select() failed, when woken up from sleep, or refusing to sleep. You couldn't tell from the return value whether the call made progress writing out the queue. The current callers don't actually notice the change. --- src/lib/empthread/io.c | 47 ++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/src/lib/empthread/io.c b/src/lib/empthread/io.c index ca9c3e25..8b47bbc6 100644 --- a/src/lib/empthread/io.c +++ b/src/lib/empthread/io.c @@ -181,53 +181,46 @@ io_outputwaiting(struct iop *iop) return ioq_qsize(iop->output); } +/* + * Write output queued in IOP. + * If WAITFOROUTPUT != IO_NOWAIT, writing may put the thread to sleep. + * Return number of bytes written on success, -1 on error. + * In particular, return zero when nothing was written because the + * queue was empty, or because the write slept and got woken up (only + * if WAITFOROUTPUT != IO_NOWAIT), or because the write refused to + * sleep (only if WAITFOROUTPUT == IO_NOWAIT). + */ int io_output(struct iop *iop, int waitforoutput) { struct iovec iov[16]; - int cc; - int n; - int remain; + int n, res, cc; - /* If there is no output waiting. */ - if (!io_outputwaiting(iop)) + if (!ioq_qsize(iop->output)) return 0; - /* If the iop is not write enabled. */ if ((iop->flags & IO_WRITE) == 0) return -1; - /* If the io is marked as in error... */ if (iop->flags & IO_ERROR) return -1; - /* make the iov point to the data in the queue. */ - /* I.E., each of the elements in the queue. */ - /* returns the number of elements in the iov. */ n = ioq_makeiov(iop->output, iov, IO_BUFSIZE); - if (n <= 0) { - return 0; - } - - /* wait for the file to be output ready. */ if (waitforoutput != IO_NOWAIT) { - /* This waits for the file to be ready for writing, */ - /* and lets other threads run. */ - empth_select(iop->fd, EMPTH_FD_WRITE, NULL); + res = empth_select(iop->fd, EMPTH_FD_WRITE, NULL); + if (res == 0) + return 0; + if (res < 0) { + iop->flags |= IO_ERROR; + return -1; + } } - /* Do the actual write. */ cc = writev(iop->fd, iov, n); - - /* if it failed.... */ if (cc < 0) { - /* Hmm, it would block. file is opened noblock, soooooo.. */ - if (errno == EAGAIN || errno == EWOULDBLOCK) { - /* If there are remaining bytes, set the IO as remaining.. */ - remain = ioq_qsize(iop->output); - return remain; - } + if (errno == EAGAIN || errno == EWOULDBLOCK) + return 0; iop->flags |= IO_ERROR; return -1; }