Commit cafffd40 authored by ths's avatar ths
Browse files

Make removing IOHandlers safe from within an IOHandler, by Anthony Liguori.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2461 c046a42c-6fe2-441c-8c8c-71466251a162
parent 9542611a
...@@ -4462,6 +4462,7 @@ typedef struct IOHandlerRecord { ...@@ -4462,6 +4462,7 @@ typedef struct IOHandlerRecord {
IOCanRWHandler *fd_read_poll; IOCanRWHandler *fd_read_poll;
IOHandler *fd_read; IOHandler *fd_read;
IOHandler *fd_write; IOHandler *fd_write;
int deleted;
void *opaque; void *opaque;
/* temporary data */ /* temporary data */
struct pollfd *ufd; struct pollfd *ufd;
...@@ -4487,8 +4488,7 @@ int qemu_set_fd_handler2(int fd, ...@@ -4487,8 +4488,7 @@ int qemu_set_fd_handler2(int fd,
if (ioh == NULL) if (ioh == NULL)
break; break;
if (ioh->fd == fd) { if (ioh->fd == fd) {
*pioh = ioh->next; ioh->deleted = 1;
qemu_free(ioh);
break; break;
} }
pioh = &ioh->next; pioh = &ioh->next;
...@@ -4509,6 +4509,7 @@ int qemu_set_fd_handler2(int fd, ...@@ -4509,6 +4509,7 @@ int qemu_set_fd_handler2(int fd,
ioh->fd_read = fd_read; ioh->fd_read = fd_read;
ioh->fd_write = fd_write; ioh->fd_write = fd_write;
ioh->opaque = opaque; ioh->opaque = opaque;
ioh->deleted = 0;
} }
return 0; return 0;
} }
...@@ -6157,7 +6158,7 @@ void qemu_system_powerdown_request(void) ...@@ -6157,7 +6158,7 @@ void qemu_system_powerdown_request(void)
void main_loop_wait(int timeout) void main_loop_wait(int timeout)
{ {
IOHandlerRecord *ioh, *ioh_next; IOHandlerRecord *ioh;
fd_set rfds, wfds, xfds; fd_set rfds, wfds, xfds;
int ret, nfds; int ret, nfds;
struct timeval tv; struct timeval tv;
...@@ -6192,6 +6193,8 @@ void main_loop_wait(int timeout) ...@@ -6192,6 +6193,8 @@ void main_loop_wait(int timeout)
FD_ZERO(&wfds); FD_ZERO(&wfds);
FD_ZERO(&xfds); FD_ZERO(&xfds);
for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) { for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
if (ioh->deleted)
continue;
if (ioh->fd_read && if (ioh->fd_read &&
(!ioh->fd_read_poll || (!ioh->fd_read_poll ||
ioh->fd_read_poll(ioh->opaque) != 0)) { ioh->fd_read_poll(ioh->opaque) != 0)) {
...@@ -6219,9 +6222,11 @@ void main_loop_wait(int timeout) ...@@ -6219,9 +6222,11 @@ void main_loop_wait(int timeout)
#endif #endif
ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv); ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
if (ret > 0) { if (ret > 0) {
/* XXX: better handling of removal */ IOHandlerRecord **pioh;
for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {
ioh_next = ioh->next; for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
if (ioh->deleted)
continue;
if (FD_ISSET(ioh->fd, &rfds)) { if (FD_ISSET(ioh->fd, &rfds)) {
ioh->fd_read(ioh->opaque); ioh->fd_read(ioh->opaque);
} }
...@@ -6229,6 +6234,17 @@ void main_loop_wait(int timeout) ...@@ -6229,6 +6234,17 @@ void main_loop_wait(int timeout)
ioh->fd_write(ioh->opaque); ioh->fd_write(ioh->opaque);
} }
} }
/* remove deleted IO handlers */
pioh = &first_io_handler;
while (*pioh) {
ioh = *pioh;
if (ioh->deleted) {
*pioh = ioh->next;
qemu_free(ioh);
} else
pioh = &ioh->next;
}
} }
#if defined(CONFIG_SLIRP) #if defined(CONFIG_SLIRP)
if (slirp_inited) { if (slirp_inited) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment