Commit ae1957d9 authored by François Grisez's avatar François Grisez

Fix memory leaks in presence-longterm.cc

parent ff51900e
Pipeline #2432 passed with stages
in 54 minutes and 30 seconds
......@@ -320,7 +320,7 @@ void SociAuthDB::getUserWithPhoneWithPool(const string &phone, const string &dom
if (sql) delete sql;
}
void SociAuthDB::getUsersWithPhonesWithPool(list<tuple<string, string,AuthDbListener*>> &creds, AuthDbListener *listener) {
void SociAuthDB::getUsersWithPhonesWithPool(list<tuple<string, string,AuthDbListener*>> &creds) {
steady_clock::time_point start;
steady_clock::time_point stop;
set<pair<string, string>> presences;
......@@ -384,14 +384,14 @@ void SociAuthDB::getUsersWithPhonesWithPool(list<tuple<string, string,AuthDbList
}
}
if (listener)
listener->onResults(phones, presences);
notifyAllListeners(creds, presences);
} catch (mysql_soci_error const &e) {
stop = steady_clock::now();
SLOGE << "[SOCI] getUsersWithPhonesWithPool MySQL error after " << DURATION_MS(start, stop) << "ms : " << e.err_num_ << " " << e.what();
SLOGE << "[SOCI] MySQL request causing the error was : " << s;
presences.clear();
if (listener) listener->onResults(phones, presences);
notifyAllListeners(creds, presences);
if (sql) reconnectSession(*sql);
......@@ -399,12 +399,28 @@ void SociAuthDB::getUsersWithPhonesWithPool(list<tuple<string, string,AuthDbList
stop = steady_clock::now();
SLOGE << "[SOCI] getUsersWithPhonesWithPool error after " << DURATION_MS(start, stop) << "ms : " << e.what();
presences.clear();
if (listener) listener->onResults(phones, presences);
notifyAllListeners(creds, presences);
if (sql) reconnectSession(*sql);
}
if (sql) delete sql;
}
void SociAuthDB::notifyAllListeners(std::list<std::tuple<std::string, std::string, AuthDbListener *>> &creds, const std::set<std::pair<std::string, std::string>> &presences) {
for(const auto &cred : creds) {
const string &phone = std::get<0>(cred);
AuthDbListener *listener = std::get<2>(cred);
auto presence = find_if(presences.cbegin(), presences.cend(),
[&phone](const pair<string, string> &p){return p.second == phone;}
);
if (presence != presences.cend()) {
// mDInfo[presence->first] = mDInfo[phone];
if (listener) listener->onResult(PASSWORD_FOUND, presence->first);
} else {
if (listener) listener->onResult(PASSWORD_NOT_FOUND, phone);
}
}
}
#ifdef __clang__
#pragma mark - Inherited virtuals
#endif
......@@ -437,15 +453,18 @@ void SociAuthDB::getUserWithPhoneFromBackend(const string &phone, const string &
}
}
void SociAuthDB::getUsersWithPhonesFromBackend(list<tuple<string, string, AuthDbListener*>> &creds, AuthDbListener *listener) {
void SociAuthDB::getUsersWithPhonesFromBackend(list<tuple<string, string, AuthDbListener*>> &creds) {
// create a thread to grab a pool connection and use it to retrieve the auth information
auto func = bind(&SociAuthDB::getUsersWithPhonesWithPool, this, creds, listener);
auto func = bind(&SociAuthDB::getUsersWithPhonesWithPool, this, creds);
bool success = thread_pool->Enqueue(func);
if (success == FALSE) {
// Enqueue() can fail when the queue is full, so we have to act on that
SLOGE << "[SOCI] Auth queue is full, cannot fullfil user request for " << &creds;
if (listener) listener->onResult(AUTH_ERROR, "");
for (const auto &cred : creds) {
AuthDbListener *listener = std::get<2>(cred);
if (listener) listener->onResult(AUTH_ERROR, "");
}
}
}
......@@ -27,10 +27,6 @@ unique_ptr<AuthDbBackend> AuthDbBackend::sUnique;
AuthDbListener::~AuthDbListener(){
}
void AuthDbListener::onResults(const list<string> &phones, const set<pair<string, string>> &presences) {
}
class FixedAuthDb : public AuthDbBackend {
public:
FixedAuthDb() {
......@@ -288,7 +284,7 @@ void AuthDbBackend::getUserWithPhone(const string & phone, const string & domain
getUserWithPhoneFromBackend(phone, domain, listener);
}
void AuthDbBackend::getUsersWithPhone(list<tuple<string,string,AuthDbListener*>> & creds, AuthDbListener *listener) {
void AuthDbBackend::getUsersWithPhone(list<tuple<string,string,AuthDbListener*>> & creds) {
list<tuple<string,string,AuthDbListener*>> needed_creds;
for (tuple<string,string,AuthDbListener*> cred : creds) {
// Check for usable cached password
......@@ -308,10 +304,10 @@ void AuthDbBackend::getUsersWithPhone(list<tuple<string,string,AuthDbListener*>>
}
// if we reach here, password wasn't cached: we have to grab the password from the actual backend
getUsersWithPhonesFromBackend(needed_creds, listener);
getUsersWithPhonesFromBackend(needed_creds);
}
void AuthDbBackend::getUsersWithPhonesFromBackend(list<tuple<string,string,AuthDbListener*>> &creds, AuthDbListener *listener) {
void AuthDbBackend::getUsersWithPhonesFromBackend(list<tuple<string,string,AuthDbListener*>> &creds) {
for(tuple<string,string,AuthDbListener*> cred : creds) {
string phone = std::get<0>(cred);
string domain = std::get<1>(cred);
......
......@@ -58,7 +58,6 @@ class AuthDbListener : public StatFinishListener {
public:
virtual void onResult(AuthDbResult result, const std::string &passwd) = 0;
virtual void onResult(AuthDbResult result, const std::vector<passwd_algo_t> &passwd)=0;
virtual void onResults(const std::list<std::string> &phones, const std::set<std::pair<std::string, std::string>> &presences);
virtual void finishVerifyAlgos(const std::vector<passwd_algo_t> &pass)=0;
virtual ~AuthDbListener();
};
......@@ -97,9 +96,9 @@ public:
void getPasswordForAlgo(const std::string &user, const std::string &host, const std::string &auth_username,
AuthDbListener *listener, AuthDbListener *listener_ref);
void getUserWithPhone(const std::string &phone, const std::string &domain, AuthDbListener *listener);
void getUsersWithPhone(std::list<std::tuple<std::string, std::string, AuthDbListener *>> &creds, AuthDbListener *listener);
void getUsersWithPhone(std::list<std::tuple<std::string, std::string, AuthDbListener *>> &creds);
virtual void getUserWithPhoneFromBackend(const std::string &, const std::string &, AuthDbListener *listener) = 0;
virtual void getUsersWithPhonesFromBackend(std::list<std::tuple<std::string, std::string, AuthDbListener *>> &creds, AuthDbListener *listener);
virtual void getUsersWithPhonesFromBackend(std::list<std::tuple<std::string, std::string, AuthDbListener *>> &creds);
virtual void createAccount(const std::string &user, const std::string &domain, const std::string &auth_username, const std::string &password, int expires, const std::string &phone_alias = "");
......@@ -299,7 +298,7 @@ public:
SociAuthDB();
void setConnectionParameters(const std::string &domain, const std::string &request);
virtual void getUserWithPhoneFromBackend(const std::string & , const std::string &, AuthDbListener *listener);
virtual void getUsersWithPhonesFromBackend(std::list<std::tuple<std::string,std::string,AuthDbListener*>> &creds, AuthDbListener *listener);
virtual void getUsersWithPhonesFromBackend(std::list<std::tuple<std::string,std::string,AuthDbListener*>> &creds);
virtual void getPasswordFromBackend(const std::string &id, const std::string &domain,
const std::string &authid, AuthDbListener *listener, AuthDbListener *listener_ref);
......@@ -307,11 +306,12 @@ public:
private:
void getUserWithPhoneWithPool(const std::string &phone, const std::string &domain, AuthDbListener *listener);
void getUsersWithPhonesWithPool(std::list<std::tuple<std::string,std::string,AuthDbListener*>> &creds, AuthDbListener *listener);
void getUsersWithPhonesWithPool(std::list<std::tuple<std::string,std::string,AuthDbListener*>> &creds);
void getPasswordWithPool(const std::string &id, const std::string &domain,
const std::string &authid, AuthDbListener *listener, AuthDbListener *listener_ref);
void reconnectSession( soci::session &session );
void notifyAllListeners(std::list<std::tuple<std::string, std::string, AuthDbListener *>> &creds, const std::set<std::pair<std::string, std::string>> &presences);
size_t poolSize;
......
......@@ -17,7 +17,7 @@ public:
AuthDbBackend::get(); /*this will initialize the database backend, which is good to know that it works at startup*/
}
virtual void onResult(AuthDbResult result, const std::string &passwd) {
void onResult(AuthDbResult result, const std::string &passwd) override {
belle_sip_source_cpp_func_t *func = new belle_sip_source_cpp_func_t([this, result, passwd](unsigned int events) {
processResponse(result, passwd);
return BELLE_SIP_STOP;
......@@ -29,7 +29,7 @@ public:
belle_sip_object_unref(timer);
}
virtual void onResult(AuthDbResult result, const vector<passwd_algo_t> &passwd) {
void onResult(AuthDbResult result, const vector<passwd_algo_t> &passwd) override {
belle_sip_source_cpp_func_t *func = new belle_sip_source_cpp_func_t([this, result, passwd](unsigned int events) {
processResponse(result, passwd.front().pass);
return BELLE_SIP_STOP;
......@@ -41,34 +41,11 @@ public:
belle_sip_object_unref(timer);
}
virtual void finishVerifyAlgos(const vector<passwd_algo_t> &pass) {
return;
}
void onResults(const list<string> &phones, const set<pair<string, string>> &presences) {
for(const string &phone : phones) {
if(presences.empty()) {
onResult(PASSWORD_NOT_FOUND, phone);
continue;
}
bool found = false;
for (const auto &presence : presences) {
if (presence.second == phone) {
mDInfo[presence.first] = mDInfo[phone];
onResult(PASSWORD_FOUND, presence.first);
found = true;
break;
}
}
if (!found)
onResult(PASSWORD_NOT_FOUND, phone);
}
}
void finishVerifyAlgos(const vector<passwd_algo_t> &pass) override {}
private:
void processResponse(AuthDbResult result, const std::string &user) {
shared_ptr<PresentityPresenceInformation> info = mInfo ? mInfo : mDInfo.find(user)->second;
bool must_delete = !!mInfo;
const char *cuser = belle_sip_uri_get_user(info->getEntity());
if (result == AuthDbResult::PASSWORD_FOUND) {
......@@ -93,9 +70,7 @@ private:
} else {
SLOGD << __FILE__ << ": " << "Could not find user " << cuser << ".";
}
if(must_delete) {
delete this;
}
delete this;
}
belle_sip_main_loop_t *mMainLoop;
......@@ -122,5 +97,5 @@ void PresenceLongterm::onListenerEvents(list<shared_ptr<PresentityPresenceInform
}
dInfo.insert(pair<string, shared_ptr<PresentityPresenceInformation>>(belle_sip_uri_get_user(info->getEntity()), info));
}
AuthDbBackend::get().getUsersWithPhone(creds, new PresenceAuthListener(mMainLoop, dInfo));
AuthDbBackend::get().getUsersWithPhone(creds);
}
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