提交 d9709343 编写于 作者: D Daniel P. Berrange

Fix crash when aborting a stream from a I/O callback

If a callback being invoked from a stream issues a virStreamAbort
operation, the stream data will be free'd but the callback will
then still 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
上级 c72aecc5
...@@ -56,8 +56,9 @@ struct virFDStreamData { ...@@ -56,8 +56,9 @@ struct virFDStreamData {
unsigned long long length; unsigned long long length;
int watch; int watch;
unsigned int cbRemoved; bool cbRemoved;
unsigned int dispatching; bool dispatching;
bool closed;
virStreamEventCallback cb; virStreamEventCallback cb;
void *opaque; void *opaque;
virFreeCallback ff; virFreeCallback ff;
...@@ -85,7 +86,7 @@ static int virFDStreamRemoveCallback(virStreamPtr stream) ...@@ -85,7 +86,7 @@ static int virFDStreamRemoveCallback(virStreamPtr stream)
virEventRemoveHandle(fdst->watch); virEventRemoveHandle(fdst->watch);
if (fdst->dispatching) if (fdst->dispatching)
fdst->cbRemoved = 1; fdst->cbRemoved = true;
else if (fdst->ff) else if (fdst->ff)
(fdst->ff)(fdst->opaque); (fdst->ff)(fdst->opaque);
...@@ -138,6 +139,7 @@ static void virFDStreamEvent(int watch ATTRIBUTE_UNUSED, ...@@ -138,6 +139,7 @@ static void virFDStreamEvent(int watch ATTRIBUTE_UNUSED,
virStreamEventCallback cb; virStreamEventCallback cb;
void *cbopaque; void *cbopaque;
virFreeCallback ff; virFreeCallback ff;
bool closed;
if (!fdst) if (!fdst)
return; return;
...@@ -151,16 +153,22 @@ static void virFDStreamEvent(int watch ATTRIBUTE_UNUSED, ...@@ -151,16 +153,22 @@ static void virFDStreamEvent(int watch ATTRIBUTE_UNUSED,
cb = fdst->cb; cb = fdst->cb;
cbopaque = fdst->opaque; cbopaque = fdst->opaque;
ff = fdst->ff; ff = fdst->ff;
fdst->dispatching = 1; fdst->dispatching = true;
virMutexUnlock(&fdst->lock); virMutexUnlock(&fdst->lock);
cb(stream, events, cbopaque); cb(stream, events, cbopaque);
virMutexLock(&fdst->lock); virMutexLock(&fdst->lock);
fdst->dispatching = 0; fdst->dispatching = false;
if (fdst->cbRemoved && ff) if (fdst->cbRemoved && ff)
(ff)(cbopaque); (ff)(cbopaque);
closed = fdst->closed;
virMutexUnlock(&fdst->lock); virMutexUnlock(&fdst->lock);
if (closed) {
virMutexDestroy(&fdst->lock);
VIR_FREE(fdst);
}
} }
static int static int
...@@ -196,7 +204,7 @@ virFDStreamAddCallback(virStreamPtr st, ...@@ -196,7 +204,7 @@ virFDStreamAddCallback(virStreamPtr st,
goto cleanup; goto cleanup;
} }
fdst->cbRemoved = 0; fdst->cbRemoved = false;
fdst->cb = cb; fdst->cb = cb;
fdst->opaque = opaque; fdst->opaque = opaque;
fdst->ff = ff; fdst->ff = ff;
...@@ -252,13 +260,18 @@ virFDStreamClose(virStreamPtr st) ...@@ -252,13 +260,18 @@ virFDStreamClose(virStreamPtr st)
ret = -1; ret = -1;
} }
virCommandFree(fdst->cmd); virCommandFree(fdst->cmd);
fdst->cmd = NULL;
} }
st->privateData = NULL; st->privateData = NULL;
virMutexUnlock(&fdst->lock); if (fdst->dispatching) {
virMutexDestroy(&fdst->lock); fdst->closed = true;
VIR_FREE(fdst); virMutexUnlock(&fdst->lock);
} else {
virMutexUnlock(&fdst->lock);
virMutexDestroy(&fdst->lock);
VIR_FREE(fdst);
}
return ret; return ret;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册