fd/socket free() memory leak and EV_WRITE post event

Rémi Pecqueur remi.pecqueur at gmail.com
Sat Feb 26 13:01:40 CET 2011


Dear all,

After a long googling time and many tests on my program, I am asking you
guys what I am doing wrong:

1) *fd/socket free()/memory leak*:
I am running libev on win32 on a server side to discuss with a mobile
application. I try to reuse as much as possible the 64 file descriptors
available on win32. I was assuming that when a client is closing, I would
need to free the file descriptor and closing the win SOCKET, but only one
close either the socket or the fd works, the other crash... I test the
program on another computer and it results the same issue. Then, if I am
closing only the fd (without the socketclose) and free the other ressources,
I have a memory leak at each close...

2) *ev_write event generation:*
I found the libev io watcher/loop very interesting implementation and I was
expecting to use this smart approach not only to watch read events but to
watch internal write events as well. The documentation explains how to
interface the EV_WRITE event to a WriteCallback, but I do not know how to
generate a write event to call my WriteCallback from the ev_loop. Should I
use the "ev_once()" or "ev_feed_fd_event()" APIs or anything else?

I have include the most relevant lines of my program for your convenience,

Many thanks,
Rémi

class CConnection
{
public:
    int fdSlave;
    SOCKET socketSlave;
    struct sockaddr_in *addrSlave;

    int fdMaster;
    SOCKET socketMaster;
    struct sockaddr_in *addrMaster;

    struct ev_io* ioRead;    //cbTcpEgnXmlRecv
    struct ev_io* ioWrite;    //cbTcpEgnXmlWrite
    struct ev_io* ioAccept; //cbTcpEgnXmlAccept
    .......
}

cbTcpEgnXmlAccept(struct ev_loop *loop, ev_io *w, int revents)
{
    .......
    //create a new slave
    CConnection *pClientInf = new CConnection();
    pClientInf->_clientAddr = (struct sockaddr_in*) malloc (sizeof(struct
sockaddr_in)); //REMI: a passer dans le constructeur

    //CallBacks
    pClientInf->_cbRead =  cbTcpEgnXmlRecv;
    pClientInf->_cbWrite = cbTcpEgnXmlSend;

    pClientInf->socketSlave = ::accept(pServerInf-> socketMaster,
(SOCKADDR*) pClientInf->_clientAddr, &addressLen);

    //get a File Descriptor
    pClientInf->fdSlave = EV_WIN32_HANDLE_TO_FD(pClientInf->socketSlave);

    //setup my new client
    pClientInf->ioRead = (struct ev_io*)malloc(sizeof(struct ev_io));
    pClientInf->ioRead->data = pClientInf;

    //setup the io_event
    ev_io_init(pClientInf->ioRead, pClientInf->_cbRead, pClientInf->fdSlave,
EV_READ);
    ev_io_start(loop, pClientInf->ioRead); //we affect a io to an engine!

}

cbTcpEgnXmlRecv(struct ev_loop *loop, ev_io *w, int revents)
{
    CConnection *pThisClient = (CConnection*)(w->data);
    pThisClient->lockMutex();

    //stop the event io
    int tmp = recv(pThisClient->socketSlave, .....);
    if (tmp != 0)
    {
        //fine I am doing what I have to do with the buffer
    }
    else
    {
        //the socket has been probably closed by the client
        //stop all the watchers
        if(pThisClient->ioRead) ev_io_stop(loop, pThisClient->ioRead);
        if(pThisClient->ioWrite) ev_io_stop(loop, pThisClient->ioWrite);
        //clear the pending events
         int revents = ev_clear_pending(loop, w);

        if(pThisClient->ioRead) free(pThisClient->ioRead);
        if(pThisClient->ioWrite) free(pThisClient->ioWrite);

         //close the socket and the fd
         res = _close(pThisClient->fdSlave);   //this is OK
         res = ::closesocket(pThisClient->socketSlave); //this call crashes
into the closesocket...
    }
}

void
CTcpEgnXml::accept(struct ev_loop *engineLoop, CConnection *pServerInf)
{
    //pClientInf is the server representation
    pServerInf->ioAccept = (struct ev_io*)malloc(sizeof(struct ev_io));
    pServerInf->ioAccept->data = pServerInf;
    pServerInf->_loopConnect = engineLoop;
    pServerInf->fdMaster = SOCKET_TO_FD(pServerInf->socketMaster); //open a
fd and linked it to the socket
    ev_io_init(pServerInf->ioAccept, _cbAccept, pServerInf->fdMaster,
EV_READ);
    ev_io_start(engineLoop, pServerInf->ioAccept);
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.schmorp.de/pipermail/libev/attachments/20110226/0d72e715/attachment.html>


More information about the libev mailing list