Hello,
When I ran programme event-test compiled from event-test.c, I found a problem that, after
virEventRegisterDefaultImpl I do virConnectOpenAuth and virConnectClose, there will be
handlers of socket and pipe opened by virConnectOpenAuth leaked after virConnectClose. So
I did some analysis, and I found the fact following:
In the condition that we only have one connection here
int virNetSocketAddIOCallback(virNetSocketPtr sock,
int events,
virNetSocketIOFunc func,
void *opaque,
virFreeCallback ff)
{
int ret = -1;
virObjectRef(sock); //Here we add sock refers once, then we will get refers equal 2
after
virObjectLock(sock);
if (sock->watch > 0) {
VIR_DEBUG("Watch already registered on socket %p", sock);
goto cleanup;
}
if ((sock->watch = virEventAddHandle(sock->fd, //If we have called
virEventRegisterDefaultImpl, then here we'll get a sock watch non negative and will
not go to cleanup.
events,
virNetSocketEventHandle,
sock,
virNetSocketEventFree)) < 0) {
VIR_DEBUG("Failed to register watch on socket %p", sock);
goto cleanup;
}
sock->func = func;
sock->opaque = opaque;
sock->ff = ff;
ret = 0;
cleanup:
virObjectUnlock(sock);
if (ret != 0)
virObjectUnref(sock); //If we haven't called virEventRegisterDefaultImpl,
we'll be here after virEventAddHandle, and sock refers will decrease to 1
return ret;
}
Condition with virEventRegisterDefaultImpl, we'll do unrefer action in two places:
1. virEventRunDefaultImpl ->virEventPollRunOnce ->virEventRunDefaultImpl
->virEventPollRunOnce ->virEventPollCleanupHandles -> virNetSocketEventFree
-> virObjectUnref
2. virConnectClose ->virObjectUnref ->virConnectDispose
->remoteConnectClose ->doRemoteClose ->virNetClientClose
->virNetClientCloseInternal -> virNetClientIOEventLoopPassTheBuck ->
virNetClientCloseLocked -> virObjectUnref
When event dealing loop is alive, everything work fine, we'll get sock refers 2 after
virConnectOpenAuth and unrefer twice in two places above after virConnectClose. But If
some accidents happened like we quit event dealing loop or virEventRunDefaultImpl
suspended, then sock refers will never be zero, and handlers will never be freed.
In a particular condition we have two threads, thread one doing event dealing loop, thread
two doing something like virConnectOpenAuth and virConnectClose ceaselessly, then
we'll get a big trouble that handlers available will be ate up soon.
I consider to add something like virEventDeregisterDefaultImpl to set addHandleImpl and
his buddy NULL. Apparently it is far away from fixing it completely.
At last I have two questions here:
1. Is it a problem that after virEventRegisterDefaultImpl we have handlers leaked?
2. If it is a problem, is there anybody any good idea to help me out?
Best Regards,
-WangYufei