Hi Cong,

> I'm a newbie to libev. I wrote a TCP server with libev. My program has a 
> relatively simple structure, with accept_cb, read_cb, write_cb and timeout_cb 
> defined. However, when I started it, I found the accept call back is called 
> right away and being called about 60K+ times per second. Each "accept()" call 
> sets the errno to EINVAL, since there's no connection. The program uses more 
> than 50% CPU time.

Do you properly bind the listening socket in the setupServerSocket ?
Could you reproduce the content of the setServerSocket() function ?

Also, instead of:

fcntl(svrSockFd, F_SETFL, O_NONBLOCK);

you should use:

fcntl(svrSockFd, F_SETFL, fcntl(svrSockFd, F_GETFL, 0) | O_NONBLOCK);

or even better (one less system call):

int flag = 1;
ioctl(svrSockFd, FIONBIO, &flag);

> My question is that if this is correct? Or there could be something wrong 
> with my program? If this is expected, then do I need to let the accept_cb to 
> sleep to avoid making the CPU too busy? But wouldn't sleeping affect the 
> performance of the server?
> 
> Thanks for your attention!
> 
> Shawn
> 
> Part of my source code:
> In main(), 
> ===============
> 
>       int svrSockFd = setupServerSocket(SOCK_STREAM, g->m_ip, g->m_port);
>               
>       // Make socket non-blocking.
>       fcntl(svrSockFd, F_SETFL, O_NONBLOCK);
> 
>       ev_io* acceptWatcher = (ev_io*)malloc(sizeof(ev_io));           
> 
>       // Init watcher
>       ev_io_init(acceptWatcher, accept_cb, svrSockFd, EV_READ);
> 
>       // Start watcher
>       struct ev_loop* loop = EV_DEFAULT;
>       ev_io_start(loop, acceptWatcher);
> 
>       // Wait for events to arrive
>       ev_run(loop, 0);
> 
> The accept_cb:
> =====================
> static void accept_cb(struct ev_loop* loop, ev_io* w, int revents)
> {
>       Log::debug("serverSocket received data");
>       int svrSockFd = w->fd;          
> 
>       // accept
>       sockaddr_in clientAddress;
>       socklen_t sin_size = (socklen_t)sizeof(clientAddress);
>       int newSockFd = accept(svrSockFd, (sockaddr *)&clientAddress, 
> &sin_size);
>       if (newSockFd < 0) {    // -1, EAGAIN??
>               if (errno == EINVAL) {
>                       //cout << "no connection" << endl;
>               } else {
>                       perror("accept");
>               }
>       } else {
>               // Handle the connection
>                 ...
>       }
> }


Regards,
Pierre-Yves


_______________________________________________
libev mailing list
[email protected]
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev

Reply via email to