[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH][QEMU] Allow iohandler removal



Allow an iohandler callback to safely remove itself from the iohandler list

Signed-off-by: Ben Guthro <bguthro@xxxxxxxxxxxxxxx>

Signed-off-by: Gary Grebus <ggrebus@xxxxxxxxxxxxxxx>

diff -r 544710158453 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Mon Aug 13 13:59:36 2007 -0400
+++ b/tools/ioemu/vl.c  Mon Aug 13 13:59:36 2007 -0400
@@ -4377,6 +4377,7 @@ void dumb_display_init(DisplayState *ds)
 
 typedef struct IOHandlerRecord {
     int fd;
+    int defunct;
     IOCanRWHandler *fd_read_poll;
     IOHandler *fd_read;
     IOHandler *fd_write;
@@ -4405,8 +4406,7 @@ int qemu_set_fd_handler2(int fd,
             if (ioh == NULL)
                 break;
             if (ioh->fd == fd) {
-                *pioh = ioh->next;
-                qemu_free(ioh);
+                ioh->defunct = 1;  /* Defer removal to the main polling loop */
                 break;
             }
             pioh = &ioh->next;
@@ -4423,6 +4423,7 @@ int qemu_set_fd_handler2(int fd,
         first_io_handler = ioh;
     found:
         ioh->fd = fd;
+        ioh->defunct = 0;
         ioh->fd_read_poll = fd_read_poll;
         ioh->fd_read = fd_read;
         ioh->fd_write = fd_write;
@@ -6189,6 +6190,7 @@ void main_loop_wait(int timeout)
 void main_loop_wait(int timeout)
 {
     IOHandlerRecord *ioh, *ioh_next;
+    IOHandlerRecord **ioh_prvlnk;
     fd_set rfds, wfds, xfds;
     int ret, nfds;
     struct timeval tv;
@@ -6222,7 +6224,19 @@ void main_loop_wait(int timeout)
     FD_ZERO(&rfds);
     FD_ZERO(&wfds);
     FD_ZERO(&xfds);
-    for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
+    ioh_prvlnk = &first_io_handler;
+
+    for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {
+
+        ioh_next = ioh->next;
+
+        if (ioh->defunct) {
+            *ioh_prvlnk = ioh->next;
+            ioh->next = NULL;
+            qemu_free(ioh);
+            continue;
+        }
+
         if (ioh->fd_read &&
             (!ioh->fd_read_poll ||
              ioh->fd_read_poll(ioh->opaque) != 0)) {
@@ -6235,6 +6249,8 @@ void main_loop_wait(int timeout)
             if (ioh->fd > nfds)
                 nfds = ioh->fd;
         }
+
+        ioh_prvlnk = &ioh->next;
     }
     
     tv.tv_sec = 0;
@@ -6250,13 +6266,12 @@ void main_loop_wait(int timeout)
 #endif
     ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
     if (ret > 0) {
-        /* XXX: better handling of removal */
         for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {
             ioh_next = ioh->next;
-            if (ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
+            if (!ioh->defunct && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
                 ioh->fd_read(ioh->opaque);
             }
-            if (ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
+            if (!ioh->defunct && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
                 ioh->fd_write(ioh->opaque);
             }
         }
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.