Commit 15640015 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Address memory leak from Curl

parent 772db6b7
...@@ -20,10 +20,10 @@ ...@@ -20,10 +20,10 @@
################################################################################ ################################################################################
include_directories(${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/common/utils) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/utils)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
include_directories(${SRC_TOP_DIR}/common)
include_directories(${SRC_TOP_DIR}/../build/ext/spdlog/include) include_directories(${SRC_TOP_DIR}/../build/ext/spdlog/include)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
add_library(3GPP_COMMON_TYPES STATIC add_library(3GPP_COMMON_TYPES STATIC
${CMAKE_CURRENT_SOURCE_DIR}/logger.cpp ${CMAKE_CURRENT_SOURCE_DIR}/logger.cpp
......
...@@ -19,12 +19,12 @@ ...@@ -19,12 +19,12 @@
# contact@openairinterface.org # contact@openairinterface.org
################################################################################ ################################################################################
include_directories(${SRC_TOP_DIR}/../build/ext/spdlog/include) include_directories(${SRC_TOP_DIR}/../build/ext/spdlog/include)
include_directories(${SRC_TOP_DIR}/api-server/api) include_directories(${SRC_TOP_DIR}/api-server/api)
include_directories(${SRC_TOP_DIR}/api-server/impl) include_directories(${SRC_TOP_DIR}/api-server/impl)
include_directories(${SRC_TOP_DIR}/api-server/model) include_directories(${SRC_TOP_DIR}/api-server/model)
include_directories(${SRC_TOP_DIR}/api-server/) include_directories(${SRC_TOP_DIR}/api-server/)
include_directories(${SRC_TOP_DIR}/common/)
add_library (NRF STATIC add_library (NRF STATIC
nrf_app.cpp nrf_app.cpp
......
...@@ -125,6 +125,7 @@ void nrf_app::handle_register_nf_instance( ...@@ -125,6 +125,7 @@ void nrf_app::handle_register_nf_instance(
// Notify NF status change event // Notify NF status change event
m_event_sub.nf_status_registered(nf_instance_id); // from nrf_app m_event_sub.nf_status_registered(nf_instance_id); // from nrf_app
//m_event_sub.nf_status_change(sn); // from nrf_app
// display the info // display the info
sn.get()->display(); sn.get()->display();
...@@ -327,7 +328,7 @@ void nrf_app::handle_create_subscription( ...@@ -327,7 +328,7 @@ void nrf_app::handle_create_subscription(
// subscribe to NF status registered // subscribe to NF status registered
// subscribe_nf_status(evsub_id); // from nrf_app // subscribe_nf_status(evsub_id); // from nrf_app
// subscribe to NF status change // subscribe to NF status change
// ss.get()->subscribe_nf_status_change(); //from subscription ss.get()->subscribe_nf_status_registered(); //from subscription
// add to the DB // add to the DB
add_subscription(evsub_id, ss); add_subscription(evsub_id, ss);
Logger::nrf_app().debug("Added a subscription to the DB"); Logger::nrf_app().debug("Added a subscription to the DB");
......
...@@ -44,6 +44,7 @@ using json = nlohmann::json; ...@@ -44,6 +44,7 @@ using json = nlohmann::json;
extern nrf_client *nrf_client_inst; extern nrf_client *nrf_client_inst;
//------------------------------------------------------------------------------
// To read content of the response from NF // To read content of the response from NF
static std::size_t callback(const char *in, std::size_t size, std::size_t num, static std::size_t callback(const char *in, std::size_t size, std::size_t num,
std::string *out) { std::string *out) {
...@@ -52,6 +53,7 @@ static std::size_t callback(const char *in, std::size_t size, std::size_t num, ...@@ -52,6 +53,7 @@ static std::size_t callback(const char *in, std::size_t size, std::size_t num,
return totalBytes; return totalBytes;
} }
//------------------------------------------------------------------------------
CURL *nrf_client::curl_create_handle(const std::string &uri, CURL *nrf_client::curl_create_handle(const std::string &uri,
std::string *httpData) { std::string *httpData) {
// create handle for a curl request // create handle for a curl request
...@@ -77,25 +79,27 @@ CURL *nrf_client::curl_create_handle(const std::string &uri, ...@@ -77,25 +79,27 @@ CURL *nrf_client::curl_create_handle(const std::string &uri,
return curl; return curl;
} }
//------------------------------------------------------------------------------
void nrf_client::notify_subscribed_event( void nrf_client::notify_subscribed_event(
const std::shared_ptr<nrf_profile> &profile, const std::shared_ptr<nrf_profile> &profile,
const std::vector<std::string> &uris) { const std::vector<std::string> &uris) {
Logger::nrf_app().debug( Logger::nrf_app().debug(
"Send notification for the subscribed event to the subscription"); "Send notification for the subscribed event to the subscriptions");
int still_running = 0, numfds = 0, res = 0; int still_running = 0, numfds = 0, res = 0, msgs_left = 0;
CURLMsg *curl_msg = nullptr; CURLMsg *curl_msg = nullptr;
CURL *curl = nullptr; CURL *curl = nullptr;
CURLcode return_code = {}; CURLcode return_code = {};
int http_status_code = 0, msgs_left = 0; int http_status_code = 0;
int index = 0;
CURLM *m_curl_multi = nullptr; CURLM *m_curl_multi = nullptr;
char *url = nullptr; char *curl_url = nullptr;
std::vector<CURL *> handles;
std::unique_ptr<std::string> httpData(new std::string()); std::unique_ptr<std::string> httpData(new std::string());
std::string data;
curl_global_init(CURL_GLOBAL_ALL); curl_global_init(CURL_GLOBAL_ALL);
m_curl_multi = curl_multi_init(); m_curl_multi = curl_multi_init();
// init header // init header
struct curl_slist *headers = NULL; struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Accept: application/json"); headers = curl_slist_append(headers, "Accept: application/json");
...@@ -108,16 +112,14 @@ void nrf_client::notify_subscribed_event( ...@@ -108,16 +112,14 @@ void nrf_client::notify_subscribed_event(
json_data["nfInstanceUri"] = profile.get()->get_nf_instance_id(); json_data["nfInstanceUri"] = profile.get()->get_nf_instance_id();
std::string body = json_data.dump(); std::string body = json_data.dump();
int index = 0;
// create and add an easy handle to a multi curl request // create and add an easy handle to a multi curl request
for (auto i : uris) { for (auto uri : uris) {
CURL *curl = curl_easy_init(); curl = curl_easy_init();
if (curl) { if (curl) {
std::string url = i;
Logger::nrf_app().debug("Send notification to NF with URI: %s", Logger::nrf_app().debug("Send notification to NF with URI: %s",
url.c_str()); uri.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_URL, uri.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPPOST, 1); curl_easy_setopt(curl, CURLOPT_HTTPPOST, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L); curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
// Hook up data handling function. // Hook up data handling function.
...@@ -129,6 +131,7 @@ void nrf_client::notify_subscribed_event( ...@@ -129,6 +131,7 @@ void nrf_client::notify_subscribed_event(
} }
curl_multi_add_handle(m_curl_multi, curl); curl_multi_add_handle(m_curl_multi, curl);
index++; index++;
handles.push_back(curl);
} }
curl_multi_perform(m_curl_multi, &still_running); curl_multi_perform(m_curl_multi, &still_running);
...@@ -145,10 +148,11 @@ void nrf_client::notify_subscribed_event( ...@@ -145,10 +148,11 @@ void nrf_client::notify_subscribed_event(
// process multiple curl // process multiple curl
// read the messages // read the messages
while ((curl_msg = curl_multi_info_read(m_curl_multi, &msgs_left))) { while ((curl_msg = curl_multi_info_read(m_curl_multi, &msgs_left))) {
Logger::nrf_app().debug("Process message for multiple curl");
if (curl_msg->msg == CURLMSG_DONE) { if (curl_msg->msg == CURLMSG_DONE) {
curl = curl_msg->easy_handle; curl = curl_msg->easy_handle;
return_code = curl_msg->data.result; return_code = curl_msg->data.result;
res = curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url); res = curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &curl_url);
if (return_code != CURLE_OK) { if (return_code != CURLE_OK) {
Logger::nrf_app().debug("CURL error code %d!", curl_msg->data.result); Logger::nrf_app().debug("CURL error code %d!", curl_msg->data.result);
...@@ -158,14 +162,33 @@ void nrf_client::notify_subscribed_event( ...@@ -158,14 +162,33 @@ void nrf_client::notify_subscribed_event(
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status_code); curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status_code);
Logger::nrf_app().debug("HTTP status code %d!", http_status_code); Logger::nrf_app().debug("HTTP status code %d!", http_status_code);
// remove this handle from the multi session and end this handle // TODO: remove handle from the multi session and end this handle now, or
// later
curl_multi_remove_handle(m_curl_multi, curl); curl_multi_remove_handle(m_curl_multi, curl);
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
std::vector<CURL *>::iterator it;
it = find(handles.begin(), handles.end(), curl);
if (it != handles.end()) {
handles.erase(it);
index--;
Logger::nrf_app().debug("Erase curl handle");
}
} else { } else {
Logger::nrf_app().debug("Error after curl_multi_info_read(), CURLMsg %s", Logger::nrf_app().debug("Error after curl_multi_info_read(), CURLMsg %s",
curl_msg->msg); curl_msg->msg);
} }
} }
// Remove handle, free memory
for (int i = 0; i < index; i++) {
curl_multi_remove_handle(m_curl_multi, handles[i]);
curl_easy_cleanup(handles[i]);
}
curl_multi_cleanup(m_curl_multi);
curl_global_cleanup();
curl_slist_free_all(headers);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
......
...@@ -84,19 +84,19 @@ void nrf_subscription::display() { ...@@ -84,19 +84,19 @@ void nrf_subscription::display() {
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void nrf_subscription::subscribe_nf_status_change() { void nrf_subscription::subscribe_nf_status_registered() {
Logger::nrf_app().debug("Subscribe to NF status change event"); Logger::nrf_app().debug("Subscribe to NF status change event");
ev_connection = m_event_sub.subscribe_nf_status_change( ev_connection = m_event_sub.subscribe_nf_status_change( //TODO: To be updated
boost::bind(&nrf_subscription::handle_nf_status_change, this, _1)); boost::bind(&nrf_subscription::handle_nf_status_registered, this, _1));
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void nrf_subscription::handle_nf_status_change( void nrf_subscription::handle_nf_status_registered(
const std::shared_ptr<nrf_profile> &profile) { const std::shared_ptr<nrf_profile> &profile) {
std::string nf_instance_id; std::string nf_instance_id;
profile.get()->get_nf_instance_id(nf_instance_id); profile.get()->get_nf_instance_id(nf_instance_id);
Logger::nrf_app().info( Logger::nrf_app().info(
"Handle NF status change (subscription ID %s), profile ID %s", "Handle NF status registered (subscription ID %s), profile ID %s",
subscription_id.c_str(), nf_instance_id.c_str()); subscription_id.c_str(), nf_instance_id.c_str());
// TODO: // TODO:
nlohmann::json notification_data = {}; nlohmann::json notification_data = {};
......
...@@ -63,8 +63,8 @@ class nrf_subscription { ...@@ -63,8 +63,8 @@ class nrf_subscription {
void get_sub_condition(subscription_condition_t &c) const; void get_sub_condition(subscription_condition_t &c) const;
// subscription_condition_t get_sub_condition() const; // subscription_condition_t get_sub_condition() const;
void subscribe_nf_status_change(); void subscribe_nf_status_registered();
void handle_nf_status_change(const std::shared_ptr<nrf_profile> &profile); void handle_nf_status_registered(const std::shared_ptr<nrf_profile> &profile);
private: private:
std::string nf_status_notification_uri; std::string nf_status_notification_uri;
std::string subscription_id; std::string subscription_id;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment