qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Anthony Liguori <anthony@codemonkey.ws>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] Make removing IOHandlers safe from within an IOHandler
Date: Sat, 24 Feb 2007 11:54:17 -0600	[thread overview]
Message-ID: <45E07BC9.1080209@codemonkey.ws> (raw)

[-- Attachment #1: Type: text/plain, Size: 506 bytes --]

I was getting random SEGVs when disconnecting from the VNC server.  I 
tracked it down to the fact that if you remove a IOHandler from another 
IOHandler, all sorts of badness may result as you're removing entries 
from a linked list while transversing it.

My solution is to simply add a deleted flag to each entry and walk the 
list a second time.  During the second transversal, we'll remove nodes 
that need removing.

Haven't seen the SEGV since I started using this patch.

Regards,

Anthony Liguori

[-- Attachment #2: iohandler-remove.diff --]
[-- Type: text/x-patch, Size: 2123 bytes --]

diff -r 5f92961f382b vl.c
--- a/vl.c	Thu Feb 22 01:48:01 2007 +0000
+++ b/vl.c	Sat Feb 24 11:51:00 2007 -0600
@@ -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;
@@ -6157,7 +6157,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 +6192,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 +6221,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 +6233,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) {

             reply	other threads:[~2007-02-24 17:54 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-02-24 17:54 Anthony Liguori [this message]
2007-02-24 18:39 ` [Qemu-devel] [PATCH] Make removing IOHandlers safe from within an IOHandler Daniel P. Berrange
2007-02-24 19:09   ` [Qemu-devel] [PATCH][UPDATE] " Anthony Liguori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=45E07BC9.1080209@codemonkey.ws \
    --to=anthony@codemonkey.ws \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).