mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
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
This commit is contained in:
parent
c72aecc5fc
commit
d97093437f
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user