-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAsyncLogging.cpp
73 lines (66 loc) · 1.76 KB
/
AsyncLogging.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include "AsyncLogging.h"
AsyncLogging::AsyncLogging(const std::string logFileName,int FlushInterval)
: flushInterval(FlushInterval),
running(false),
basename(logFileName),
thread_(std::bind(&AsyncLogging::threadFunc,this),"Logging"),
mutex(),
cond(mutex),
currentBuffer(newElement<Buffer>(),deleteElement<Buffer>),
nextBuffer(newElement<Buffer>(),deleteElement<Buffer>)
{
}
AsyncLogging::~AsyncLogging(){
if(running)
stop();
}
void AsyncLogging::append(const char *logline,int len){
MutexLockGuard lock(mutex);
if(currentBuffer->avail()>len)
currentBuffer->append(logline,len);
else{
buffers.emplace_back(currentBuffer);
if(nextBuffer)
currentBuffer=std::move(nextBuffer);
else
currentBuffer.reset(newElement<Buffer>(),deleteElement<Buffer>);
currentBuffer->append(logline,len);
cond.notify();
}
}
void AsyncLogging::threadFunc(){
BufferPtr newBuffer1(newElement<Buffer>(),deleteElement<Buffer>);
BufferPtr newBuffer2(newElement<Buffer>(),deleteElement<Buffer>);
BufferVector buffersToWrite;
LogFile output(basename);
while(running){
{
MutexLockGuard lock(mutex);
if(buffers.empty())
cond.waitForSeconds(flushInterval);
buffers.emplace_back(currentBuffer);
currentBuffer=std::move(newBuffer1);
buffersToWrite.swap(buffers);
if(!nextBuffer)
nextBuffer=std::move(newBuffer2);
}
for(auto &wi:buffersToWrite)
output.append(wi->data(),wi->length());
if(!newBuffer1)
newBuffer1.reset(newElement<Buffer>(),deleteElement<Buffer>);
if(!newBuffer2)
newBuffer2.reset(newElement<Buffer>(),deleteElement<Buffer>);
buffersToWrite.clear();
output.flush();
}
output.flush();
}
void AsyncLogging::start(){
running=true;
thread_.start();
}
void AsyncLogging::stop(){
running=false;
cond.notify();
thread_.join();
}