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>
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 1c74ba5..6307bed 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -242,7 +242,7 @@
LastLogTimes::iterator t = mTimes.begin();
while(t != mTimes.end()) {
LogTimeEntry *entry = (*t);
- if (entry->owned_Locked()
+ if (entry->owned_Locked() && entry->isWatching(id)
&& (!oldest || (oldest->mStart > entry->mStart))) {
oldest = entry;
}
@@ -354,7 +354,7 @@
// kick a misbehaving log reader client off the island
oldest->release_Locked();
} else {
- oldest->triggerSkip_Locked(pruneRows);
+ oldest->triggerSkip_Locked(id, pruneRows);
}
}
break;
@@ -385,7 +385,7 @@
// kick a misbehaving log reader client off the island
oldest->release_Locked();
} else {
- oldest->triggerSkip_Locked(pruneRows);
+ oldest->triggerSkip_Locked(id, pruneRows);
}
break;
}