From d3987a96241d211351b0c8b942c047fc16b659da Mon Sep 17 00:00:00 2001 From: Jintao Zhu Date: Thu, 20 Dec 2018 23:10:41 +0800 Subject: [PATCH] logd: improve logd prune upon memory usage high(>log_buffer_size), logd will try to prune(erase) all those old log elements which have been read by all readers for reclaiming the memory. As such, a too slow reader will be a hinder to the success of the prune. Logd has to try to kick-out the slow-est reader when memory usage is really too high(>2 * log_buffer_size). But the kick-out operation is just a request to the reader and at what time the reader will exit is always uncertain, beyond control. Furthermore, if you kick-out reader-A, waiting for A to exit; then, another reader-B may come in; then A exit; and then you kick-out-B, waiting for B to exit; and then, ...loop for ever: yes, logd may find that there seems to be always a slow reader hinder its pruning. As we all know, that, logd will probably kick-out a slow reader(logcat), hence, indeed, almost all log capturing tools will try to re-connect logd immediately after it being kick-out-ed. Such retry makes the issue easy to happen. And, we observed that the reader thread may often be blocked by socket write operation, which hindering its exiting and hereby hindering the prune progress. We need gracefully shutdown socket to relieve it from blocking and eventually stop such disaster from happening. Test: monkey test for one day and one night Change-Id: I5496ff74168b71e261914b91c145aa44814a5def --- logd/LogTimes.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/logd/LogTimes.h b/logd/LogTimes.h index f4e165fdc..9f6f20335 100644 --- a/logd/LogTimes.h +++ b/logd/LogTimes.h @@ -18,6 +18,7 @@ #define _LOGD_LOG_TIMES_H__ #include +#include #include #include @@ -82,6 +83,8 @@ class LogTimeEntry { void cleanSkip_Locked(void); void release_Locked(void) { + // gracefully shut down the socket. + shutdown(mClient->getSocket(), SHUT_RDWR); mRelease = true; pthread_cond_signal(&threadTriggeredCondition); }