| 457 | } |
| 458 | |
| 459 | void StopHTTPServer() |
| 460 | { |
| 461 | LogPrint(BCLog::HTTP, "Stopping HTTP server\n"); |
| 462 | if (workQueue) { |
| 463 | LogPrint(BCLog::HTTP, "Waiting for HTTP worker threads to exit\n"); |
| 464 | for (auto& thread: g_thread_http_workers) { |
| 465 | thread.join(); |
| 466 | } |
| 467 | g_thread_http_workers.clear(); |
| 468 | delete workQueue; |
| 469 | workQueue = nullptr; |
| 470 | } |
| 471 | if (eventBase) { |
| 472 | LogPrint(BCLog::HTTP, "Waiting for HTTP event thread to exit\n"); |
| 473 | // Exit the event loop as soon as there are no active events. |
| 474 | event_base_loopexit(eventBase, nullptr); |
| 475 | // Give event loop a few seconds to exit (to send back last RPC responses), then break it |
| 476 | // Before this was solved with event_base_loopexit, but that didn't work as expected in |
| 477 | // at least libevent 2.0.21 and always introduced a delay. In libevent |
| 478 | // master that appears to be solved, so in the future that solution |
| 479 | // could be used again (if desirable). |
| 480 | // (see discussion in https://github.com/bitcoin/bitcoin/pull/6990) |
| 481 | if (threadResult.valid() && threadResult.wait_for(std::chrono::milliseconds(2000)) == std::future_status::timeout) { |
| 482 | LogPrintf("HTTP event loop did not exit within allotted time, sending loopbreak\n"); |
| 483 | event_base_loopbreak(eventBase); |
| 484 | } |
| 485 | threadHTTP.join(); |
| 486 | } |
| 487 | if (eventHTTP) { |
| 488 | evhttp_free(eventHTTP); |
| 489 | eventHTTP = nullptr; |
| 490 | } |
| 491 | if (eventBase) { |
| 492 | event_base_free(eventBase); |
| 493 | eventBase = nullptr; |
| 494 | } |
| 495 | LogPrint(BCLog::HTTP, "Stopped HTTP server\n"); |
| 496 | } |
| 497 | |
| 498 | struct event_base* EventBase() |
| 499 | { |