[libvirt] [PATCH 1/9] Fix crash when aborting a stream from a I/O callback

Daniel P. Berrange berrange at redhat.com
Tue Jun 28 17:01:51 UTC 2011


If a callback being invoked from a stream issues a virStreamAbort
operation, the stream data will be free'd but the callback will
then stil try to use this. Delay free'ing of the stream data when
a callback is dispatching

* src/fdstream.c: Delay stream free when callback is active
---
 src/fdstream.c |   33 +++++++++++++++++++++++----------
 1 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/src/fdstream.c b/src/fdstream.c
index c1ad787..182b6fa 100644
--- a/src/fdstream.c
+++ b/src/fdstream.c
@@ -56,8 +56,9 @@ struct virFDStreamData {
     unsigned long long length;
 
     int watch;
-    unsigned int cbRemoved;
-    unsigned int dispatching;
+    bool cbRemoved;
+    bool dispatching;
+    bool closed;
     virStreamEventCallback cb;
     void *opaque;
     virFreeCallback ff;
@@ -85,7 +86,7 @@ static int virFDStreamRemoveCallback(virStreamPtr stream)
 
     virEventRemoveHandle(fdst->watch);
     if (fdst->dispatching)
-        fdst->cbRemoved = 1;
+        fdst->cbRemoved = true;
     else if (fdst->ff)
         (fdst->ff)(fdst->opaque);
 
@@ -138,6 +139,7 @@ static void virFDStreamEvent(int watch ATTRIBUTE_UNUSED,
     virStreamEventCallback cb;
     void *cbopaque;
     virFreeCallback ff;
+    bool closed;
 
     if (!fdst)
         return;
@@ -151,16 +153,22 @@ static void virFDStreamEvent(int watch ATTRIBUTE_UNUSED,
     cb = fdst->cb;
     cbopaque = fdst->opaque;
     ff = fdst->ff;
-    fdst->dispatching = 1;
+    fdst->dispatching = true;
     virMutexUnlock(&fdst->lock);
 
     cb(stream, events, cbopaque);
 
     virMutexLock(&fdst->lock);
-    fdst->dispatching = 0;
+    fdst->dispatching = false;
     if (fdst->cbRemoved && ff)
         (ff)(cbopaque);
+    closed = fdst->closed;
     virMutexUnlock(&fdst->lock);
+
+    if (closed) {
+        virMutexDestroy(&fdst->lock);
+        VIR_FREE(fdst);
+    }
 }
 
 static int
@@ -196,7 +204,7 @@ virFDStreamAddCallback(virStreamPtr st,
         goto cleanup;
     }
 
-    fdst->cbRemoved = 0;
+    fdst->cbRemoved = false;
     fdst->cb = cb;
     fdst->opaque = opaque;
     fdst->ff = ff;
@@ -252,13 +260,18 @@ virFDStreamClose(virStreamPtr st)
             ret = -1;
         }
         virCommandFree(fdst->cmd);
+        fdst->cmd = NULL;
     }
-
     st->privateData = NULL;
 
-    virMutexUnlock(&fdst->lock);
-    virMutexDestroy(&fdst->lock);
-    VIR_FREE(fdst);
+    if (fdst->dispatching) {
+        fdst->closed = true;
+        virMutexUnlock(&fdst->lock);
+    } else {
+        virMutexUnlock(&fdst->lock);
+        virMutexDestroy(&fdst->lock);
+        VIR_FREE(fdst);
+    }
 
     return ret;
 }
-- 
1.7.4.4




More information about the libvir-list mailing list