Change _stdio_handles_locking into _caller_handles_locking.

It is reported by tsan that funlockfile() can unlock an unlocked mutex.
It happens when printf() is called before fopen() or other stdio stuff.
As FLOCKFILE(fp) is called before __sinit(), _stdio_handles_locking is false,
and _FLOCK(fp) will not be locked. But then cantwrite(fp) in __vfprintf()
calls__sinit(), which makes _stdio_handles_locking become true, and
FUNLOCKFILE(fp) unlocks _FLOCK(fp).

Change _stdio_handles_locking into _caller_handles_locking,
so __sinit() won't change its value. Add test due to my previous fault.

Bug: 25392375
Change-Id: I483e3c3cdb28da65e62f1fd9615bf58c5403b4dd
diff --git a/tests/stdio_ext_test.cpp b/tests/stdio_ext_test.cpp
index c95cbbd..7872567 100644
--- a/tests/stdio_ext_test.cpp
+++ b/tests/stdio_ext_test.cpp
@@ -30,6 +30,7 @@
 #include <locale.h>
 
 #include "TemporaryFile.h"
+#include "utils.h"
 
 TEST(stdio_ext, __fbufsize) {
   FILE* fp = fopen("/proc/version", "r");
@@ -140,3 +141,24 @@
   ASSERT_EQ(FSETLOCKING_INTERNAL, __fsetlocking(fp, FSETLOCKING_QUERY));
   fclose(fp);
 }
+
+static void LockingByCallerHelper(std::atomic<pid_t>* pid) {
+  *pid = gettid();
+  flockfile(stdout);
+  funlockfile(stdout);
+}
+
+TEST(stdio_ext, __fsetlocking_BYCALLER) {
+  // Check if users can use flockfile/funlockfile to protect stdio operations.
+  int old_state = __fsetlocking(stdout, FSETLOCKING_BYCALLER);
+  flockfile(stdout);
+  pthread_t thread;
+  std::atomic<pid_t> pid(0);
+  ASSERT_EQ(0, pthread_create(&thread, nullptr,
+                              reinterpret_cast<void* (*)(void*)>(LockingByCallerHelper), &pid));
+  WaitUntilThreadSleep(pid);
+  funlockfile(stdout);
+
+  ASSERT_EQ(0, pthread_join(thread, nullptr));
+  __fsetlocking(stdout, old_state);
+}