Fix a pile of actual memory leaks
Originally committed to SVN as r4575.
This commit is contained in:
parent
cbf201ab86
commit
2b47f34e76
8 changed files with 80 additions and 88 deletions
|
@ -21,6 +21,8 @@
|
||||||
#include "charset_ucd.h"
|
#include "charset_ucd.h"
|
||||||
|
|
||||||
#ifndef LAGI_PRE
|
#ifndef LAGI_PRE
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "../../universalchardet/nsCharSetProber.h"
|
#include "../../universalchardet/nsCharSetProber.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -31,8 +33,7 @@ namespace agi {
|
||||||
|
|
||||||
UCDetect::UCDetect(const std::string &file): nsUniversalDetector(NS_FILTER_ALL) {
|
UCDetect::UCDetect(const std::string &file): nsUniversalDetector(NS_FILTER_ALL) {
|
||||||
{
|
{
|
||||||
std::ifstream *fp;
|
std::auto_ptr<std::ifstream> fp(io::Open(file));
|
||||||
fp = io::Open(file);
|
|
||||||
|
|
||||||
while (!mDone && !fp->eof()) {
|
while (!mDone && !fp->eof()) {
|
||||||
char buf[512];
|
char buf[512];
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -40,99 +42,84 @@ std::auto_ptr<LogSink> log(new LogSink());
|
||||||
/// Keep this ordered the same as Severity
|
/// Keep this ordered the same as Severity
|
||||||
const char *Severity_ID = "EAWID";
|
const char *Severity_ID = "EAWID";
|
||||||
|
|
||||||
SinkMessage::SinkMessage(const char *section, Severity severity, const char *file,
|
SinkMessage::SinkMessage(const char *section, Severity severity,
|
||||||
const char *func, int line, agi_timeval tv):
|
const char *file, const char *func, int line,
|
||||||
section(section),
|
agi_timeval tv)
|
||||||
severity(severity),
|
: section(section)
|
||||||
file(file),
|
, severity(severity)
|
||||||
func(func),
|
, file(file)
|
||||||
line(line),
|
, func(func)
|
||||||
tv(tv) {
|
, line(line)
|
||||||
|
, tv(tv)
|
||||||
|
, message(NULL)
|
||||||
|
, len(0)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
SinkMessage::~SinkMessage() {
|
SinkMessage::~SinkMessage() {
|
||||||
///@todo Memory cleanup
|
delete message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LogSink::LogSink(): emit(0) {
|
LogSink::LogSink() {
|
||||||
sink = new Sink();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSink::~LogSink() {
|
LogSink::~LogSink() {
|
||||||
/// @todo This needs to flush all log data to disk on quit.
|
/// @todo This needs to flush all log data to disk on quit.
|
||||||
if (emit) {
|
agi::util::delete_clear(sink);
|
||||||
for (int i = emitters.size()-1; i >= 0; i--) {
|
|
||||||
delete emitters[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LogSink::log(SinkMessage *sm) {
|
void LogSink::log(SinkMessage *sm) {
|
||||||
sink->push_back(sm);
|
sink.push_back(sm);
|
||||||
|
|
||||||
if (emit) {
|
std::for_each(
|
||||||
for (int i = emitters.size()-1; i >= 0; i--) {
|
emitters.begin(),
|
||||||
emitters[i]->log(sm);
|
emitters.end(),
|
||||||
}
|
std::bind2nd(std::mem_fun(&Emitter::log), sm));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LogSink::Subscribe(Emitter *em) {
|
||||||
Emitter::~Emitter() {
|
emitters.push_back(em);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LogSink::Unsubscribe(Emitter *em) {
|
||||||
Emitter::Emitter() {
|
emitters.erase(std::remove(emitters.begin(), emitters.end(), em), emitters.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int LogSink::Subscribe(Emitter &em) {
|
|
||||||
emitters.push_back(&em);
|
|
||||||
emit = 1;
|
|
||||||
/// @todo This won't work since removing it will cause the id's to change,
|
|
||||||
/// it's good enough while this is being written.
|
|
||||||
return emitters.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LogSink::Unsubscribe(const int &id) {
|
|
||||||
emitters.erase((emitters.begin()-1)+id);
|
|
||||||
if (emitters.size() == 0)
|
|
||||||
emit = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Message::Message(const char *section,
|
Message::Message(const char *section,
|
||||||
Severity severity,
|
Severity severity,
|
||||||
const char *file,
|
const char *file,
|
||||||
const char *func,
|
const char *func,
|
||||||
int line):
|
int line)
|
||||||
len(1024) {
|
: len(1024)
|
||||||
buf = new char[len];
|
, buf(new char[len])
|
||||||
msg = new std::ostrstream(buf, len);
|
, msg(buf, len)
|
||||||
|
{
|
||||||
agi_timeval tv;
|
agi_timeval tv;
|
||||||
util::time_log(tv);
|
util::time_log(tv);
|
||||||
sm = new SinkMessage(section, severity, file, func, line, tv);
|
sm = new SinkMessage(section, severity, file, func, line, tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Message::~Message() {
|
Message::~Message() {
|
||||||
sm->message = msg->str();
|
sm->message = msg.str();
|
||||||
sm->len = msg->pcount();
|
sm->len = msg.pcount();
|
||||||
agi::log::log->log(sm);
|
agi::log::log->log(sm);
|
||||||
delete msg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Emitter::Emitter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
Emitter::~Emitter() {
|
||||||
|
Disable();
|
||||||
|
}
|
||||||
|
|
||||||
void Emitter::Enable() {
|
void Emitter::Enable() {
|
||||||
id = agi::log::log->Subscribe(*(this));
|
agi::log::log->Subscribe(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Emitter::Disable() {
|
void Emitter::Disable() {
|
||||||
agi::log::log->Unsubscribe(id);
|
agi::log::log->Unsubscribe(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "libaegisub/cajun/reader.h"
|
#include "libaegisub/cajun/reader.h"
|
||||||
#include "libaegisub/cajun/writer.h"
|
#include "libaegisub/cajun/writer.h"
|
||||||
|
@ -55,10 +56,10 @@ void Options::ConfigNext(std::istream& stream) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Options::ConfigUser() {
|
void Options::ConfigUser() {
|
||||||
std::istream *stream;
|
std::auto_ptr<std::istream> stream;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
stream = agi::io::Open(config_file);
|
stream.reset(agi::io::Open(config_file));
|
||||||
} catch (const acs::AcsNotFound&) {
|
} catch (const acs::AcsNotFound&) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +67,6 @@ void Options::ConfigUser() {
|
||||||
/// @todo Handle other errors such as parsing and notifying the user.
|
/// @todo Handle other errors such as parsing and notifying the user.
|
||||||
LoadConfig(*stream);
|
LoadConfig(*stream);
|
||||||
config_loaded = true;
|
config_loaded = true;
|
||||||
delete stream;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -77,11 +77,11 @@ struct SinkMessage {
|
||||||
/// @param file File name
|
/// @param file File name
|
||||||
/// @param func Function name
|
/// @param func Function name
|
||||||
/// @param line Source line
|
/// @param line Source line
|
||||||
/// @param tv Log time
|
/// @param tv Log time
|
||||||
SinkMessage(const char *section, Severity severity, const char *file,
|
SinkMessage(const char *section, Severity severity, const char *file,
|
||||||
const char *func, int line, agi_timeval tv);
|
const char *func, int line, agi_timeval tv);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
~SinkMessage();
|
~SinkMessage();
|
||||||
|
|
||||||
const char *section; ///< Section info eg "video/open" "video/seek" etc
|
const char *section; ///< Section info eg "video/open" "video/seek" etc
|
||||||
|
@ -105,14 +105,11 @@ class LogSink {
|
||||||
int64_t size;
|
int64_t size;
|
||||||
|
|
||||||
/// Log sink
|
/// Log sink
|
||||||
Sink *sink;
|
Sink sink;
|
||||||
|
|
||||||
/// List of function pointers to emitters
|
/// List of function pointers to emitters
|
||||||
std::vector<Emitter*> emitters;
|
std::vector<Emitter*> emitters;
|
||||||
|
|
||||||
/// Whether to enable emitters
|
|
||||||
bool emit;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
LogSink();
|
LogSink();
|
||||||
|
@ -124,24 +121,20 @@ public:
|
||||||
void log(SinkMessage *sm);
|
void log(SinkMessage *sm);
|
||||||
|
|
||||||
/// @brief Subscribe an emitter.
|
/// @brief Subscribe an emitter.
|
||||||
/// @param Function pointer to an emitter
|
/// @param em Emitter to add
|
||||||
/// @return ID for this Emitter
|
void Subscribe(Emitter *em);
|
||||||
int Subscribe(Emitter &em);
|
|
||||||
|
|
||||||
/// @brief Unsubscribe an emitter.
|
/// @brief Unsubscribe an emitter.
|
||||||
/// @param id ID to remove.
|
/// @param em Emitter to remove
|
||||||
void Unsubscribe(const int &id);
|
void Unsubscribe(Emitter *em);
|
||||||
|
|
||||||
/// @brief @get the complete (current) log.
|
/// @brief @get the complete (current) log.
|
||||||
/// @return Const pointer to internal sink.
|
/// @return Const pointer to internal sink.
|
||||||
const Sink* GetSink() { return sink; }
|
const Sink* GetSink() { return &sink; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An emitter to produce human readable output for a log sink.
|
/// An emitter to produce human readable output for a log sink.
|
||||||
class Emitter {
|
class Emitter {
|
||||||
/// ID for this emitter
|
|
||||||
int id;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
Emitter();
|
Emitter();
|
||||||
|
@ -162,9 +155,9 @@ public:
|
||||||
|
|
||||||
/// Generates a message and submits it to the log sink.
|
/// Generates a message and submits it to the log sink.
|
||||||
class Message {
|
class Message {
|
||||||
char *buf;
|
|
||||||
const int len;
|
const int len;
|
||||||
std::ostrstream *msg;
|
char *buf;
|
||||||
|
std::ostrstream msg;
|
||||||
SinkMessage *sm;
|
SinkMessage *sm;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -174,7 +167,7 @@ public:
|
||||||
const char *func,
|
const char *func,
|
||||||
int line);
|
int line);
|
||||||
~Message();
|
~Message();
|
||||||
std::ostream& stream() { return *(msg); }
|
std::ostream& stream() { return msg; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,5 +34,17 @@ namespace agi {
|
||||||
void Rename(const std::string& from, const std::string& to);
|
void Rename(const std::string& from, const std::string& to);
|
||||||
void time_log(agi_timeval &tv);
|
void time_log(agi_timeval &tv);
|
||||||
|
|
||||||
|
struct delete_ptr {
|
||||||
|
template<class T>
|
||||||
|
void operator()(T* ptr) const {
|
||||||
|
delete ptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<class T>
|
||||||
|
void delete_clear(T& container) {
|
||||||
|
std::for_each(container.begin(), container.end(), delete_ptr());
|
||||||
|
container.clear();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace util
|
} // namespace util
|
||||||
} // namespace agi
|
} // namespace agi
|
||||||
|
|
|
@ -37,7 +37,7 @@ void EmitSTDOUT::log(SinkMessage *sm) {
|
||||||
// tmtime.tm_mon,
|
// tmtime.tm_mon,
|
||||||
// tmtime.tm_mday,
|
// tmtime.tm_mday,
|
||||||
|
|
||||||
printf("%c %02d:%02d:%02d %ld <%-25s> [%s:%s:%d] %s\n",
|
printf("%c %02d:%02d:%02d %ld <%-25s> [%s:%s:%d] %.*s\n",
|
||||||
Severity_ID[sm->severity],
|
Severity_ID[sm->severity],
|
||||||
tmtime.tm_hour,
|
tmtime.tm_hour,
|
||||||
tmtime.tm_min,
|
tmtime.tm_min,
|
||||||
|
@ -47,8 +47,8 @@ void EmitSTDOUT::log(SinkMessage *sm) {
|
||||||
sm->file,
|
sm->file,
|
||||||
sm->func,
|
sm->func,
|
||||||
sm->line,
|
sm->line,
|
||||||
strndup(sm->message,
|
sm->len,
|
||||||
sm->len));
|
sm->message);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace log
|
} // namespace log
|
||||||
|
|
|
@ -30,15 +30,15 @@ namespace agi {
|
||||||
namespace log {
|
namespace log {
|
||||||
|
|
||||||
void EmitSTDOUT::log(SinkMessage *sm) {
|
void EmitSTDOUT::log(SinkMessage *sm) {
|
||||||
/*
|
|
||||||
tm tmtime;
|
tm tmtime;
|
||||||
localtime_r(&sm->tv.tv_sec, &tmtime);
|
time_t time = sm->tv.tv_sec;
|
||||||
|
localtime_s(&tmtime, &time);
|
||||||
|
|
||||||
// tmtime.tm_year+1900,
|
// tmtime.tm_year+1900,
|
||||||
// tmtime.tm_mon,
|
// tmtime.tm_mon,
|
||||||
// tmtime.tm_mday,
|
// tmtime.tm_mday,
|
||||||
|
|
||||||
printf("%c %02d:%02d:%02d %ld <%-25s> [%s:%s:%d] %s\n",
|
printf("%c %02d:%02d:%02d %ld <%-25s> [%s:%s:%d] %.*s\n",
|
||||||
Severity_ID[sm->severity],
|
Severity_ID[sm->severity],
|
||||||
tmtime.tm_hour,
|
tmtime.tm_hour,
|
||||||
tmtime.tm_min,
|
tmtime.tm_min,
|
||||||
|
@ -48,9 +48,8 @@ void EmitSTDOUT::log(SinkMessage *sm) {
|
||||||
sm->file,
|
sm->file,
|
||||||
sm->func,
|
sm->func,
|
||||||
sm->line,
|
sm->line,
|
||||||
strndup(sm->message,
|
sm->len,
|
||||||
sm->len));
|
sm->message);
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
} // namespace log
|
} // namespace log
|
||||||
} // namespace agi
|
} // namespace agi
|
||||||
|
|
|
@ -144,8 +144,8 @@ void SetThreadName(DWORD dwThreadID, LPCSTR szThreadName) {
|
||||||
///
|
///
|
||||||
bool AegisubApp::OnInit() {
|
bool AegisubApp::OnInit() {
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
agi::log::EmitSTDOUT *emit_stdout = new agi::log::EmitSTDOUT();
|
agi::log::EmitSTDOUT emit_stdout;
|
||||||
emit_stdout->Enable();
|
emit_stdout.Enable();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// App name (yeah, this is a little weird to get rid of an odd warning)
|
// App name (yeah, this is a little weird to get rid of an odd warning)
|
||||||
|
|
Loading…
Reference in a new issue