diff options
author | Elliott Hughes <enh@google.com> | 2015-01-20 18:09:05 -0800 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2015-01-21 10:33:30 -0800 |
commit | 8c4994bbc1a9a01e34ea92c91eb5b2d1a27bd074 (patch) | |
tree | 8b632cea0832373b9cb843427bb5976b3668f1a2 /libc/stdio/stdio_ext.cpp | |
parent | f374358414812d3e5a45ba75a2b1926693924420 (diff) |
Implement __fsetlocking.
The old __isthreaded hack was never very useful on Android because all user
code runs in a VM where there are lots of threads running. But __fsetlocking
lets a caller say "I'll worry about the locking for this FILE*", which is
useful for the normal case where you don't share a FILE* between threads
so you don't need any locking.
Bug: 17154740
Bug: 18593728
Change-Id: I2a8dddc29d3edff39a3d7d793387f2253608a68d
Diffstat (limited to 'libc/stdio/stdio_ext.cpp')
-rw-r--r-- | libc/stdio/stdio_ext.cpp | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/libc/stdio/stdio_ext.cpp b/libc/stdio/stdio_ext.cpp index bfdecb81c..fea44f68b 100644 --- a/libc/stdio/stdio_ext.cpp +++ b/libc/stdio/stdio_ext.cpp @@ -27,13 +27,10 @@ */ #include <stdio_ext.h> +#include <stdlib.h> -#include <stdio.h> #include "local.h" - -#define FSETLOCKING_QUERY 0 -#define FSETLOCKING_INTERNAL 1 -#define FSETLOCKING_BYCALLER 2 +#include "private/libc_logging.h" size_t __fbufsize(FILE* fp) { return fp->_bf._size; @@ -76,11 +73,19 @@ void _flushlbf() { fflush(NULL); } -int __fsetlocking(FILE*, int) { - // We don't currently have an implementation that would obey this, - // so make setting the state a no-op and always return "we handle locking for you". - // http://b/17154740 suggests ways we could fix this. - return FSETLOCKING_INTERNAL; +int __fsetlocking(FILE* fp, int type) { + int old_state = _EXT(fp)->_stdio_handles_locking ? FSETLOCKING_INTERNAL : FSETLOCKING_BYCALLER; + if (type == FSETLOCKING_QUERY) { + return old_state; + } + + if (type != FSETLOCKING_INTERNAL && type != FSETLOCKING_BYCALLER) { + // The API doesn't let us report an error, so blow up. + __libc_fatal("Bad type (%d) passed to __fsetlocking", type); + } + + _EXT(fp)->_stdio_handles_locking = (type == FSETLOCKING_INTERNAL); + return old_state; } void clearerr_unlocked(FILE* fp) { |