From 4371961e00ad83fca033992c8a19c7d262fe6f84 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Thu, 3 Dec 2015 13:23:03 -0800 Subject: [PATCH] Remove __sinit and __sdidinit. We're eagerly initializing stdio now, so this can all be simplified. Change-Id: Icb288f8dd0ee08f02bea0d23670f75e78bed6b99 --- libc/bionic/flockfile.cpp | 12 --------- libc/bionic/libc_init_common.cpp | 8 +++--- libc/bionic/ndk_cruft.cpp | 6 +++++ libc/stdio/findfp.c | 44 +++++--------------------------- libc/stdio/local.h | 7 ++--- libc/stdio/refill.c | 5 ---- 6 files changed, 20 insertions(+), 62 deletions(-) diff --git a/libc/bionic/flockfile.cpp b/libc/bionic/flockfile.cpp index db688016b..db5382859 100644 --- a/libc/bionic/flockfile.cpp +++ b/libc/bionic/flockfile.cpp @@ -36,20 +36,12 @@ // struct __sfileext (see fileext.h). void flockfile(FILE* fp) { - if (!__sdidinit) { - __sinit(); - } - if (fp != nullptr) { pthread_mutex_lock(&_FLOCK(fp)); } } int ftrylockfile(FILE* fp) { - if (!__sdidinit) { - __sinit(); - } - // The specification for ftrylockfile() says it returns 0 on success, // or non-zero on error. So return an errno code directly on error. if (fp == nullptr) { @@ -60,10 +52,6 @@ int ftrylockfile(FILE* fp) { } void funlockfile(FILE* fp) { - if (!__sdidinit) { - __sinit(); - } - if (fp != nullptr) { pthread_mutex_unlock(&_FLOCK(fp)); } diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp index 91e210e3e..8f210ea7c 100644 --- a/libc/bionic/libc_init_common.cpp +++ b/libc/bionic/libc_init_common.cpp @@ -54,7 +54,7 @@ extern "C" abort_msg_t** __abort_message_ptr; extern "C" int __system_properties_init(void); extern "C" int __set_tls(void* ptr); extern "C" int __set_tid_address(int* tid_address); -extern "C" int __sinit(void); +extern "C" int __libc_init_stdio(void); __LIBC_HIDDEN__ WriteProtected __libc_globals; @@ -134,9 +134,9 @@ void __libc_init_common(KernelArgumentBlock& args) { __pthread_internal_add(main_thread); __system_properties_init(); // Requires 'environ'. - // Initialize stdio here to get rid of data races caused by lazy initialization. - // TODO: Remove other calls to __sinit(). - __sinit(); + + // Initialize stdio to avoid data races caused by BSD-style lazy initialization. + __libc_init_stdio(); } __noreturn static void __early_abort(int line) { diff --git a/libc/bionic/ndk_cruft.cpp b/libc/bionic/ndk_cruft.cpp index d6b8e8f02..6609470ef 100644 --- a/libc/bionic/ndk_cruft.cpp +++ b/libc/bionic/ndk_cruft.cpp @@ -286,6 +286,12 @@ extern "C" int getdtablesize() { return r.rlim_cur; } +// A leaked BSD stdio implementation detail that's now a no-op. +extern "C" void __sinit() { +} + +extern "C" int __sdidinit = 1; + // Only used by ftime, which was removed from POSIX 2008. struct timeb { time_t time; diff --git a/libc/stdio/findfp.c b/libc/stdio/findfp.c index 2696cfd25..4054d5f3c 100644 --- a/libc/stdio/findfp.c +++ b/libc/stdio/findfp.c @@ -44,8 +44,6 @@ #define ALIGNBYTES (sizeof(uintptr_t) - 1) #define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES) -int __sdidinit; - #define NDYNAMIC 10 /* add ten more whenever necessary */ #define std(flags, file) \ @@ -114,9 +112,6 @@ __sfp(void) int n; struct glue *g; - if (!__sdidinit) - __sinit(); - _THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex); for (g = &__sglue; g != NULL; g = g->next) { for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) @@ -149,48 +144,21 @@ found: return (fp); } -/* - * exit() and abort() call _cleanup() through the callback registered - * with __atexit_register_cleanup(), set whenever we open or buffer a - * file. This chicanery is done so that programs that do not use stdio - * need not link it all in. - * - * The name `_cleanup' is, alas, fairly well known outside stdio. - */ -void -_cleanup(void) -{ +static void __stdio_cleanup(void) { /* (void) _fwalk(fclose); */ (void) _fwalk(__sflush); /* `cheating' */ } -/* - * __sinit() is called whenever stdio's internal variables must be set up. - */ -void -__sinit(void) -{ - _THREAD_PRIVATE_MUTEX(__sinit_mutex); - - _THREAD_PRIVATE_MUTEX_LOCK(__sinit_mutex); - if (__sdidinit) { - /* bail out if caller lost the race */ - _THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex); - return; - } - - /* Initialize stdin/stdout/stderr (for the recursive mutex). http://b/18208568. */ +void __libc_init_stdio(void) { + // Initialize stdin/stdout/stderr (for the recursive mutex). http://b/18208568. for (size_t i = 0; i < 3; ++i) { _FILEEXT_SETUP(__sF+i, __sFext+i); } - /* Initialize the pre-allocated (but initially unused) streams. */ + // Initialize the pre-allocated (but initially unused) streams. for (size_t i = 0; i < FOPEN_MAX - 3; ++i) { _FILEEXT_SETUP(usual+i, usualext+i); } - /* make sure we clean up on exit */ - __atexit_register_cleanup(_cleanup); /* conservative */ - __sdidinit = 1; - - _THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex); + // Make sure we clean up on exit. + __atexit_register_cleanup(__stdio_cleanup); /* conservative */ } diff --git a/libc/stdio/local.h b/libc/stdio/local.h index 3ae7059da..db3068df4 100644 --- a/libc/stdio/local.h +++ b/libc/stdio/local.h @@ -153,10 +153,8 @@ __LIBC32_LEGACY_PUBLIC__ int __srefill(FILE*); __LIBC32_LEGACY_PUBLIC__ int __swsetup(FILE*); /* These were referenced by a couple of different pieces of middleware and the Crystax NDK. */ -__LIBC32_LEGACY_PUBLIC__ extern int __sdidinit; __LIBC32_LEGACY_PUBLIC__ int __sflags(const char*, int*); __LIBC32_LEGACY_PUBLIC__ FILE* __sfp(void); -__LIBC32_LEGACY_PUBLIC__ void __sinit(void); __LIBC32_LEGACY_PUBLIC__ void __smakebuf(FILE*); /* These are referenced by the Greed for Glory franchise. */ @@ -170,7 +168,6 @@ __LIBC32_LEGACY_PUBLIC__ int _fwalk(int (*)(FILE *)); #pragma GCC visibility push(hidden) int __sflush_locked(FILE *); -void _cleanup(void); int __swhatbuf(FILE *, size_t *, int *); wint_t __fgetwc_unlock(FILE *); wint_t __ungetwc(wint_t, FILE *); @@ -237,6 +234,10 @@ struct __suio; extern int __sfvwrite(FILE *, struct __suio *); wint_t __fputwc_unlock(wchar_t wc, FILE *fp); +/* Remove the if (!__sdidinit) __sinit() idiom from untouched upstream stdio code. */ +extern void __sinit(void); // Not actually implemented. +#define __sdidinit 1 + #pragma GCC visibility pop __END_DECLS diff --git a/libc/stdio/refill.c b/libc/stdio/refill.c index e87c7b93e..5b0811f6a 100644 --- a/libc/stdio/refill.c +++ b/libc/stdio/refill.c @@ -51,11 +51,6 @@ lflush(FILE *fp) int __srefill(FILE *fp) { - - /* make sure stdio is set up */ - if (!__sdidinit) - __sinit(); - fp->_r = 0; /* largely a convenience for callers */ #if !defined(__ANDROID__)