I've recently started a project that includes bi-directional HTTP messaging to an embedded Ubuntu program (10.4). Libevent has the perfect feature set for this project, so I jumped on board, and started the implementation using 2.0.20. I am a new libevent user.
The first phase was accepting inbound HTTP GET messages. I had no issues
with that, and it seems to be rock solid. J When I got to the second phase,
which is sending HTTP posts, I started running into all kinds of stability
issues. When I watch the HTTP activity on Wireshark, I see many cases where
the TCP connection is set up perfectly, but the HTTP message is never sent.
I also see way too many retransmissions, considering this is a loopback IP
address. I have run the program under Valgrind, and it doesn't report any
issues. The response handler typically reports 'timeout'.
I may see three or four successful transmissions, then things fall apart. I
occasionally get a callback to the fatal error handler, indicating something
is wrong. The error is not the same every time, though. Here is an
example:
event_del_internal: noting a del on a non-setup event
My code is pretty basic, but I am sure I am missing something. It smells
like a multi-thread issue - the initialization code runs in a different
thread than the app generating the outbound HTTP messages, and in a
different thread than the event loop.
Initialization:
LibEventShell::LibEventShell()
{
event_set_log_callback(eventLibLog);
event_set_fatal_callback(eventFatal_cb);
evthread_use_pthreads();
#pragma message("Debug mode enabled, should be turned off for production")
event_enable_debug_mode();
}
// The following is extracted from a constructor for my HTTP_Transport
class.
LibEventShell();
eventBase_ = event_base_new();
event_base_priority_init(eventBase_, 1);
eventHttp_ = evhttp_new(eventBase_);
evhttp_set_gencb(eventHttp_,requestHandler,(void *)this);
pDNSServer_ = evdns_base_new (eventBase_,1);
serverThread_ = new cHTTPServer(eventBase_);
serverThread_->detach();
serverThread_->ThreadWait();
HTTP Event loop thread:
while (1)
{
Thread::sleep(100);
event_base_dispatch(eventBase_);
}
Then, to send a request. I have trimmed it down to the bare minimum. no DNS,
no timeout. I get the same results either way.
//msg and URI are input parms.
struct evhttp_request *pReq =
evhttp_request_new(responseHandler, (void *)this);
evhttp_add_header(evhttp_request_get_output_headers(pReq),"Content-Type",
"text/xml; charset=utf-8");
evhttp_add_header(evhttp_request_get_output_headers(pReq),"User-Agent",
endpointIdentifier_.c_str());
struct evbuffer * pOutBuf =
evhttp_request_get_output_buffer(pReq);
evbuffer_add(pOutBuf,msg.c_str(),msg.size());
pConn_ = evhttp_connection_base_new (eventBase_,
NULL/*pDNSServer_*/, "127.0.0.1", 8083);
//evhttp_connection_set_local_address(pConn_,"127.0.0.1");
//evhttp_connection_set_timeout(pConn_,3);
http_result = evhttp_make_request(pConn_, pReq,
EVHTTP_REQ_POST, URI_.c_str());
Does anyone see something obvious here?
smime.p7s
Description: S/MIME cryptographic signature
