Some questions about libev

Dejan Markic Dejan.Markic at mobik-ics.com
Fri May 22 15:26:45 CEST 2015


Hello!

I'm writing multi-threaded C client with hiredis and their libev adapter. I'm using multi-threading, because I have several servers to which I send the same command and await their reply.

First of all, there is no ev default loop. Each ev loop is initialized in main thread and is then passed on to pthread_create (along with other stuff like watchers, etc). 
Once the thread starts, it create hiredis async handler and attaches libev with its libev handler and sets up all the callbacks.
After all is initialized and connected, I send commands from main thread to all servers via redisAsyncCommand.

Questions:

1. Hiredis libev adapter uses two ev_io watchers, one for reading and one for writing. It's simply calling start and stop on those watchers based on what it tries to do.
    This does not work for me, unless I register another ev_async watcher, that fires everytime hiredis tries to start/stop the io_watcher. Is that expected? I would say that once
    libev goes into poll/select/etc wait, it will not move out of wait if you stop the watcher, or start the stopped watcher, right?

2. I tried another approach I saw on the internet. Single ev_io watcher, but everytime hiredis tries to stop/start read/write, I to ev_io_stop(...) and then I set EV_READ and/or EV_WRITE flags via ev_io_set and then ev_io_start again. Also in that case, I need ev_async watcher to wakeup the libev. Would you that that single IO watcher approach would be better?

Both 1. and 2. I tried protecting changes in watchers with mutex, but no success. 

3. My test program hangs after few minutes, maybe even few seconds (it's working for atleast 1000 iterations, even 100000 sometimes) after I fire it (sending SET/GET to one or many servers). It hangs in epoll_wait or select (tried different EVBACKEND_*). It doesn't receive the ev_async event it seems. I also have a feeling that there might be some memory corruptions, but I cannot find any using efence or valgrind.
I've enabled EV_VERIFY 3 and sometimes I get "libev: pending watcher not on pending queue" when on EVBACKEND_SELECT.

Any hints before I go and completely rewrite it?

Thank you and kind regards,
Dejan







More information about the libev mailing list