mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 20:42:59 +01:00
Merge #11593: rpc: work-around an upstream libevent bug
97932cd
rpc: further constrain the libevent workaround (Cory Fields)6b58360
rpc: work-around an upstream libevent bug (Cory Fields) Pull request description: A rare race condition may trigger while awaiting the body of a message. This may fix some reported rpc hangs/crashes. This work-around mimics what libevent does internally once a write has started, which is what usually happens, but not always due to the processing happening on a different thread:e7ff4ef2b4/http.c (L373)
Fixed upstream at:5ff8eb2637
Tree-SHA512: b9fa97cae9da2a44101c5faf1e3be0b9cbdf722982d35541cf224be31430779c75e519c8ed18d06ab7487bfb1211069b28f22739f126d6c28ca62d3f73b79a52
This commit is contained in:
commit
7008b07005
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include <event2/thread.h>
|
#include <event2/thread.h>
|
||||||
#include <event2/buffer.h>
|
#include <event2/buffer.h>
|
||||||
|
#include <event2/bufferevent.h>
|
||||||
#include <event2/util.h>
|
#include <event2/util.h>
|
||||||
#include <event2/keyvalq_struct.h>
|
#include <event2/keyvalq_struct.h>
|
||||||
|
|
||||||
@ -239,6 +240,16 @@ static std::string RequestMethodString(HTTPRequest::RequestMethod m)
|
|||||||
/** HTTP request callback */
|
/** HTTP request callback */
|
||||||
static void http_request_cb(struct evhttp_request* req, void* arg)
|
static void http_request_cb(struct evhttp_request* req, void* arg)
|
||||||
{
|
{
|
||||||
|
// Disable reading to work around a libevent bug, fixed in 2.2.0.
|
||||||
|
if (event_get_version_number() >= 0x02010600 && event_get_version_number() < 0x02020001) {
|
||||||
|
evhttp_connection* conn = evhttp_request_get_connection(req);
|
||||||
|
if (conn) {
|
||||||
|
bufferevent* bev = evhttp_connection_get_bufferevent(conn);
|
||||||
|
if (bev) {
|
||||||
|
bufferevent_disable(bev, EV_READ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
std::unique_ptr<HTTPRequest> hreq(new HTTPRequest(req));
|
std::unique_ptr<HTTPRequest> hreq(new HTTPRequest(req));
|
||||||
|
|
||||||
LogPrint(BCLog::HTTP, "Received a %s request for %s from %s\n",
|
LogPrint(BCLog::HTTP, "Received a %s request for %s from %s\n",
|
||||||
@ -601,8 +612,21 @@ void HTTPRequest::WriteReply(int nStatus, const std::string& strReply)
|
|||||||
struct evbuffer* evb = evhttp_request_get_output_buffer(req);
|
struct evbuffer* evb = evhttp_request_get_output_buffer(req);
|
||||||
assert(evb);
|
assert(evb);
|
||||||
evbuffer_add(evb, strReply.data(), strReply.size());
|
evbuffer_add(evb, strReply.data(), strReply.size());
|
||||||
HTTPEvent* ev = new HTTPEvent(eventBase, true,
|
auto req_copy = req;
|
||||||
std::bind(evhttp_send_reply, req, nStatus, (const char*)nullptr, (struct evbuffer *)nullptr));
|
HTTPEvent* ev = new HTTPEvent(eventBase, true, [req_copy, nStatus]{
|
||||||
|
evhttp_send_reply(req_copy, nStatus, nullptr, nullptr);
|
||||||
|
// Re-enable reading from the socket. This is the second part of the libevent
|
||||||
|
// workaround above.
|
||||||
|
if (event_get_version_number() >= 0x02010600 && event_get_version_number() < 0x02020001) {
|
||||||
|
evhttp_connection* conn = evhttp_request_get_connection(req_copy);
|
||||||
|
if (conn) {
|
||||||
|
bufferevent* bev = evhttp_connection_get_bufferevent(conn);
|
||||||
|
if (bev) {
|
||||||
|
bufferevent_enable(bev, EV_READ | EV_WRITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
ev->trigger(nullptr);
|
ev->trigger(nullptr);
|
||||||
replySent = true;
|
replySent = true;
|
||||||
req = nullptr; // transferred back to main thread
|
req = nullptr; // transferred back to main thread
|
||||||
|
Loading…
Reference in New Issue
Block a user