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

--
libvir-list mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to