Lei Kong | 25 Sep 04:57 2015

Dynamically adding and removing evconnlistener

I am trying to share event loop among multiple listeners instead of blocking one thread per listener.

Things work fine if I add all my evconnlistener instances before starting the event loop, but only one listener works if I add them after starting event loop (event loop runs in a background thread). Can I dynamically add and remove evconnlistener instances like this?

juan.fernandez | 4 Sep 13:19 2015

evdns doesn't load hosts file on windows



This code skips loading the hosts file when the call to getnetworkparams succeds.

Doesn’t look right to me…






evdns_base_config_windows_nameservers(struct evdns_base *base)


            int r;

            char *fname;

            if (base == NULL)

                         base = current_base;

            if (base == NULL)

                         return -1;


            if (load_nameservers_with_getnetworkparams(base) == 0)            {


                         return 0;


            r = load_nameservers_from_registry(base);


            fname = evdns_get_default_hosts_filename();

            evdns_base_load_hosts(base, fname);


Krishnan Parthasarathi | 4 Sep 14:13 2015

Missed read callbacks while using filtering bufferevents

Hi all,

We are using libevent (libevent 2.0.22-1) for our lightweight RPC library[1] on top of libevent.
The RPC implementation is length-encoded, i.e the first 8 bytes of the message
contains the length of the message. We use filtered bufferevents to wait until
an entire message is 'pulled-up' into the input buffer before the read callback
is called. While doing the above we face the following issue,

The test client code[2] performs 'N' bufferevent_write() calls before calling
event_base_dispatch().  With instrumentation, I observed that test server[3]
receives 'N' calls to read filter callback, each returning BEV_OK but the read
call back registered on the accepted connection was called only once. Am I
missing something? Could someone point me how to debug this further?

[1] - https://github.com/krisis/pbrpc
[2] - https://github.com/krisis/pbrpc/blob/pbrpc-C-API/tests/client.c
[3] - https://github.com/krisis/pbrpc/blob/pbrpc-C-API/tests/server.c

Thanks in advance,

Krishnan Parthasarathi
Morand, Guy | 25 Aug 11:41 2015

epoll fd in libevent

Hallo libevent developers,

I want to monitor GPIO lines under Linux and I'm using libevent. As I understand, for portability issues, it
is not possible to monitor GPIOs with libevent because the "exception" event is not cross platform.

I saw in a thread of the libevent mailing list that it would be possible to create an epoll and register the
file descriptor in libevent: 

I tried this solution but the problem is that I only get the "POLLPRI" event once at startup, despite I
register the epoll fd in libevent with "EV_READ | EV_PERSIST".

Some code talks more than too many explanation, here is how I register the GPIO in epoll:
int EPollEventLoop::addExceptionHandler(libds::IIoHandler& handler)
    struct epoll_event event;

    // Init must be called
    assert(m_epollFd >= 0);

    // Add to epoll
    event.data.fd = handler.getIoHandle();
    event.events = EPOLLPRI;    
    if (epoll_ctl(m_epollFd, EPOLL_CTL_ADD, handler.getIoHandle(), &event) != 0)
        ILog_msg(NULL, LOG_LEVEL_ERR, "Cannot add event to epoll %s", strerror(errno));
        return -1;

    return 0;

I'm wondering if this solution is supposed to work or if I'm missing something like edge/level triggered.
Anyone could achieve this?

Kind regards,

Guy Morand
To unsubscribe, send an e-mail to majordomo <at> freehaven.net with
unsubscribe libevent-users    in the body.

xiaoxin gao | 18 Aug 07:35 2015

libevent performance problem for detect the socket is readable

Hi all,

 I use libevent in my program, but I meet some performance problem.

I create one class named SocketEventBase. SocketEventBase is one thread and use event_base_dispatch() to check socket.

There is one list<socket*> in the SocketEventBase. Use SocketEventBase to listen all the socket in the list.

When the socket is ready to read, libevent framework will remove socket from the list and I will use another thread(named Handler) to deal the request by using
the callback function.

After Handler complete the request, i will add the socket to event base again.

So during the run-time, there are lots of event will be remove from and add to
the event base.

I try to use more event base to get better performance. I use handler-thread-pool-num to control the num of SocketEventBase. Assume handler-thread-pool-num is four, all requests will be dispatch to the four event base.

When i don't use libevent, one thread will service one socket.

After i use libevent, i wish less threads can service same num of socket and will get better performance.

But i test my program as below.

I use 300 client threads to test my program.
(It is a sysbench oltp test, and libevent is used inside a proxy, which is located between the sysbench and backend mysql)

When i don't use libevent, i get 10000~12000 tps.

After i use libevent, different handler-thread-pool-num get different result.

handler-thread-pool-num          tps
1                               1101.17
2                               2065.75
4                               3354.30
8                               3995.18
16                              4308.92

Then i monitor my program like below:
| Monitor_point        | Cost_time | %      |
| session_other        | 37462     | 78.36  |
| session_svc          | 47805     | 100.00 |
| session_switch       | 484       | 1.01   |
| session_work         | 9670      | 20.23  |

session_svc : all the time of the requests be done
session_switch : the time is when socket is ready to read, move request from SocketEventBase to Handler.
session_work : the time is Handler deal the requests
session_other : the time is from adding socket to SocketEventBase's list to find the socket is ready to read. (The time is also include waiting for sysbench client to send the request, but it still too much, cause the  session_work is only 20%, which also
includes the time for backend mysql handle the sql request and send back result )

I don't know why session_other needs so much time. Is libevent need so much time to find the socket is ready?

some other test result as below:

client thread = 30
tps 2696.23
session_other 14.56%

client thread = 60
tps 4323.21
session_other 27.18%

client thread = 90
tps 5019.76
session_other 41.99%

client thread = 120
tps 4893.41
session_other 54.31%
Mark Ellzey | 25 Jul 09:49 2015

Sunset of SourceForge.

September 1st, 2015; we will officially close down the SourceForge repository for libevent. All of the packages and code will remain, but all further development and management will be done on Github. (So grab an account there if you don't have one!)

I've accidentally been neglecting SF as of late -  I always forget to look at my spam folder, I will address these before the move.

The decision was due to many reasons. SourceForge lacks: security, no-advertisements, popups,  not to mention it's incredibly slow. 

Github has become a standard for a reason: intuitive,  easy to use, and transparent about any problems that arise.

Tomorrow I will be migrating the current issues and pull requests  from SourceForge over to Github using some hacked up scripts.

Remember, remember, the 1st of September.
Bill Vaughan | 24 Jul 03:56 2015

leak in be_pair_flush

Hi all,

I added bufferevent pairs to my project a few weeks ago as it was perfect for what I needed.  Got it all working nicely but valgrind was reporting a leak.  I finally tracked down the culprit to the bufferevent pair flush code.

Here is the patch for libevent 2.0.22. The lock was being taken and not released if the mode was BEV_NORMAL.

[bvaughan <at> dev-client tproxy]$ git diff
diff --git a/libevent-2.0.22-stable/bufferevent_pair.c b/libevent-2.0.22-stable/bufferevent_pair.c
index e9ed9f5..2a77dc7 100644
--- a/libevent-2.0.22-stable/bufferevent_pair.c
+++ b/libevent-2.0.22-stable/bufferevent_pair.c
<at> <at> -284,14 +284,15 <at> <at> be_pair_flush(struct bufferevent *bev, short iotype,
        struct bufferevent_pair *bev_p = upcast(bev);
        struct bufferevent *partner;
-       incref_and_lock(bev);
        if (!bev_p->partner)
                return -1;
-       partner = downcast(bev_p->partner);
+   if (mode == BEV_NORMAL)
+      return 0;
-       if (mode == BEV_NORMAL)
-               return 0;
+       incref_and_lock(bev);
+   partner = downcast(bev_p->partner);
        if ((iotype & EV_READ) != 0)
                be_pair_transfer(partner, bev, 1);


Jesper Lundgren | 19 Jul 12:29 2015

http client throttle

Hello, I am using libevent http in client mode to send GET requests. Many of the requests I try to send end with http_req_done callbacks where req == NULL and socket error is set to 36 (Operation now in progress). My guess is that the server can not handle the traffic but I am not sure what is the best approach to dynamically adjust the request rate in libevent to prevent socket errors.

Any suggestions?

Ilya Gordeev | 16 Jul 19:47 2015

evdns behaviour questions and suggestions

Hello. Using libevent (specifically evdns subsystem) I've encountered 
with some troubles.

1) How should I properly interrupt all pending evdns_getaddrinfo 
requests and free evdns_base? Let's say I've caught signal to interrupt 
working. If I call evdns_getaddrinfo_cancel for all pending evdns 
getaddrinfo requests and immediately call evdns_base_free(evdns_base, 0) 
and event_base_free(base) then some memory leaks occur.
In my testing program I detect memory leaks using mtrace/muntrace. (If 
it's needed I can attach testing program). In one mtrace log I've got this:
Memory not freed:
            Address     Size     Caller
0x00000000006035e0     0x30  at 0x7ffff799224f
0x0000000000603620    0x108  at 0x7ffff7992687
0x0000000000603730    0x108  at 0x7ffff7992687
0x0000000000603840     0x30  at 0x7ffff799224f
0x0000000000603880     0x30  at 0x7ffff799238f
0x0000000000603d60     0x30  at 0x7ffff799224f
0x0000000000603e60     0x30  at 0x7ffff799238f
0x0000000000603ea0     0x30  at 0x7ffff799238f
0x0000000000603fc0     0x30  at 0x7ffff799238f
0x0000000000604010    0x108  at 0x7ffff7992687
0x0000000000604120     0x40  at 0x7ffff7bc7496
0x0000000000604170     0x40  at 0x7ffff7bc7496
0x00000000006043e0    0x258  at 0x7ffff798d553
0x0000000000604640    0x108  at 0x7ffff7992687
0x0000000000604900    0x258  at 0x7ffff798d553
0x0000000000604b60    0x258  at 0x7ffff798d553
0x0000000000604f20    0x258  at 0x7ffff798d553
0x0000000000605180    0x258  at 0x7ffff798d553
0x00000000006056a0    0x258  at 0x7ffff798d553
0x0000000000605900    0x258  at 0x7ffff798d553
Then in gdb I've got which code they are:
(gdb) info line *0x7ffff798d553
Line 834 of "libevent-2.1.5-beta/evdns.c" starts at address 
0x7ffff798d553 <reply_schedule_callback+35>
    and ends at 0x7ffff798d556 <reply_schedule_callback+38>.
(gdb) info line *0x7ffff799224f
Line 2861 of "libevent-2.1.5-beta/evdns.c"
    starts at address 0x7ffff799224f <evdns_base_resolve_ipv4+63> and 
ends at 0x7ffff7992252 <evdns_base_resolve_ipv4+66>.
(gdb) info line *0x7ffff799238f
Line 2900 of "libevent-2.1.5-beta/evdns.c"
    starts at address 0x7ffff799238f <evdns_base_resolve_ipv6+63> and 
ends at 0x7ffff7992392 <evdns_base_resolve_ipv6+66>.
(gdb) info line *0x7ffff7992687
Line 4650 of "libevent-2.1.5-beta/evdns.c" starts at address 
0x7ffff7992687 <evdns_getaddrinfo+551>
    and ends at 0x7ffff799268a <evdns_getaddrinfo+554>.
(gdb) info line *0x7ffff7bc7496
Line 824 of "libevent-2.1.5-beta/evutil.c" starts at address 
0x7ffff7bc7496 <evutil_new_addrinfo_+70>
    and ends at 0x7ffff7bc7499 <evutil_new_addrinfo_+73>.

2) It would be very useful in some cases if there was additional evdns 
functions similar to some event_* such as: event_base_foreach_event(), 
event_get_callback() and event_get_callback_arg().

3) If evdns_getaddrinfo_cancel is called then evdns_getaddrinfo_request 
callback will be called with result = EVUTIL_EAI_CANCEL (not 
DNS_ERR_CANCEL). Am I right? If yes it was not easy to figure out, in 
documentation it is not very clear.

To unsubscribe, send an e-mail to majordomo <at> freehaven.net with
unsubscribe libevent-users    in the body.

Mark Ellzey | 7 Jul 22:54 2015


sorry for the spam. testing.
Kaustubh Deorukhkar | 23 Jun 12:34 2015

libevent HTTP support feature list


I am new to libevent and would like to know how is the support for HTTP protocol. I am evaluating it for a http server and would help if you all can share experience with using libevent HTTP in prod.

- Does it support full HTTP/1.1 ?
- HTTP pipe-lining (found some posts about issues with pipe-lining on keep alive, is it fixed and stable?)
- Expect 100 support for managing requests
- Do we have a feature list of what all is supported?

Will be very helpful if someone can share or point me to docs if any?

Thanks in advance,