message: rpc: work-around an upstream libevent bug
  A rare race condition may trigger while awaiting the body of a message, see
  upsteam commit for details.
  This may fix some reported rpc hangs/crashes.
  Github-Pull:
  Rebased-From:
diff: #include <event2/thread.h>
  #include <event2/buffer.h>
  +#include <event2/bufferevent.h>
  #include <event2/util.h>
  #include <event2/keyvalq_struct.h>
  @@ -239,6 +240,16 @@ static std::string RequestMethodString(HTTPRequest::RequestMethod m)
  /** HTTP request callback */
  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() < 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));
  LogPrint(BCLog::HTTP, "Received a %s request for %s from %s\n",
  @@ -599,11 +610,24 @@ void HTTPRequest::WriteReply(int nStatus, const std::string& strReply)
  struct evbuffer* evb = evhttp_request_get_output_buffer(req);
  assert(evb);
  evbuffer_add(evb, strReply.data(), strReply.size());
  - HTTPEvent* ev = new HTTPEvent(eventBase, true,
  - std::bind(evhttp_send_reply, req, nStatus, (const char*)nullptr, (struct evbuffer *)nullptr));
  - ev->trigger(0);
  + auto req_copy = req;
  + 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() < 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);
  replySent = true;
  - req = 0; // transferred back to main thread
  + req = nullptr; // transferred back to main thread
  }
  CService HTTPRequest::GetPeer()
  