summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2011-01-12 12:14:49 +0000
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2011-01-21 15:01:37 +0000
commit460e6282d68a928a78f16031ed1637bc7676e10e (patch)
tree61214b7e3776473d6730cacac061d16f210aa1aa
parentf3ed53a30f77cc0c87cf469857263bb9682acd9a (diff)
_dbus_loop_iterate: if the kernel says a fd is bad, stop watching it
Again, this shouldn't happen - modules are responsible for cleaning up their watches - but the failure mode here is really bad: if we leave an invalid fd in the set, every poll() call will instantly return, marking it as POLLNVAL. The result is that dbus-daemon busy-loops on poll() without responding to I/O, so the bad watch will probably never be cleared up. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=32992 Bug-NB: NB#200248 Reviewed-by: Colin Walters <walters@verbum.org>
-rw-r--r--dbus/dbus-mainloop.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/dbus/dbus-mainloop.c b/dbus/dbus-mainloop.c
index c3751382..43159a70 100644
--- a/dbus/dbus-mainloop.c
+++ b/dbus/dbus-mainloop.c
@@ -829,6 +829,15 @@ _dbus_loop_iterate (DBusLoop *loop,
retval = TRUE;
}
+
+ if (_DBUS_UNLIKELY (fds[i].revents & _DBUS_POLLNVAL))
+ {
+ _dbus_warn ("invalid request, socket fd %d not open\n",
+ fds[i].fd);
+ _dbus_watch_invalidate (wcb->watch);
+ _dbus_loop_remove_watch (loop, wcb->watch, wcb->function,
+ ((Callback *)wcb)->data);
+ }
}
++i;