[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[Libevent-users] [evhttp] Issues using blocking operation


I'm using the libevent 1.4.14 to implement a web server
that provides some simple html pages, each managed by a callback function.

One of these callback, before rendering the html page, will perform an intensive operation (as read a file of an a priori unknown size) that could block the web-server for some minutes. The callback must complete the reading operation before creating the HTML page content and then call the function evhttp_send_reply() to send the reply.

To prevent this problem, I had tried to add a simple thread (pthread) in the callback body. My intention is to run the thread to read the file, without blocking the web server that continues to respond. When the reading operation is completed, the thread calls the function evhttp_send_reply() and then terminates.

I had problems with this solution, so I wrote a minimal example of web server (named micro.c) to show you my problem and ask some advice. The code of web server and the Makefile have been compressed and are temporarily available here: http://dl.dropbox.com/u/6002228/micro.tar.gz

The web-server, used in this example, runs without special configurations and simply listens on port 8000. In the main function have been registered three callbacks:

evhttp_set_cb (server, "/", home_cb, NULL);
evhttp_set_cb (server, "/page1", page1_cb, NULL);
evhttp_set_cb (server, "/page2", page2_cb, NULL);

The url "/page1" is managed by the callback "page1_cb()" and it simulates the blocking operation and creates the thread. To simulate the blocking operation I called a sleep(5) in the thread code.

If I click on "Page1" in my browser and I wait 5 seconds, the web server works fine: after 5 seconds the page is shown. If during those 5 seconds I click to another page (e.g. I click on the link of "Page2"), when the 5 seconds are elapsed there is a segmentation-fault. (I added in micro.tar.gz the gdb output in a file named 'gdb.txt').

I think the problem is caused by the sharing of the structure evhttp_request, but I have not found other ways to manage the response with the thread. I have to create a new evhttp_request in the thread?

My primary requirement is to not block the web server while a callback performs a long operation. Do you have suggestions, corrections, ideas?

Any help would be greatly appreciated,
thanks in advance!

Valeria Lorenzetti


To try my example, download the source code of the web-server:

> wget http://dl.dropbox.com/u/6002228/micro.tar.gz
> tar xvfz micro1.4.tar.gz
> cd micro1.4/

Download in this folder the latest libevent 1.4.x, then configure and compile it:

> wget http://monkey.org/~provos/libevent-1.4.14b-stable.tar.gz
> tar xvfz libevent-1.4.14b-stable.tar.gz
> cd libevent-1.4.14b-stable
> ./configure
> make

Return to the previous folder and compile the code of the web server:

> cd ..
> make

Run the web-server (by default it will be listening on port 8000).

> ./micro
> [micro] Now accepting connections on http://*:8000

Now, with a browser open "http://localhost:8000/", then use the HTML link to open 'Page1" (the page with the thread), then click to "Page2" and wait...