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,6 +4462,7 @@ typedef struct IOHandlerRecord {
4462 IOCanRWHandler *fd_read_poll; 4462 IOCanRWHandler *fd_read_poll;
4463 IOHandler *fd_read; 4463 IOHandler *fd_read;
4464 IOHandler *fd_write; 4464 IOHandler *fd_write;
  4465 + int deleted;
4465 void *opaque; 4466 void *opaque;
4466 /* temporary data */ 4467 /* temporary data */
4467 struct pollfd *ufd; 4468 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,
4487 if (ioh == NULL) 4488 if (ioh == NULL)
4488 break; 4489 break;
4489 if (ioh->fd == fd) { 4490 if (ioh->fd == fd) {
4490 - *pioh = ioh->next;  
4491 - qemu_free(ioh); 4491 + ioh->deleted = 1;
4492 break; 4492 break;
4493 } 4493 }
4494 pioh = &ioh->next; 4494 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,
4509 ioh->fd_read = fd_read; 4509 ioh->fd_read = fd_read;
4510 ioh->fd_write = fd_write; 4510 ioh->fd_write = fd_write;
4511 ioh->opaque = opaque; 4511 ioh->opaque = opaque;
  4512 + ioh->deleted = 0;
4512 } 4513 }
4513 return 0; 4514 return 0;
4514 } 4515 }
@@ -6157,7 +6158,7 @@ void qemu_system_powerdown_request(void) @@ -6157,7 +6158,7 @@ void qemu_system_powerdown_request(void)
6157 6158
6158 void main_loop_wait(int timeout) 6159 void main_loop_wait(int timeout)
6159 { 6160 {
6160 - IOHandlerRecord *ioh, *ioh_next; 6161 + IOHandlerRecord *ioh;
6161 fd_set rfds, wfds, xfds; 6162 fd_set rfds, wfds, xfds;
6162 int ret, nfds; 6163 int ret, nfds;
6163 struct timeval tv; 6164 struct timeval tv;
@@ -6192,6 +6193,8 @@ void main_loop_wait(int timeout) @@ -6192,6 +6193,8 @@ void main_loop_wait(int timeout)
6192 FD_ZERO(&wfds); 6193 FD_ZERO(&wfds);
6193 FD_ZERO(&xfds); 6194 FD_ZERO(&xfds);
6194 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) { 6195 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
  6196 + if (ioh->deleted)
  6197 + continue;
6195 if (ioh->fd_read && 6198 if (ioh->fd_read &&
6196 (!ioh->fd_read_poll || 6199 (!ioh->fd_read_poll ||
6197 ioh->fd_read_poll(ioh->opaque) != 0)) { 6200 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)
6219 #endif 6222 #endif
6220 ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv); 6223 ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
6221 if (ret > 0) { 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 if (FD_ISSET(ioh->fd, &rfds)) { 6230 if (FD_ISSET(ioh->fd, &rfds)) {
6226 ioh->fd_read(ioh->opaque); 6231 ioh->fd_read(ioh->opaque);
6227 } 6232 }
@@ -6229,6 +6234,17 @@ void main_loop_wait(int timeout) @@ -6229,6 +6234,17 @@ void main_loop_wait(int timeout)
6229 ioh->fd_write(ioh->opaque); 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 #if defined(CONFIG_SLIRP) 6249 #if defined(CONFIG_SLIRP)
6234 if (slirp_inited) { 6250 if (slirp_inited) {