merge in nougat-cts-release history after reset to nougat-cts-dev
diff --git a/include/android/log.h b/include/android/log.h
index 1c171b7..391c826 100644
--- a/include/android/log.h
+++ b/include/android/log.h
@@ -89,6 +89,11 @@
 } 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 b802ed7..c7b5a84 100644
--- a/liblog/logger_write.c
+++ b/liblog/logger_write.c
@@ -132,6 +132,41 @@
     }
     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 6aa4fb7..f0acdf8 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -132,12 +132,17 @@
     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 @@
         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);
 }