[Spice-devel] [PATCH 4/5] server: introduce dispatcher

Alon Levy alevy at redhat.com
Mon Nov 7 01:29:35 PST 2011


On Mon, Nov 07, 2011 at 09:28:34AM +0100, Paolo Bonzini wrote:
> On 11/06/2011 05:49 PM, Alon Levy wrote:
> >+    while (read_size<  size) {
> >+        ret = read(fd, buf + read_size, size - read_size);
> >+        if (ret == -1) {
> >+            if (errno != EINTR) {
> >+                if (errno == EAGAIN&&  !block) {
> >+                    return 0;
> >+                }
> >+                return -1;
> >+            }
> >+            continue;
> >+        }
> >+        if (ret == 0) {
> >+            if (block) {
> >+                red_error("broken pipe on read");
> >+                return -1;
> 
> No, broken pipe on read will return 0 for non-blocking too.
> 
> The if should be removed, and the else branch below should be moved
> to errno == EAGAIN && block.
> 
> That is,
> 
>    if (fd_set_blocking(fd, block) == -1) {
>        return -1;
>    }
>    while (read_size < size) {
>        ret = read(fd, buf + read_size, size - read_size);
>        if (ret == -1) {
>            if (errno == EINTR) {
>                continue;
>            }
>            if (errno == EAGAIN) {
>                if (read_size == 0) {
>                    /* Nothing read so far, return 0.  */
>                    return 0;
>                }
>                if (fd_set_blocking(fd, 1) == -1) {
>                    return -1;
>                }
>                continue;
>            }
>            return -1;
>        }
>        if (ret == 0) {
>            red_error("broken pipe on read");
>            errno = ECONNRESET; /* example */

Why would I want to override errno?

>            return -1;
>        }
>        read_size += ret;
> 
> >+/*
> >+ * write_safe
> >+ * @return -1 for error, otherwise number of written bytes. may be zero.
> >+ */
> >+static int write_safe(int fd, void *buf, size_t size)
> >+{
> >+    int write_size = 0;
>            ^^^^^
> 
> Should be "written" (the "read" in read_size is pronounced "red",
> not "reed").
> 
> >+    int ret;
> >+
> >+    while (write_size<  size) {
> >+        ret = write(fd, buf + write_size, size - write_size);
> >+        if (ret == -1) {
> >+            if (errno != EINTR) {
> >+                return -1;
> >+            }
> >+            continue;
> >+        }
> >+        if (ret == 0) {
> >+            red_error("broken pipe on write");
> >+            return -1;
> 
> Broken pipe on write will return EPIPE or raise SIGPIPE (likely the
> former).  You can just remove the if altogether here.
> 
> However, you likely want to handle EAGAIN like in read_safe.
> Perhaps you need a block argument to write_safe as well.  If not,
> O_NONBLOCK applies to both read and write, so you should set it to a
> known invariant value---either at the end of read_safe, or at the
> beginning of write_safe.
> 
> Alternatively, instead of toggling the blocking flag, you can always
> leave it set and use a single poll system call in the !block case.
> If the descriptor is not readable (resp. writeable) you return 0
> immediately.

Taking this advice. Thanks for the multiple choice :)

> 
> Paolo


More information about the Spice-devel mailing list