]> code.delx.au - pulseaudio/commitdiff
iochannel: Avoid unnecessary wakeup after successful write
authorDavid Henningsson <david.henningsson@canonical.com>
Thu, 13 Jun 2013 12:26:09 +0000 (14:26 +0200)
committerTanu Kaskinen <tanu.kaskinen@linux.intel.com>
Fri, 14 Jun 2013 10:45:57 +0000 (13:45 +0300)
To save some CPU (in low latency scenarios), don't re-enable the
"writable" event after it has succeeded. It is very likely the next
write will succeed right away too.

This means that we always need to handle EAGAIN/EWOULDBLOCK as a
successful write of 0 bytes, so I also verified that all callers to
pa_iochannel_write handled this correctly.

Signed-off-by: David Henningsson <david.henningsson@canonical.com>
src/modules/module-esound-sink.c
src/pulsecore/iochannel.c
src/pulsecore/ioline.c
src/pulsecore/protocol-esound.c
src/pulsecore/protocol-http.c
src/pulsecore/protocol-simple.c

index 40ef5bc1dcfc5653815e2d22c5b8138b2dba3788..9cb7a717ffb6b89197d5af1bf357b8ab3ed4e37b 100644 (file)
@@ -345,7 +345,7 @@ static int do_write(struct userdata *u) {
     if (u->write_data) {
         pa_assert(u->write_index < u->write_length);
 
-        if ((r = pa_iochannel_write(u->io, (uint8_t*) u->write_data + u->write_index, u->write_length - u->write_index)) <= 0) {
+        if ((r = pa_iochannel_write(u->io, (uint8_t*) u->write_data + u->write_index, u->write_length - u->write_index)) < 0) {
             pa_log("write() failed: %s", pa_cstrerror(errno));
             return -1;
         }
index fa3d767708e1dbc7179b81018256fb4e391ccb14..ed8be239d0d6ce908b509c8b3171c181fb575031 100644 (file)
@@ -223,11 +223,22 @@ ssize_t pa_iochannel_write(pa_iochannel*io, const void*data, size_t l) {
     pa_assert(l);
     pa_assert(io->ofd >= 0);
 
-    if ((r = pa_write(io->ofd, data, l, &io->ofd_type)) >= 0) {
-        io->writable = io->hungup = FALSE;
-        enable_events(io);
+    r = pa_write(io->ofd, data, l, &io->ofd_type);
+
+    if ((size_t) r == l)
+        return r; /* Fast path - we almost always successfully write everything */
+
+    if (r < 0) {
+        if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
+            r = 0;
+        else
+            return r;
     }
 
+    /* Partial write - let's get a notification when we can write more */
+    io->writable = io->hungup = FALSE;
+    enable_events(io);
+
     return r;
 }
 
index a18188df3cb04eb3b823c28adce96aca17672346..a5572e9f752939d5da9f98d183476bd620332875 100644 (file)
@@ -351,12 +351,9 @@ static int do_write(pa_ioline *l) {
 
     while (l->io && !l->dead && pa_iochannel_is_writable(l->io) && l->wbuf_valid_length > 0) {
 
-        if ((r = pa_iochannel_write(l->io, l->wbuf+l->wbuf_index, l->wbuf_valid_length)) <= 0) {
+        if ((r = pa_iochannel_write(l->io, l->wbuf+l->wbuf_index, l->wbuf_valid_length)) < 0) {
 
-            if (r < 0 && errno == EAGAIN)
-                break;
-
-            if (r < 0 && errno != EPIPE)
+            if (errno != EPIPE)
                 pa_log("write(): %s", pa_cstrerror(errno));
 
             failure(l, FALSE);
index 52aa2c507934317998b90af01431e7fd4223985c..ff4afc6df7d4709a575c486a05c8b55e62917b97 100644 (file)
@@ -1226,10 +1226,6 @@ static int do_write(connection *c) {
         pa_memblock_unref(chunk.memblock);
 
         if (r < 0) {
-
-            if (r < 0 && (errno == EINTR || errno == EAGAIN))
-                return 0;
-
             pa_log("write(): %s", pa_cstrerror(errno));
             return -1;
         }
index 400150fb407158eb706a85c93d768c63b76bc756..52571d3bb80de104d3f4ed7cb639e6aee8c65f8c 100644 (file)
@@ -162,10 +162,6 @@ static int do_write(struct connection *c) {
     pa_memblock_unref(chunk.memblock);
 
     if (r < 0) {
-
-        if (errno == EINTR || errno == EAGAIN)
-            return 0;
-
         pa_log("write(): %s", pa_cstrerror(errno));
         return -1;
     }
index 9242e68d863ff403be20ec85b132cb5886be5423..0e7c6e0a7246c23d7d3dde8017eb872d6b40665c 100644 (file)
@@ -229,10 +229,6 @@ static int do_write(connection *c) {
     pa_memblock_unref(chunk.memblock);
 
     if (r < 0) {
-
-        if (errno == EINTR || errno == EAGAIN)
-            return 0;
-
         pa_log("write(): %s", pa_cstrerror(errno));
         return -1;
     }