[Click] [PATCH] usermode Router::run_selects() not robust under
handler deletion
Eddie Kohler
kohler at icir.org
Fri Oct 31 15:08:57 EST 2003
Peter,
Thanks so much for this fix!! It's ridiculous: we knew this could happen,
at least when this comment got written:
// Beware: calling 'selected()' might call remove_select(), causing
// disaster! Load everything we need out of the vectors before calling
// out.
Duh.
I've attached the patch I checked in. Note the different fix for your third
problem:
> I dropped the optimization in the 3rd fragment, in which self-deletion of
> handlers causes a re-scan of the new occupant of the slot. Nice trick,
> but it was also vulnerable to vector realloc problems if one of the handlers
> called add_select().
> The next poll() will catch the moved handler anyway.
I'm not sure I really understood the problem -- why not just fix up the 'p'
pointer, as attached?
Eddie
Index: lib/router.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/lib/router.cc,v
retrieving revision 1.149
diff -u -w -r1.149 router.cc
--- lib/router.cc 14 Oct 2003 18:47:03 -0000 1.149
+++ lib/router.cc 31 Oct 2003 23:03:47 -0000
@@ -1444,6 +1444,11 @@
if (!p->events) {
*p = _pollfds.back();
_pollfds.pop_back();
+ // 31.Oct.2003 - Peter Swain: keep fds and elements in sync
+ _write_poll_elements[pi] = _write_poll_elements.back();
+ _write_poll_elements.pop_back();
+ _read_poll_elements[pi] = _read_poll_elements.back();
+ _read_poll_elements.pop_back();
#if !HAVE_POLL_H
if (!_pollfds.size())
_max_select_fd = -1;
@@ -1519,6 +1524,8 @@
if (write_elt >= 0 && write_elt != read_elt)
_elements[write_elt]->selected(fd);
+ // 31.Oct.2003 - Peter Swain: _pollfds may have grown or shrunk!
+ p = _pollfds.begin() + pi;
if (p < _pollfds.end() && fd != p->fd)
p--;
}
@@ -1550,6 +1557,8 @@
if (write_elt >= 0 && write_elt != read_elt)
_elements[write_elt]->selected(fd);
+ // 31.Oct.2003 - Peter Swain: _pollfds may have grown or shrunk!
+ p = _pollfds.begin() + pi;
if (p < _pollfds.end() && fd != p->fd)
p--;
}
More information about the click
mailing list