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; | ||||
|     IOHandler *fd_read; | ||||
|     IOHandler *fd_write; | ||||
|     int deleted; | ||||
|     void *opaque; | ||||
|     /* temporary data */ | ||||
|     struct pollfd *ufd; | ||||
| @ -4487,8 +4488,7 @@ int qemu_set_fd_handler2(int fd, | ||||
|             if (ioh == NULL) | ||||
|                 break; | ||||
|             if (ioh->fd == fd) { | ||||
|                 *pioh = ioh->next; | ||||
|                 qemu_free(ioh); | ||||
|                 ioh->deleted = 1; | ||||
|                 break; | ||||
|             } | ||||
|             pioh = &ioh->next; | ||||
| @ -4509,6 +4509,7 @@ int qemu_set_fd_handler2(int fd, | ||||
|         ioh->fd_read = fd_read; | ||||
|         ioh->fd_write = fd_write; | ||||
|         ioh->opaque = opaque; | ||||
|         ioh->deleted = 0; | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
| @ -6157,7 +6158,7 @@ void qemu_system_powerdown_request(void) | ||||
| 
 | ||||
| void main_loop_wait(int timeout) | ||||
| { | ||||
|     IOHandlerRecord *ioh, *ioh_next; | ||||
|     IOHandlerRecord *ioh; | ||||
|     fd_set rfds, wfds, xfds; | ||||
|     int ret, nfds; | ||||
|     struct timeval tv; | ||||
| @ -6192,6 +6193,8 @@ void main_loop_wait(int timeout) | ||||
|     FD_ZERO(&wfds); | ||||
|     FD_ZERO(&xfds); | ||||
|     for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) { | ||||
|         if (ioh->deleted) | ||||
|             continue; | ||||
|         if (ioh->fd_read && | ||||
|             (!ioh->fd_read_poll || | ||||
|              ioh->fd_read_poll(ioh->opaque) != 0)) { | ||||
| @ -6219,9 +6222,11 @@ void main_loop_wait(int timeout) | ||||
| #endif | ||||
|     ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv); | ||||
|     if (ret > 0) { | ||||
|         /* XXX: better handling of removal */ | ||||
|         for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) { | ||||
|             ioh_next = ioh->next; | ||||
|         IOHandlerRecord **pioh; | ||||
| 
 | ||||
|         for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) { | ||||
|             if (ioh->deleted) | ||||
|                 continue; | ||||
|             if (FD_ISSET(ioh->fd, &rfds)) { | ||||
|                 ioh->fd_read(ioh->opaque); | ||||
|             } | ||||
| @ -6229,6 +6234,17 @@ void main_loop_wait(int timeout) | ||||
|                 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 (slirp_inited) { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 ths
						ths