Fix memory leak

This commit is contained in:
Alexander A. Klimov 2018-10-30 12:51:55 +01:00 committed by Michael Friedrich
parent 11d5415193
commit 74eccf60f2
2 changed files with 15 additions and 6 deletions

View File

@ -25,6 +25,7 @@
#include "icinga/checkable.hpp" #include "icinga/checkable.hpp"
#include "icinga/host.hpp" #include "icinga/host.hpp"
#include <memory>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <utility> #include <utility>
@ -189,7 +190,7 @@ void RedisWriter::UpdateSubscriptions()
bool RedisWriter::GetSubscriptionTypes(String key, RedisSubscriptionInfo& rsi) bool RedisWriter::GetSubscriptionTypes(String key, RedisSubscriptionInfo& rsi)
{ {
try { try {
redisReply *redisReply = RedisGet({ "SMEMBERS", key }); auto redisReply = RedisGet({ "SMEMBERS", key });
VERIFY(redisReply->type == REDIS_REPLY_ARRAY); VERIFY(redisReply->type == REDIS_REPLY_ARRAY);
if (redisReply->elements == 0) if (redisReply->elements == 0)
@ -280,11 +281,11 @@ void RedisWriter::HandleEvent(const Dictionary::Ptr& event)
String body = JsonEncode(event); String body = JsonEncode(event);
redisReply *maxExists = RedisGet({ "EXISTS", "icinga:subscription:" + name + ":limit" }); auto maxExists = RedisGet({ "EXISTS", "icinga:subscription:" + name + ":limit" });
long maxEvents = MAX_EVENTS_DEFAULT; long maxEvents = MAX_EVENTS_DEFAULT;
if (maxExists->integer) { if (maxExists->integer) {
redisReply *redisReply = RedisGet({ "GET", "icinga:subscription:" + name + ":limit"}); auto redisReply = RedisGet({ "GET", "icinga:subscription:" + name + ":limit"});
VERIFY(redisReply->type == REDIS_REPLY_STRING); VERIFY(redisReply->type == REDIS_REPLY_STRING);
Log(LogInformation, "RedisWriter") Log(LogInformation, "RedisWriter")
@ -399,8 +400,15 @@ void RedisWriter::RedisQueryCallback(redisAsyncContext *c, void *r, void *p) {
wait->cv.notify_all(); wait->cv.notify_all();
} }
struct RedisReplyDeleter
{
inline void operator() (redisReply *reply)
{
freeReplyObject(reply);
}
};
redisReply* RedisWriter::RedisGet(const std::vector<String>& query) { std::shared_ptr<redisReply> RedisWriter::RedisGet(const std::vector<String>& query) {
auto *wait = new synchronousWait; auto *wait = new synchronousWait;
wait->ready = false; wait->ready = false;
@ -413,5 +421,5 @@ redisReply* RedisWriter::RedisGet(const std::vector<String>& query) {
wait->ready = true; wait->ready = true;
} }
return wait->reply; return std::shared_ptr<redisReply>(wait->reply, RedisReplyDeleter());
} }

View File

@ -29,6 +29,7 @@
#include "icinga/checkable.hpp" #include "icinga/checkable.hpp"
#include "icinga/service.hpp" #include "icinga/service.hpp"
#include "icinga/downtime.hpp" #include "icinga/downtime.hpp"
#include <memory>
#include <hiredis/hiredis.h> #include <hiredis/hiredis.h>
namespace icinga namespace icinga
@ -114,7 +115,7 @@ private:
void ExceptionHandler(boost::exception_ptr exp); void ExceptionHandler(boost::exception_ptr exp);
//Used to get a reply from the asyncronous connection //Used to get a reply from the asyncronous connection
redisReply* RedisGet(const std::vector<String>& query); std::shared_ptr<redisReply> RedisGet(const std::vector<String>& query);
static void RedisQueryCallback(redisAsyncContext *c, void *r, void *p); static void RedisQueryCallback(redisAsyncContext *c, void *r, void *p);
static redisReply* dupReplyObject(redisReply* reply); static redisReply* dupReplyObject(redisReply* reply);