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? |
Attachment:
smime.p7s
Description: S/MIME cryptographic signature