Made buffer thread wait until there is a GUI client #4721

Conflicts:
	src/lib/ipc/IpcLogOutputter.cpp
This commit is contained in:
Xinyu Hou 2015-07-13 11:00:10 +01:00 committed by Jerry (Xinyu Hou)
parent cc3dc315f9
commit afdcb9cefe
4 changed files with 20 additions and 19 deletions

View File

@ -37,7 +37,7 @@ enum EIpcLogOutputter {
kBufferRateTimeLimit = 1 // seconds kBufferRateTimeLimit = 1 // seconds
}; };
IpcLogOutputter::IpcLogOutputter(IpcServer& ipcServer, bool useThread) : IpcLogOutputter::IpcLogOutputter(IpcServer& ipcServer, EIpcClientType clientType, bool useThread) :
m_ipcServer(ipcServer), m_ipcServer(ipcServer),
m_bufferMutex(ARCH->newMutex()), m_bufferMutex(ARCH->newMutex()),
m_sending(false), m_sending(false),
@ -50,7 +50,8 @@ IpcLogOutputter::IpcLogOutputter(IpcServer& ipcServer, bool useThread) :
m_bufferRateWriteLimit(kBufferRateWriteLimit), m_bufferRateWriteLimit(kBufferRateWriteLimit),
m_bufferRateTimeLimit(kBufferRateTimeLimit), m_bufferRateTimeLimit(kBufferRateTimeLimit),
m_bufferWriteCount(0), m_bufferWriteCount(0),
m_bufferRateStart(ARCH->time()) m_bufferRateStart(ARCH->time()),
m_clientType(clientType)
{ {
if (useThread) { if (useThread) {
m_bufferThread = new Thread(new TMethodJob<IpcLogOutputter>( m_bufferThread = new Thread(new TMethodJob<IpcLogOutputter>(
@ -102,7 +103,9 @@ IpcLogOutputter::write(ELevel, const char* text)
} }
appendBuffer(text); appendBuffer(text);
notifyBuffer(); if (m_ipcServer.hasClients(m_clientType)) {
notifyBuffer();
}
return true; return true;
} }
@ -141,7 +144,7 @@ IpcLogOutputter::bufferThread(void*)
try { try {
while (m_running) { while (m_running) {
if (m_buffer.empty()) { if (m_buffer.empty() || !m_ipcServer.hasClients(m_clientType)) {
ArchMutexLock lock(m_notifyMutex); ArchMutexLock lock(m_notifyMutex);
ARCH->waitCondVar(m_notifyCond, m_notifyMutex, -1); ARCH->waitCondVar(m_notifyCond, m_notifyMutex, -1);
} }
@ -184,10 +187,7 @@ IpcLogOutputter::getChunk(size_t count)
void void
IpcLogOutputter::sendBuffer() IpcLogOutputter::sendBuffer()
{ {
if (m_buffer.empty() || !m_ipcServer.hasClients(kIpcClientGui)) { if (m_buffer.empty() || !m_ipcServer.hasClients(m_clientType)) {
if (!m_buffer.empty()) {
m_buffer.clear();
}
return; return;
} }

View File

@ -21,6 +21,7 @@
#include "arch/Arch.h" #include "arch/Arch.h"
#include "arch/IArchMultithread.h" #include "arch/IArchMultithread.h"
#include "base/ILogOutputter.h" #include "base/ILogOutputter.h"
#include "ipc/Ipc.h"
#include <deque> #include <deque>
@ -39,7 +40,7 @@ public:
If \p useThread is \c false, then the buffer needs to be sent manually If \p useThread is \c false, then the buffer needs to be sent manually
using the \c sendBuffer() function. using the \c sendBuffer() function.
*/ */
IpcLogOutputter(IpcServer& ipcServer, bool useThread); IpcLogOutputter(IpcServer& ipcServer, EIpcClientType clientType, bool useThread);
virtual ~IpcLogOutputter(); virtual ~IpcLogOutputter();
// ILogOutputter overrides // ILogOutputter overrides
@ -113,4 +114,5 @@ private:
UInt16 m_bufferWriteCount; UInt16 m_bufferWriteCount;
double m_bufferRateStart; double m_bufferRateStart;
bool m_useThread; bool m_useThread;
EIpcClientType m_clientType;
}; };

View File

@ -211,7 +211,7 @@ DaemonApp::mainLoop(bool logToFile)
m_ipcServer = new IpcServer(m_events, &multiplexer); m_ipcServer = new IpcServer(m_events, &multiplexer);
// send logging to gui via ipc, log system adopts outputter. // send logging to gui via ipc, log system adopts outputter.
m_ipcLogOutputter = new IpcLogOutputter(*m_ipcServer, true); m_ipcLogOutputter = new IpcLogOutputter(*m_ipcServer, kIpcClientGui, true);
CLOG->insert(m_ipcLogOutputter); CLOG->insert(m_ipcLogOutputter);
#if SYSAPI_WIN32 #if SYSAPI_WIN32

View File

@ -52,11 +52,11 @@ TEST(IpcLogOutputterTests, write_threadingEnabled_bufferIsSent)
ON_CALL(mockServer, hasClients(_)).WillByDefault(Return(true)); ON_CALL(mockServer, hasClients(_)).WillByDefault(Return(true));
EXPECT_CALL(mockServer, hasClients(_)).Times(2); EXPECT_CALL(mockServer, hasClients(_)).Times(5);
EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock 1\n"), _)).Times(1); EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock 1\n"), _)).Times(1);
EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock 2\n"), _)).Times(1); EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock 2\n"), _)).Times(1);
IpcLogOutputter outputter(mockServer, true); IpcLogOutputter outputter(mockServer, kIpcClientUnknown, true);
outputter.write(kNOTE, "mock 1"); outputter.write(kNOTE, "mock 1");
mockServer.waitForSend(); mockServer.waitForSend();
outputter.write(kNOTE, "mock 2"); outputter.write(kNOTE, "mock 2");
@ -68,11 +68,10 @@ TEST(IpcLogOutputterTests, write_overBufferMaxSize_firstLineTruncated)
MockIpcServer mockServer; MockIpcServer mockServer;
ON_CALL(mockServer, hasClients(_)).WillByDefault(Return(true)); ON_CALL(mockServer, hasClients(_)).WillByDefault(Return(true));
EXPECT_CALL(mockServer, hasClients(_)).Times(4);
EXPECT_CALL(mockServer, hasClients(_)).Times(1);
EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock 2\nmock 3\n"), _)).Times(1); EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock 2\nmock 3\n"), _)).Times(1);
IpcLogOutputter outputter(mockServer, false); IpcLogOutputter outputter(mockServer, kIpcClientUnknown, false);
outputter.bufferMaxSize(2); outputter.bufferMaxSize(2);
// log more lines than the buffer can contain // log more lines than the buffer can contain
@ -88,10 +87,10 @@ TEST(IpcLogOutputterTests, write_underBufferMaxSize_allLinesAreSent)
ON_CALL(mockServer, hasClients(_)).WillByDefault(Return(true)); ON_CALL(mockServer, hasClients(_)).WillByDefault(Return(true));
EXPECT_CALL(mockServer, hasClients(_)).Times(1); EXPECT_CALL(mockServer, hasClients(_)).Times(3);
EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock 1\nmock 2\n"), _)).Times(1); EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock 1\nmock 2\n"), _)).Times(1);
IpcLogOutputter outputter(mockServer, false); IpcLogOutputter outputter(mockServer, kIpcClientUnknown, false);
outputter.bufferMaxSize(2); outputter.bufferMaxSize(2);
// log more lines than the buffer can contain // log more lines than the buffer can contain
@ -143,11 +142,11 @@ TEST(IpcLogOutputterTests, write_underBufferRateLimit_allLinesAreSent)
ON_CALL(mockServer, hasClients(_)).WillByDefault(Return(true)); ON_CALL(mockServer, hasClients(_)).WillByDefault(Return(true));
EXPECT_CALL(mockServer, hasClients(_)).Times(2); EXPECT_CALL(mockServer, hasClients(_)).Times(6);
EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock 1\nmock 2\n"), _)).Times(1); EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock 1\nmock 2\n"), _)).Times(1);
EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock 3\nmock 4\n"), _)).Times(1); EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock 3\nmock 4\n"), _)).Times(1);
IpcLogOutputter outputter(mockServer, false); IpcLogOutputter outputter(mockServer, kIpcClientUnknown, false);
outputter.bufferRateLimit(4, 1); // 1s (should be plenty of time) outputter.bufferRateLimit(4, 1); // 1s (should be plenty of time)
// log 1 more line than the buffer can accept in time limit. // log 1 more line than the buffer can accept in time limit.