Yang Gao | 16 Jul 23:46 2014
Picon

Race condition on event_debug_mode_too_late.

Hi,

In one of our tests, we saw a race condition on event_debug_mode_too_late. We are using 2.0.21 stable.

In the test, one thread has on top of the stack
#0  event_assign
#1  event_new
#2 ... omitted

and another is doing
#0  event_add_internal
#1  event_add
#2  ... omitted

Setting macro _EVENT_DISABLE_DEBUG_MODE fixes the problem. 

A google search shows this might be similar to reports here:
and here:

Thanks.

Yang

CJ Ess | 5 Jul 03:55 2014
Picon

libevent http post/put example, please

I believe I've Googled thoroughly and gone through everything on Github, and while I can find many step-by-step examples of handling http GETs with libevent, I can not find any good examples of how to handle a POST or PUT. The few examples I do find seem to assume that the entire request, headers and body, is in memory.

I would like to see an example of receiving a POST or PUT with a large body - larger then available memory. Does anyone have one they could post here or send to me privately?

Andre | 3 Jul 17:41 2014
Picon

Using evbuffer_add to write into a file

Hello
I have a lot of functions for serialization data. At the moment I am 
just sending these data to other sockets. But I want to save some of the 
information with the same functions for serialization in a file. So I 
thought that there is might be a chance to fopen and fwrite the data via 
libevent with it's file descriptor. I searched a lot but I found nothing 
similar to this.
I am using libevent 2.1.4.
Thanks in advance.
***********************************************************************
To unsubscribe, send an e-mail to majordomo <at> freehaven.net with
unsubscribe libevent-users    in the body.

Hiroaki Hata | 27 Jun 15:50 2014
Picon

output buffer length check of SSL connection

Hi

le-proxy.c sample is very helpful for me. Thanks Nick.
https://github.com/nmathewson/Libevent/blob/master/sample/le-proxy.c

I'm tried to use it for SSL connections and noticed some transmitted 
packets dropped. 
In congestion control, we have to check the length of output buffer,
but when the SSL is used, the buffer of the underlay bufferevent b_out
should be checked rather than the filter event of SSL.
In the sample code, the underlay bufferevent is overwritten with b_ssl.
I cached b_out and checked the buffer length of it and set write callback
to it, then the congestion works well.
This is a just comment but I appreciate you for your detailed online manuals
and comprehensive examples.

Hiroaki Hata

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

Robin | 26 Jun 14:36 2014

Event timeout after it has been freed

Hey,
I'm still investigating the issues from my other email and came across 
another thing.
This might, again, be due to memory corruption on my side - I'm hoping 
it isn't though.

I implemented a simple timer-event class which basically creates an 
event with a timeout and calls an std::function once that timeout is hit.
Every now and then I get crashes in my ping event.
The ping event is a lambda which captures the "this" pointer of my 
socket and just pings the client every 30 seconds.
The crashes are always related to the ping event having a nullptr as the 
socket pointer.
So I did some recording in gdb and came to the conclusion it gets set to 
0 in the destructor of the event class, which gets called when a socket 
disconnects.
Backtrace can be seen here:
http://puu.sh/9KSs8/927aa257e2.txt
Destructor just calls event_del, if the event is running, followed by an 
event_free
It rarely happens, I had to wait for that crash for about 5hours, thats 
10k connections minimum.

Could it be the event doesnt get canceled when it is pending?
Like the event "queue" could look something like this
1. Disconnect socket x
2. Socket y recieve
4. Socket x send
5. Event z timeout

"1." would cancel Event z though
(I am just guessing here since I have no idea why it's happening)

Really hope someone is able to help me out, slowly going insane..

imer

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

Robin | 15 Jun 15:09 2014

Valgrind, evmap_io_add Invalid write of size 4

Hey,

I was just debugging some crashes and memory leaks with valgrind and 
this came up:
[warn] Epoll MOD(4) on fd 61 failed.  Old events were 6; read change was 
2 (del); write change was 0 (none): Bad file descriptor
> ==10706== Invalid write of size 4
> ==10706==    at 0x5348FE6: evmap_io_add (in 
> /usr/lib/i386-linux-gnu/libevent-2.0.so.5.1.7)
> ==10706==    by 0x5337BAA: event_add (in 
> /usr/lib/i386-linux-gnu/libevent-2.0.so.5.1.7)
> ==10706==    by 0x5343A57: _bufferevent_add_event (in 
> /usr/lib/i386-linux-gnu/libevent-2.0.so.5.1.7)
> ==10706==    by 0x53441DC: be_socket_enable (in 
> /usr/lib/i386-linux-gnu/libevent-2.0.so.5.1.7)
> ==10706==    by 0x5343475: bufferevent_enable (in 
> /usr/lib/i386-linux-gnu/libevent-2.0.so.5.1.7)
> ==10706==    by 0x806974F: net::Socket::Setup(int, sockaddr_in) 
> (Socket.cpp:77)
> ==10706==    by 0x8068A96: 
> net::Listener<net::socket::Client>::Accept(int, sockaddr_in*) 
> (Listener.hpp:85)
> ==10706==    by 0x806885A: 
> net::Listener<net::socket::Client>::SOnAccept(evconnlistener*, int, 
> sockaddr*, int, void*) (Listener.hpp:112)
> ==10706==    by 0x53462E1: listener_read_cb (in 
> /usr/lib/i386-linux-gnu/libevent-2.0.so.5.1.7)
> ==10706==    by 0x78BBD23D: ???
> ==10706==  Address 0x61d44e80 is 176 bytes inside a block of size 
> 4,056 free'd
> [...] Non libevent related stuff, some free'd memory which has nothing 
> to do with libevent

net::Listener:
>         void Accept(evutil_socket_t fd, sockaddr_in * addr) {
>             sys_log(0, "New connection on %s:%d from %s", 
> m_bind_ip.c_str(), m_bind_port, inet_ntoa(addr->sin_addr));
>             SocketType* s = new SocketType();
>             s->SetID(m_socket_id++);
>             if (!s->Setup(fd, *addr)) {
>                 sys_err("Failed to set up socket %d", m_socket_id);
>                 delete s;
>                 return;
>             }
>             if (!OnAccept(s)) {
>                 delete s;
>                 return;
>             }
>             m_sockets.insert(std::pair<unsigned int, 
> SocketType*>(s->GetID(), s));
>         }
>         static void SOnAccept(evconnlistener *, evutil_socket_t fd, 
> struct sockaddr * addr, int socklen, void * arg) {
>             if (!arg) {
>                 sys_err("Recieved nullpointer as arg");
>                 return;
>             }
>             Listener<SocketType>* l = (Listener<SocketType>*) arg;
>             l->Accept(fd, (sockaddr_in*) addr);
>         }
The callback is registered like this:
m_listener = 
evconnlistener_new_bind(NetworkManager::instance().GetEventBase(), 
Listener::SOnAccept, this, LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, 
1024, (sockaddr*) & sa, sizeof (sa));

  Socket::Setup:
>     bool Socket::Setup(evutil_socket_t fd, sockaddr_in addr) {
>         if (m_event) {
>             sys_err("Socket already set up");
>             return false;
>         }
>         m_addr = addr;
>         m_event = 
> bufferevent_socket_new(NetworkManager::instance().GetEventBase(), fd, 
> _SOCKET_DEFAULT_FLAGS);
>         bufferevent_setcb(m_event, Socket::SOnRead, Socket::SOnWrite, 
> Socket::SOnEvent, this);
>         bufferevent_enable(m_event, EV_READ | EV_WRITE);
>         OnConnect();
>         return true;
>     }
Is this just a false positive or am I doing something wrong?
This doesn't happen every time there's a new connection, in fact, it 
only seems to happen once

I am running on Debian Wheezy & libevent 2.0.19

I am also getting a bunch of these type errors:
> [warn] Epoll MOD(4) on fd 68 failed.  Old events were 6; read change 
> was 2 (del); write change was 0 (none): Bad file descriptor

Usually after it hit a breakpoint or it couldn't keep up (running this 
in a single thread+valgrind, stuff gets sloow)
Am I right to assume I can just ignore it as it only seems to happen 
when running valgrind?

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

Nick Mathewson | 9 Jun 05:04 2014
Picon

Sorry -- patch review is going slowly (and how you can help)

Hi, all!

Things have been busy in my day job, so please accept my apologies for
the slow speed of getting incoming patches reviewed.  I'll try to set
aside time in June to reduce those queues as much as I can.

You can help!  If you've looked around the Libevent codebase much at
all, you could have a look through patches and bug reports at the
various trackers that people seem to be using.

There's the one I'd prefer people to use for patches:

   https://github.com/libevent/libevent/

And there's the other two:

   https://github.com/nmathewson/libevent/
   http://sourceforge.net/projects/levent/

When reviewing patches, here are some things to look for:
  * If this is a patch to libevent itself, is it tested?  Is it
correct?  (Whenever possible, changes should have tests.)
  * If this is a patch to the documentation or the sample code, does
it really improve clarity?
  * If this patch introduces any new APIs, are they well-documented,
reasonable, and relatively future-proot?
  * If this patch changes any existing APIs, will the change break any
existing correct code?  (If so, the patch must change. We don't do
this kind of API breakage.)

cheers,
--

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

Adrian Chadd | 7 Jun 21:41 2014
Picon

libevent2 and delete-after-close with kqueue

Hi all,

I'm trying to chase down a bug with libevent2-trunk.

The TL;DR is that I have ktrace traces from FreeBSD showing that an FD
delete event is being kqueued to a kqueue FD after the FD has been
closed in that thread. It's responsible for ENOTCAPABLE showing up.
Something like EBADF just drops through; ENOTCAPABLE currently causes
the IO loop to terminate. This is with a multi-threaded server, but
there's one event base per thread and one accept FD per event base.

It _looks_ like the evhttp / bufferevent code is doing the right thing
- ie, it's deleting the events (which should delete them from the
kqueue list) before calling close(). But there's a bunch of places
that I have to actually go and check. Unfortunately "EV_DELETE"
entries are being left on the kqueue list and not removed. The only
way to know that these need to be removed is to actually call the
event deletion function from evutil.c when the socket is closed.
Teaching evutil_closesocket() would do it, but it would require an
eventbase. It also implies that a socket is only in one event base -
it's quite possible servers have an FD in multiple event bases. Ugh.

What do people think?

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

Andre | 28 May 20:19 2014
Picon

Unexpected exit

Hello
I just cloned your official git repo updating libevent and everything 
works fine until I changed something that I can not figure out anymore.
Libevent exits the program with the code 141 every time at the same code 
line.
In this line I call evbuffer_add. The buffer have to be valid because 
the evbuffer_add I call one line before works fine. The pointer is valid 
too.
The fatal callback defined by event_set_fatal_callback is not called.
Thanks in advance.
***********************************************************************
To unsubscribe, send an e-mail to majordomo <at> freehaven.net with
unsubscribe libevent-users    in the body.

Nick Giles | 18 May 18:43 2014

Multithreading to handle HTTP keep-alive connections

Hello.

A while ago I asked this question on Stackoverflow ( http://stackoverflow.com/questions/21677154/libevent-multithreading-to-handle-http-keep-alive-connections ) but didn't have much luck with getting any replies, so I thought I'd ask on the mailing list.   Here's the question:

I am writing an HTTP reverse-proxy in C using Libevent and I would like to implement multithreading to make use of all available CPU cores. I had a look at this example: http://roncemer.com/software-development/multi-threaded-libevent-server-example/

In this example it appears that one thread is used for the full duration of a connection, but for HTTP 1.1 I don't think this will be the most effective solution as connections are kept alive by default after each request so that they can be reused later. I have noticed that even one browser panel can open several connections to one server and keep them open until the tab is closed which would immediately exhaust the thread pool. For an HTTP 1.1 proxy there will be many open connections but only very few of them actively transferring data at a given moment.

So I was thinking of an alternative, to have one event base for all incoming connections and have the event callback functions delegate to worker threads. This way we could have many open connections and make use of a thread only when data arrives on a connection, returning it back to the pool once the data has been dealt with.

My question is: is this a suitable implementation of threads with Libevent?

Specifically – is there any need to have one event base per connection as in the example or is one for all connections sufficient?

Also – are there any other issues I should be aware of?

Currently the only problem I can see is with burstiness, when data is received in many small chunks triggering many read events per HTTP response which would lead to a lot of handing-off to worker threads. Would this be a problem? If it would be, then it could be somewhat negated using Libevent's watermarking, although I'm not sure how that works if a request arrives in two chunks and the second chunk is sufficiently small to leave the buffer size below the watermark. Would it then stay there until more data arrives?

Also, I would need to implement scheduling so that a chunk is only sent once the previous chunk has been fully sent.

The second problem I thought of is when the thread pool is exhausted, i.e. all threads are currently doing something, and another read event occurs – this would lead to the read event callback blocking. Does that matter? I thought of putting these into another queue, but surely that's exactly what happens internally in the event base. On the other hand, a second queue might be a good way to organise scheduling of the chunks without blocking worker threads.

Thanks!

Nick.

Bill Vaughan | 15 May 19:17 2014
Picon

polarSSL support

Hello,

I have used libevent on two projects now with great success. I use the bufferevent_ssl() APIs on one project, but I now have a requirement to work with PolarSSL.  I really like the well documented and clean PolarSSL APIs, but since it is GPL I suppose no one has created a PolarSSL implementation for libevent? At least I didn't see much on this after searching around a bit.

BTW...Nick: you and your contributors have done a great job with libevent. I really enjoy working with it.  Just did a solo project for an airline and it is running right now with 20K+ concurrent connections.

Thanks,
-Bill



 


Gmane