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
|