mirror of https://github.com/xemu-project/xemu.git
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
This commit is contained in:
parent
9542611a66
commit
cafffd4024
28
vl.c
28
vl.c
|
@ -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,
|
||||||
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,
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
#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)
|
||||||
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) {
|
||||||
|
|
Loading…
Reference in New Issue