From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1G4on6-0002zc-8J for qemu-devel@nongnu.org; Sun, 23 Jul 2006 20:59:24 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1G4on4-0002zP-RP for qemu-devel@nongnu.org; Sun, 23 Jul 2006 20:59:23 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1G4on4-0002zM-Ju for qemu-devel@nongnu.org; Sun, 23 Jul 2006 20:59:22 -0400 Received: from [70.116.9.243] (helo=localhost.localdomain) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA:32) (Exim 4.52) id 1G4oo2-0005qZ-MD for qemu-devel@nongnu.org; Sun, 23 Jul 2006 21:00:23 -0400 Received: from localhost ([127.0.0.1]) by localhost.localdomain with esmtp (Exim 4.60) (envelope-from ) id 1G4omT-0002jc-CO for qemu-devel@nongnu.org; Sun, 23 Jul 2006 19:58:45 -0500 Message-ID: <44C41B45.1080302@codemonkey.ws> Date: Sun, 23 Jul 2006 19:58:45 -0500 From: Anthony Liguori MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------050902080806070505070208" Subject: [Qemu-devel] [PATCH] Fix select loop to handle handler deletions Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This is a multi-part message in MIME format. --------------050902080806070505070208 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit The current select loop can SEGV if a handler removes itself. The following patch changes the select loop to be safe no matter how the io handler list is changed. It definitely changes the complexity of the dispatch but since there are usually so few fds, I don't think it really matters. Regards, Anthony Liguori --------------050902080806070505070208 Content-Type: text/x-patch; name="select-loop.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="select-loop.diff" # HG changeset patch # User Anthony Liguori # Node ID 2b8742c4699e6726de3fde00831a3b1248fe1a79 # Parent 14d871ce5717d63e4bea98bca85653aa1cecdcba Fix dispatch loop. If a callback removes itself, it can lead to a SEGV. diff -r 14d871ce5717 -r 2b8742c4699e vl.c --- a/vl.c Sun Jul 23 18:14:01 2006 -0500 +++ b/vl.c Sun Jul 23 19:19:20 2006 -0500 @@ -4942,14 +4942,26 @@ void qemu_system_powerdown_request(void) cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); } +static IOHandlerRecord *find_io_handler(int fd) +{ + IOHandlerRecord *ioh; + + for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) { + if (ioh->fd == fd) + break; + } + + return ioh; +} + void main_loop_wait(int timeout) { - IOHandlerRecord *ioh, *ioh_next; + IOHandlerRecord *ioh; fd_set rfds, wfds, xfds; int ret, nfds; struct timeval tv; PollingEntry *pe; - + int i; /* XXX: need to suppress polling by better using win32 events */ ret = 0; @@ -5006,16 +5018,18 @@ 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; - if (FD_ISSET(ioh->fd, &rfds)) { - ioh->fd_read(ioh->opaque); - } - if (FD_ISSET(ioh->fd, &wfds)) { - ioh->fd_write(ioh->opaque); - } - } + for (i = 0; i < nfds + 1; i++) { + if (FD_ISSET(i, &rfds)) { + ioh = find_io_handler(i); + if (ioh && ioh->fd_read) + ioh->fd_read(ioh->opaque); + } + if (FD_ISSET(i, &wfds)) { + ioh = find_io_handler(i); + if (ioh && ioh->fd_write) + ioh->fd_write(ioh->opaque); + } + } } #if defined(CONFIG_SLIRP) if (slirp_inited) { --------------050902080806070505070208--