Commit cafffd4024b10ac1eae54b74a5a0f372d86eede7

Authored by ths
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
... ... @@ -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) {
... ...