summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/android/log.h5
-rw-r--r--liblog/logger_write.c35
-rw-r--r--liblog/tests/liblog_test.cpp10
3 files changed, 49 insertions, 1 deletions
diff --git a/include/android/log.h b/include/android/log.h
index 1c171b7bf..391c826d5 100644
--- a/include/android/log.h
+++ b/include/android/log.h
@@ -89,6 +89,11 @@ typedef enum android_LogPriority {
} android_LogPriority;
/*
+ * Release any logger resources (a new log write will immediately re-acquire)
+ */
+void __android_log_close();
+
+/*
* Send a simple string to the log.
*/
int __android_log_write(int prio, const char *tag, const char *text);
diff --git a/liblog/logger_write.c b/liblog/logger_write.c
index b802ed7b2..c7b5a8415 100644
--- a/liblog/logger_write.c
+++ b/liblog/logger_write.c
@@ -132,6 +132,41 @@ LIBLOG_ABI_PUBLIC int __android_log_dev_available()
}
return kLogNotAvailable;
}
+/*
+ * Release any logger resources. A new log write will immediately re-acquire.
+ */
+LIBLOG_ABI_PUBLIC void __android_log_close()
+{
+ struct android_log_transport_write *transport;
+
+ __android_log_lock();
+
+ write_to_log = __write_to_log_init;
+
+ /*
+ * Threads that are actively writing at this point are not held back
+ * by a lock and are at risk of dropping the messages with a return code
+ * -EBADF. Prefer to return error code than add the overhead of a lock to
+ * each log writing call to guarantee delivery. In addition, anyone
+ * calling this is doing so to release the logging resources and shut down,
+ * for them to do so with outstanding log requests in other threads is a
+ * disengenuous use of this function.
+ */
+
+ write_transport_for_each(transport, &__android_log_persist_write) {
+ if (transport->close) {
+ (*transport->close)();
+ }
+ }
+
+ write_transport_for_each(transport, &__android_log_transport_write) {
+ if (transport->close) {
+ (*transport->close)();
+ }
+ }
+
+ __android_log_unlock();
+}
/* log_init_lock assumed */
static int __write_to_log_initialize()
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 6aa4fb786..f0acdf8f8 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -132,12 +132,17 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) {
ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
+ // Check that we can close and reopen the logger
log_time ts(CLOCK_MONOTONIC);
-
ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
+ __android_log_close();
+
+ log_time ts1(CLOCK_MONOTONIC);
+ ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1)));
usleep(1000000);
int count = 0;
+ int second_count = 0;
for (;;) {
log_msg log_msg;
@@ -161,10 +166,13 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) {
log_time tx(eventData + 4 + 1);
if (ts == tx) {
++count;
+ } else if (ts1 == tx) {
+ ++second_count;
}
}
EXPECT_EQ(1, count);
+ EXPECT_EQ(1, second_count);
android_logger_list_close(logger_list);
}