Revert fwalk/sfp locking to fix concurrent reads

The locking can fail in a couple of ways:

 - A concurrent fread from an unbuffered or line-buffered file flushes
   the output of other line-buffered files, and if _fwalk locks every
   file, then the fread blocks until other file reads have completed.

 - __sfp can initialize a file lock while _fwalk is locking/unlocking it.

For now, revert to the behavior Bionic had in previous releases. This
commit reverts the file locking parts of commit
468efc80da2504f4ae7de8b5e137426d44dda9d7.

Bug: http://b/131251441
Bug: http://b/130189834
Test: bionic unit tests
Change-Id: I9e20b9cd8ccd14e7962f7308e174f08af72b56c6
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index 4cec757..91c7689 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -106,7 +106,7 @@
 FILE* stdout = &__sF[1];
 FILE* stderr = &__sF[2];
 
-static pthread_mutex_t __stdio_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+static pthread_mutex_t __stdio_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 static uint64_t __get_file_tag(FILE* fp) {
   // Don't use a tag for the standard streams.
@@ -211,21 +211,23 @@
 }
 
 int _fwalk(int (*callback)(FILE*)) {
-  pthread_mutex_lock(&__stdio_mutex);
   int result = 0;
   for (glue* g = &__sglue; g != nullptr; g = g->next) {
     FILE* fp = g->iobs;
     for (int n = g->niobs; --n >= 0; ++fp) {
-      ScopedFileLock sfl(fp);
       if (fp->_flags != 0 && (fp->_flags & __SIGN) == 0) {
         result |= (*callback)(fp);
       }
     }
   }
-  pthread_mutex_unlock(&__stdio_mutex);
   return result;
 }
 
+extern "C" __LIBC_HIDDEN__ void __libc_stdio_cleanup(void) {
+  // Equivalent to fflush(nullptr), but without all the locking since we're shutting down anyway.
+  _fwalk(__sflush);
+}
+
 static FILE* __fopen(int fd, int flags) {
 #if !defined(__LP64__)
   if (fd > SHRT_MAX) {
@@ -520,6 +522,11 @@
   return 0;
 }
 
+int __sflush_locked(FILE* fp) {
+  ScopedFileLock sfl(fp);
+  return __sflush(fp);
+}
+
 int __sread(void* cookie, char* buf, int n) {
   FILE* fp = reinterpret_cast<FILE*>(cookie);
   return TEMP_FAILURE_RETRY(read(fp->_file, buf, n));
@@ -1061,7 +1068,7 @@
 }
 
 static int fflush_all() {
-  return _fwalk(__sflush);
+  return _fwalk(__sflush_locked);
 }
 
 int fflush(FILE* fp) {