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);
}
_______________________________________________
libev mailing list
[email protected]
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev