Skip to content
Browse files

Convert LoggingItem to use ReferenceCounter

This gets rid of the deleteLater() which removes the nasty memory growth
issues in various threads that don't use the full Qt event loop.

Also converted mthreadpool processEvents/sendPostedEvents to use qApp->
rather than QCoreApplication::  QCoreApplication:: is specifically for console
apps, which made mythfrontend grow like crazy as it did not effect it.
  • Loading branch information...
1 parent c2883d0 commit 4b07742e8af6f18e1b353f1f866211e9331f4c4b @Beirdo Beirdo committed Jun 29, 2012
View
74 mythtv/libs/libmythbase/logging.cpp
@@ -136,13 +136,15 @@ void loggingGetTimeStamp(qlonglong *epoch, uint *usec)
#endif
}
-LoggingItem::LoggingItem() : m_file(NULL), m_function(NULL), m_threadName(NULL),
- m_appName(NULL), m_table(NULL), m_logFile(NULL)
+LoggingItem::LoggingItem() : ReferenceCounter("LoggingItem"), m_file(NULL),
+ m_function(NULL), m_threadName(NULL), m_appName(NULL), m_table(NULL),
+ m_logFile(NULL)
{
}
LoggingItem::LoggingItem(const char *_file, const char *_function,
int _line, LogLevel_t _level, LoggingType _type) :
+ ReferenceCounter("LoggingItem"),
m_threadId((uint64_t)(QThread::currentThreadId())),
m_line(_line), m_type(_type), m_level(_level),
m_file(strdup(_file)), m_function(strdup(_function)),
@@ -153,7 +155,6 @@ LoggingItem::LoggingItem(const char *_file, const char *_function,
m_message[0]='\0';
m_message[LOGLINE_MAX]='\0';
setThreadTid();
- refcount.ref();
}
LoggingItem::~LoggingItem()
@@ -373,7 +374,7 @@ void LoggerThread::run(void)
fillItem(item);
handleItem(item);
logConsole(item);
- item->deleteItem();
+ item->DecrRef();
qLock.relock();
}
@@ -559,7 +560,7 @@ bool LoggerThread::logConsole(LoggingItem *item)
if (!(item->m_type & kMessage))
return false;
- item->refcount.ref();
+ item->IncrRef();
if (item->m_type & kStandardIO)
snprintf( line, MAX_STRING_LENGTH, "%s", item->m_message );
@@ -591,7 +592,7 @@ bool LoggerThread::logConsole(LoggingItem *item)
int result = write( 1, line, strlen(line) );
(void)result;
- item->deleteItem();
+ item->DecrRef();
return true;
}
@@ -637,14 +638,6 @@ void LoggerThread::fillItem(LoggingItem *item)
item->setFacility(m_facility);
}
-static QAtomicInt item_count;
-static QAtomicInt malloc_count;
-
-#define DEBUG_MEMORY 0
-#if DEBUG_MEMORY
-static int max_count = 0;
-static QTime memory_time;
-#endif
/// \brief Create a new LoggingItem
/// \param _file filename of the source file where the log message is from
@@ -660,26 +653,6 @@ LoggingItem *LoggingItem::create(const char *_file,
{
LoggingItem *item = new LoggingItem(_file, _function, _line, _level, _type);
- malloc_count.ref();
-
-#if DEBUG_MEMORY
- int val = item_count.fetchAndAddRelaxed(1) + 1;
- if (val == 0)
- memory_time.start();
- max_count = (val > max_count) ? val : max_count;
- if (memory_time.elapsed() > 1000)
- {
- cout<<"current memory usage: "
- <<val<<" * "<<sizeof(LoggingItem)<<endl;
- cout<<"max memory usage: "
- <<max_count<<" * "<<sizeof(LoggingItem)<<endl;
- cout<<"malloc count: "<<(int)malloc_count<<endl;
- memory_time.start();
- }
-#else
- item_count.ref();
-#endif
-
return item;
}
@@ -692,40 +665,9 @@ LoggingItem *LoggingItem::create(QByteArray &buf)
LoggingItem *item = new LoggingItem;
QJson::QObjectHelper::qvariant2qobject(variant.toMap(), item);
- malloc_count.ref();
-
-#if DEBUG_MEMORY
- int val = item_count.fetchAndAddRelaxed(1) + 1;
- if (val == 0)
- memory_time.start();
- max_count = (val > max_count) ? val : max_count;
- if (memory_time.elapsed() > 1000)
- {
- cout<<"current memory usage: "
- <<val<<" * "<<sizeof(LoggingItem)<<endl;
- cout<<"max memory usage: "
- <<max_count<<" * "<<sizeof(LoggingItem)<<endl;
- cout<<"malloc count: "<<(int)malloc_count<<endl;
- memory_time.start();
- }
-#else
- item_count.ref();
-#endif
-
return item;
}
-/// \brief Delete the LoggingItem once its reference count has run down
-/// \param item LoggingItem to delete.
-void LoggingItem::deleteItem(void)
-{
- if (!refcount.deref())
- {
- item_count.deref();
- this->deleteLater();
- }
-}
-
/// \brief Format and send a log message into the queue. This is called from
/// the LOG() macro. The intention is minimal blocking of the caller.
@@ -780,7 +722,7 @@ void LogPrintLine( uint64_t mask, LogLevel_t level, const char *file, int line,
qLock.unlock();
logThread->handleItem(item);
logThread->logConsole(item);
- item->deleteItem();
+ item->DecrRef();
qLock.relock();
}
}
View
6 mythtv/libs/libmythbase/logging.h
@@ -15,6 +15,7 @@
#include "verbosedefs.h"
#include "mythsignalingtimer.h"
#include "mthread.h"
+#include "referencecounter.h"
#include "nzmqt.hpp"
#define LOGLINE_MAX (2048-120)
@@ -44,7 +45,7 @@ typedef struct tm tmType;
/// \brief The logging items that are generated by LOG() and are sent to the
/// console and to mythlogserver via ZeroMQ
-class LoggingItem: public QObject
+class LoggingItem: public QObject, public ReferenceCounter
{
Q_OBJECT
@@ -76,11 +77,8 @@ class LoggingItem: public QObject
static LoggingItem *create(const char *, const char *, int, LogLevel_t,
LoggingType);
static LoggingItem *create(QByteArray &buf);
- void deleteItem(void);
QByteArray toByteArray(void);
- QAtomicInt refcount;
-
int pid() const { return m_pid; };
qlonglong tid() const { return m_tid; };
qulonglong threadId() const { return m_threadId; };
View
37 mythtv/libs/libmythbase/loggingserver.cpp
@@ -206,8 +206,6 @@ bool FileLogger::logmsg(LoggingItem *item)
if (!m_opened)
return false;
- item->refcount.ref();
-
time_t epoch = item->epoch();
struct tm tm;
localtime_r(&epoch, &tm);
@@ -517,7 +515,6 @@ bool DatabaseLogger::logmsg(LoggingItem *item)
if (m_disabled)
return false;
- item->refcount.ref();
m_thread->enqueue(item);
return true;
}
@@ -586,7 +583,7 @@ bool DatabaseLogger::logqmsg(MSqlQuery &query, LoggingItem *item)
return false;
}
- item->deleteItem();
+ item->DecrRef();
return true;
}
@@ -665,7 +662,7 @@ DBLoggerThread::~DBLoggerThread()
QMutexLocker qLock(&m_queueMutex);
while (!m_queue->empty())
- m_queue->dequeue()->deleteItem();
+ m_queue->dequeue()->DecrRef();
delete m_queue;
delete m_wait;
m_queue = NULL;
@@ -710,13 +707,14 @@ void DBLoggerThread::run(void)
if (!item)
continue;
- qLock.unlock();
-
if (item->message()[0] != '\0')
{
- if (!m_logger->logqmsg(*query, item))
+ qLock.unlock();
+ bool logged = m_logger->logqmsg(*query, item);
+ qLock.relock();
+
+ if (!logged)
{
- qLock.relock();
m_queue->prepend(item);
m_wait->wait(qLock.mutex(), 100);
delete query;
@@ -725,17 +723,11 @@ void DBLoggerThread::run(void)
continue;
}
}
- else
- {
- item->deleteItem();
- }
- qLock.relock();
+ item->DecrRef();
}
delete query;
-
- qLock.unlock();
}
RunEpilog();
@@ -1003,7 +995,7 @@ void FileLogger::receivedMessage(const QList<QByteArray> &msg)
QByteArray json = msg.at(1);
LoggingItem *item = LoggingItem::create(json);
logmsg(item);
- item->deleteItem();
+ item->DecrRef();
}
#ifndef _WIN32
@@ -1024,7 +1016,7 @@ void SyslogLogger::receivedMessage(const QList<QByteArray> &msg)
QByteArray json = msg.at(1);
LoggingItem *item = LoggingItem::create(json);
logmsg(item);
- item->deleteItem();
+ item->DecrRef();
}
#else
@@ -1054,7 +1046,8 @@ void DatabaseLogger::receivedMessage(const QList<QByteArray> &msg)
QByteArray json = msg.at(1);
LoggingItem *item = LoggingItem::create(json);
- logmsg(item);
+ if (!logmsg(item))
+ item->DecrRef();
}
@@ -1101,6 +1094,7 @@ void LogForwardThread::run(void)
while (!m_aborted)
{
qApp->processEvents(QEventLoop::AllEvents, 10);
+ qApp->sendPostedEvents(NULL, QEvent::DeferredDelete);
{
QMutexLocker lock(&logMsgListMutex);
@@ -1122,7 +1116,10 @@ void LogForwardThread::run(void)
// Force a processEvents every 128 messages so a busy queue
// doesn't preclude timer notifications, etc.
if ((processed & 127) == 0)
+ {
qApp->processEvents(QEventLoop::AllEvents, 10);
+ qApp->sendPostedEvents(NULL, QEvent::DeferredDelete);
+ }
lock.relock();
}
@@ -1361,7 +1358,7 @@ void LogForwardThread::forwardMessage(LogMessage *msg)
logItem->list = loggers;
logClientMap.insert(clientId, logItem);
- item->deleteItem();
+ item->DecrRef();
}
m_zmqPubSock->sendMessage(*msg);
View
4 mythtv/libs/libmythbase/mthreadpool.cpp
@@ -96,8 +96,8 @@ class MPoolThread : public MThread
loggingRegisterThread(objectName());
GetMythDB()->GetDBManager()->PurgeIdleConnections(false);
- QCoreApplication::processEvents();
- QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ qApp->processEvents();
+ qApp->sendPostedEvents(NULL, QEvent::DeferredDelete);
t.start();

0 comments on commit 4b07742

Please sign in to comment.
Something went wrong with that request. Please try again.