summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTraianX Schiau2014-12-17 02:53:41 -0600
committerMark Salyzyn2015-01-14 13:12:47 -0600
commitda6495d06f1798ea81cebbfbdd44f16135e1a3cd (patch)
treefe2b7bf4d3f15d06da42731645b8fe7115084b5b /logd/LogTimes.cpp
parentda3dec3c19d1489f5997aea9dafd34b68c2b515b (diff)
downloadplatform-system-core-da6495d06f1798ea81cebbfbdd44f16135e1a3cd.tar.gz
platform-system-core-da6495d06f1798ea81cebbfbdd44f16135e1a3cd.tar.xz
platform-system-core-da6495d06f1798ea81cebbfbdd44f16135e1a3cd.zip
logd: Fix pruning
In a scenario in which an on-line (blocking) client is running and a clean is attempted (logcat -c), the following can be observed: 1) the on-line logger seems to freeze 2) any other clear attempt will have no effect What is actually happening: In this case prune function will "instruct" the oldest timeEntry to skip a huge number (very close to ULONG_MAX) of messages, this being the cause of 1. Since the consumer thread will skip all the log entries, mStart updating will also be skipped. So a new cleaning attempt will have the same oldest entry, nothing will be done. Fix description: a. keep a separated skipAhead count for individual log buffers (log_id_t) LogTimeEntry::LogTimeEntry LogTimeEntry::FilterSecondPass LogTimeEntry::skipAhead LogTimeEntry::riggerSkip_Locked b. update LogTimeEntry::mStart even if the current message is skipped LogTimeEntry::FilterSecondPass c. while pruning, only take into account the LogTimeEntrys that are monitoring the log_id in question, and provide a public method of checking this. LogTimeEntry::isWatching LogTimeEntry::FilterFirstPass LogTimeEntry::FilterSecondPass d. Reset the skip cont befor the client thtread starts to sleep, at this point we should be up to date. LogTimeEntry::cleanSkip_Locked LogTimeEntry::threadStart Change-Id: I1b369dc5b02476e633e52578266a644e37e188a5 Signed-off-by: TraianX Schiau <traianx.schiau@intel.com>
Diffstat (limited to 'logd/LogTimes.cpp')
-rw-r--r--logd/LogTimes.cpp24
1 files changed, 16 insertions, 8 deletions
diff --git a/logd/LogTimes.cpp b/logd/LogTimes.cpp
index ea4e8c83d..5f9db8da5 100644
--- a/logd/LogTimes.cpp
+++ b/logd/LogTimes.cpp
@@ -36,7 +36,6 @@ LogTimeEntry::LogTimeEntry(LogReader &reader, SocketClient *client,
36 , mReader(reader) 36 , mReader(reader)
37 , mLogMask(logMask) 37 , mLogMask(logMask)
38 , mPid(pid) 38 , mPid(pid)
39 , skipAhead(0)
40 , mCount(0) 39 , mCount(0)
41 , mTail(tail) 40 , mTail(tail)
42 , mIndex(0) 41 , mIndex(0)
@@ -46,6 +45,7 @@ LogTimeEntry::LogTimeEntry(LogReader &reader, SocketClient *client,
46 , mEnd(CLOCK_MONOTONIC) 45 , mEnd(CLOCK_MONOTONIC)
47{ 46{
48 pthread_cond_init(&threadTriggeredCondition, NULL); 47 pthread_cond_init(&threadTriggeredCondition, NULL);
48 cleanSkip_Locked();
49} 49}
50 50
51void LogTimeEntry::startReader_Locked(void) { 51void LogTimeEntry::startReader_Locked(void) {
@@ -148,6 +148,8 @@ void *LogTimeEntry::threadStart(void *obj) {
148 break; 148 break;
149 } 149 }
150 150
151 me->cleanSkip_Locked();
152
151 pthread_cond_wait(&me->threadTriggeredCondition, &timesLock); 153 pthread_cond_wait(&me->threadTriggeredCondition, &timesLock);
152 } 154 }
153 155
@@ -169,7 +171,7 @@ bool LogTimeEntry::FilterFirstPass(const LogBufferElement *element, void *obj) {
169 } 171 }
170 172
171 if ((!me->mPid || (me->mPid == element->getPid())) 173 if ((!me->mPid || (me->mPid == element->getPid()))
172 && (me->mLogMask & (1 << element->getLogId()))) { 174 && (me->isWatching(element->getLogId()))) {
173 ++me->mCount; 175 ++me->mCount;
174 } 176 }
175 177
@@ -184,19 +186,19 @@ bool LogTimeEntry::FilterSecondPass(const LogBufferElement *element, void *obj)
184 186
185 LogTimeEntry::lock(); 187 LogTimeEntry::lock();
186 188
187 if (me->skipAhead) { 189 me->mStart = element->getMonotonicTime();
188 me->skipAhead--; 190
191 if (me->skipAhead[element->getLogId()]) {
192 me->skipAhead[element->getLogId()]--;
189 goto skip; 193 goto skip;
190 } 194 }
191 195
192 me->mStart = element->getMonotonicTime();
193
194 // Truncate to close race between first and second pass 196 // Truncate to close race between first and second pass
195 if (me->mNonBlock && me->mTail && (me->mIndex >= me->mCount)) { 197 if (me->mNonBlock && me->mTail && (me->mIndex >= me->mCount)) {
196 goto skip; 198 goto skip;
197 } 199 }
198 200
199 if ((me->mLogMask & (1 << element->getLogId())) == 0) { 201 if (!me->isWatching(element->getLogId())) {
200 goto skip; 202 goto skip;
201 } 203 }
202 204
@@ -223,7 +225,7 @@ bool LogTimeEntry::FilterSecondPass(const LogBufferElement *element, void *obj)
223 } 225 }
224 226
225ok: 227ok:
226 if (!me->skipAhead) { 228 if (!me->skipAhead[element->getLogId()]) {
227 LogTimeEntry::unlock(); 229 LogTimeEntry::unlock();
228 return true; 230 return true;
229 } 231 }
@@ -233,3 +235,9 @@ skip:
233 LogTimeEntry::unlock(); 235 LogTimeEntry::unlock();
234 return false; 236 return false;
235} 237}
238
239void LogTimeEntry::cleanSkip_Locked(void) {
240 for (log_id_t i = LOG_ID_MIN; i < LOG_ID_MAX; i = (log_id_t) (i + 1)) {
241 skipAhead[i] = 0;
242 }
243}