diff options
author | Ryan Prichard <rprichard@google.com> | 2019-04-30 14:47:34 -0700 |
---|---|---|
committer | Ryan Prichard <rprichard@google.com> | 2019-05-04 00:28:00 -0700 |
commit | c485cdb0249415b8aee5968b2b8854921e152854 (patch) | |
tree | 160af7094ea713aa83b280f594e4c834c4316bb3 /tests/stdio_test.cpp | |
parent | 0cd818a377157326ce326e8a48ea00882d1d1d06 (diff) |
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
Diffstat (limited to 'tests/stdio_test.cpp')
-rw-r--r-- | tests/stdio_test.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp index 65a942c37..c237d6d32 100644 --- a/tests/stdio_test.cpp +++ b/tests/stdio_test.cpp @@ -29,6 +29,7 @@ #include <locale.h> #include <string> +#include <thread> #include <vector> #include <android-base/file.h> @@ -2577,3 +2578,24 @@ TEST(STDIO_TEST, dev_std_files) { ASSERT_LT(0, length); ASSERT_EQ("/proc/self/fd/2", std::string(path, length)); } + +TEST(STDIO_TEST, fread_with_locked_file) { + // Reading an unbuffered/line-buffered file from one thread shouldn't block on + // files locked on other threads, even if it flushes some line-buffered files. + FILE* fp1 = fopen("/dev/zero", "r"); + ASSERT_TRUE(fp1 != nullptr); + flockfile(fp1); + + std::thread([] { + for (int mode : { _IONBF, _IOLBF }) { + FILE* fp2 = fopen("/dev/zero", "r"); + ASSERT_TRUE(fp2 != nullptr); + setvbuf(fp2, nullptr, mode, 0); + ASSERT_EQ('\0', fgetc(fp2)); + fclose(fp2); + } + }).join(); + + funlockfile(fp1); + fclose(fp1); +} |