diff --git a/src/httpserver.cpp b/src/httpserver.cpp --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -17,12 +17,12 @@ #include #include -#include -#include #include #include #include +#include + #ifdef EVENT__HAVE_NETINET_IN_H #include #ifdef _XOPEN_SOURCE_EXTENDED @@ -359,10 +359,9 @@ } bool InitHTTPServer(Config &config) { - struct evhttp *http = 0; - struct event_base *base = 0; - - if (!InitHTTPAllowList()) return false; + if (!InitHTTPAllowList()) { + return false; + } if (gArgs.GetBoolArg("-rpcssl", false)) { uiInterface.ThreadSafeMessageBox( @@ -388,18 +387,13 @@ evthread_use_pthreads(); #endif - // XXX RAII: Create a new event_base for Libevent use - base = event_base_new(); - if (!base) { - LogPrintf("Couldn't create an event_base: exiting\n"); - return false; - } + raii_event_base base_ctr = obtain_event_base(); - // XXX RAII: Create a new evhttp object to handle requests - http = evhttp_new(base); + /* Create a new evhttp object to handle requests. */ + raii_evhttp http_ctr = obtain_evhttp(base_ctr.get()); + struct evhttp *http = http_ctr.get(); if (!http) { LogPrintf("couldn't create evhttp. Exiting.\n"); - event_base_free(base); return false; } @@ -418,8 +412,6 @@ if (!HTTPBindAddresses(http)) { LogPrintf("Unable to bind any endpoint for RPC server\n"); - evhttp_free(http); - event_base_free(base); return false; } @@ -429,8 +421,9 @@ LogPrintf("HTTP: creating work queue of depth %d\n", workQueueDepth); workQueue = new WorkQueue(workQueueDepth); - eventBase = base; - eventHTTP = http; + // tranfer ownership to eventBase/HTTP via .release() + eventBase = base_ctr.release(); + eventHTTP = http_ctr.release(); return true; } diff --git a/src/support/events.h b/src/support/events.h --- a/src/support/events.h +++ b/src/support/events.h @@ -25,32 +25,36 @@ MAKE_RAII(evhttp_request); MAKE_RAII(evhttp_connection); -raii_event_base obtain_event_base() { +inline raii_event_base obtain_event_base() { auto result = raii_event_base(event_base_new()); - if (!result.get()) throw std::runtime_error("cannot create event_base"); + if (!result.get()) { + throw std::runtime_error("cannot create event_base"); + } return result; } -raii_event obtain_event(struct event_base *base, evutil_socket_t s, - short events, event_callback_fn cb, void *arg) { +inline raii_event obtain_event(struct event_base *base, evutil_socket_t s, + short events, event_callback_fn cb, void *arg) { return raii_event(event_new(base, s, events, cb, arg)); } -raii_evhttp obtain_evhttp(struct event_base *base) { +inline raii_evhttp obtain_evhttp(struct event_base *base) { return raii_evhttp(evhttp_new(base)); } -raii_evhttp_request +inline raii_evhttp_request obtain_evhttp_request(void (*cb)(struct evhttp_request *, void *), void *arg) { return raii_evhttp_request(evhttp_request_new(cb, arg)); } -raii_evhttp_connection obtain_evhttp_connection_base(struct event_base *base, - std::string host, - uint16_t port) { +inline raii_evhttp_connection +obtain_evhttp_connection_base(struct event_base *base, std::string host, + uint16_t port) { auto result = raii_evhttp_connection( evhttp_connection_base_new(base, nullptr, host.c_str(), port)); - if (!result.get()) throw std::runtime_error("create connection failed"); + if (!result.get()) { + throw std::runtime_error("create connection failed"); + } return result; }