Commit cafffd4024b10ac1eae54b74a5a0f372d86eede7
1 parent
9542611a
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
Showing
1 changed file
with
22 additions
and
6 deletions
vl.c
| ... | ... | @@ -4462,6 +4462,7 @@ typedef struct IOHandlerRecord { |
| 4462 | 4462 | IOCanRWHandler *fd_read_poll; |
| 4463 | 4463 | IOHandler *fd_read; |
| 4464 | 4464 | IOHandler *fd_write; |
| 4465 | + int deleted; | |
| 4465 | 4466 | void *opaque; |
| 4466 | 4467 | /* temporary data */ |
| 4467 | 4468 | struct pollfd *ufd; |
| ... | ... | @@ -4487,8 +4488,7 @@ int qemu_set_fd_handler2(int fd, |
| 4487 | 4488 | if (ioh == NULL) |
| 4488 | 4489 | break; |
| 4489 | 4490 | if (ioh->fd == fd) { |
| 4490 | - *pioh = ioh->next; | |
| 4491 | - qemu_free(ioh); | |
| 4491 | + ioh->deleted = 1; | |
| 4492 | 4492 | break; |
| 4493 | 4493 | } |
| 4494 | 4494 | pioh = &ioh->next; |
| ... | ... | @@ -4509,6 +4509,7 @@ int qemu_set_fd_handler2(int fd, |
| 4509 | 4509 | ioh->fd_read = fd_read; |
| 4510 | 4510 | ioh->fd_write = fd_write; |
| 4511 | 4511 | ioh->opaque = opaque; |
| 4512 | + ioh->deleted = 0; | |
| 4512 | 4513 | } |
| 4513 | 4514 | return 0; |
| 4514 | 4515 | } |
| ... | ... | @@ -6157,7 +6158,7 @@ void qemu_system_powerdown_request(void) |
| 6157 | 6158 | |
| 6158 | 6159 | void main_loop_wait(int timeout) |
| 6159 | 6160 | { |
| 6160 | - IOHandlerRecord *ioh, *ioh_next; | |
| 6161 | + IOHandlerRecord *ioh; | |
| 6161 | 6162 | fd_set rfds, wfds, xfds; |
| 6162 | 6163 | int ret, nfds; |
| 6163 | 6164 | struct timeval tv; |
| ... | ... | @@ -6192,6 +6193,8 @@ void main_loop_wait(int timeout) |
| 6192 | 6193 | FD_ZERO(&wfds); |
| 6193 | 6194 | FD_ZERO(&xfds); |
| 6194 | 6195 | for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) { |
| 6196 | + if (ioh->deleted) | |
| 6197 | + continue; | |
| 6195 | 6198 | if (ioh->fd_read && |
| 6196 | 6199 | (!ioh->fd_read_poll || |
| 6197 | 6200 | ioh->fd_read_poll(ioh->opaque) != 0)) { |
| ... | ... | @@ -6219,9 +6222,11 @@ void main_loop_wait(int timeout) |
| 6219 | 6222 | #endif |
| 6220 | 6223 | ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv); |
| 6221 | 6224 | if (ret > 0) { |
| 6222 | - /* XXX: better handling of removal */ | |
| 6223 | - for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) { | |
| 6224 | - ioh_next = ioh->next; | |
| 6225 | + IOHandlerRecord **pioh; | |
| 6226 | + | |
| 6227 | + for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) { | |
| 6228 | + if (ioh->deleted) | |
| 6229 | + continue; | |
| 6225 | 6230 | if (FD_ISSET(ioh->fd, &rfds)) { |
| 6226 | 6231 | ioh->fd_read(ioh->opaque); |
| 6227 | 6232 | } |
| ... | ... | @@ -6229,6 +6234,17 @@ void main_loop_wait(int timeout) |
| 6229 | 6234 | ioh->fd_write(ioh->opaque); |
| 6230 | 6235 | } |
| 6231 | 6236 | } |
| 6237 | + | |
| 6238 | + /* remove deleted IO handlers */ | |
| 6239 | + pioh = &first_io_handler; | |
| 6240 | + while (*pioh) { | |
| 6241 | + ioh = *pioh; | |
| 6242 | + if (ioh->deleted) { | |
| 6243 | + *pioh = ioh->next; | |
| 6244 | + qemu_free(ioh); | |
| 6245 | + } else | |
| 6246 | + pioh = &ioh->next; | |
| 6247 | + } | |
| 6232 | 6248 | } |
| 6233 | 6249 | #if defined(CONFIG_SLIRP) |
| 6234 | 6250 | if (slirp_inited) { | ... | ... |