Merge "Revert "Remove __sinit and __sdidinit.""

This commit is contained in:
Elliott Hughes 2015-12-05 01:53:21 +00:00 committed by Gerrit Code Review
commit 0d89913e74
6 changed files with 62 additions and 21 deletions

View File

@ -36,12 +36,20 @@
// struct __sfileext (see fileext.h). // struct __sfileext (see fileext.h).
void flockfile(FILE* fp) { void flockfile(FILE* fp) {
if (!__sdidinit) {
__sinit();
}
if (fp != nullptr) { if (fp != nullptr) {
pthread_mutex_lock(&_FLOCK(fp)); pthread_mutex_lock(&_FLOCK(fp));
} }
} }
int ftrylockfile(FILE* fp) { int ftrylockfile(FILE* fp) {
if (!__sdidinit) {
__sinit();
}
// The specification for ftrylockfile() says it returns 0 on success, // The specification for ftrylockfile() says it returns 0 on success,
// or non-zero on error. So return an errno code directly on error. // or non-zero on error. So return an errno code directly on error.
if (fp == nullptr) { if (fp == nullptr) {
@ -52,6 +60,10 @@ int ftrylockfile(FILE* fp) {
} }
void funlockfile(FILE* fp) { void funlockfile(FILE* fp) {
if (!__sdidinit) {
__sinit();
}
if (fp != nullptr) { if (fp != nullptr) {
pthread_mutex_unlock(&_FLOCK(fp)); pthread_mutex_unlock(&_FLOCK(fp));
} }

View File

@ -54,7 +54,7 @@ extern "C" abort_msg_t** __abort_message_ptr;
extern "C" int __system_properties_init(void); extern "C" int __system_properties_init(void);
extern "C" int __set_tls(void* ptr); extern "C" int __set_tls(void* ptr);
extern "C" int __set_tid_address(int* tid_address); extern "C" int __set_tid_address(int* tid_address);
extern "C" int __libc_init_stdio(void); extern "C" int __sinit(void);
__LIBC_HIDDEN__ WriteProtected<libc_globals> __libc_globals; __LIBC_HIDDEN__ WriteProtected<libc_globals> __libc_globals;
@ -134,9 +134,9 @@ void __libc_init_common(KernelArgumentBlock& args) {
__pthread_internal_add(main_thread); __pthread_internal_add(main_thread);
__system_properties_init(); // Requires 'environ'. __system_properties_init(); // Requires 'environ'.
// Initialize stdio here to get rid of data races caused by lazy initialization.
// Initialize stdio to avoid data races caused by BSD-style lazy initialization. // TODO: Remove other calls to __sinit().
__libc_init_stdio(); __sinit();
} }
__noreturn static void __early_abort(int line) { __noreturn static void __early_abort(int line) {

View File

@ -286,13 +286,6 @@ extern "C" int getdtablesize() {
return r.rlim_cur; return r.rlim_cur;
} }
// A leaked BSD stdio implementation detail that's now a no-op.
// (GCC doesn't like 'extern "C"' on a definition.)
extern "C" {
void __sinit() {}
int __sdidinit = 1;
}
// Only used by ftime, which was removed from POSIX 2008. // Only used by ftime, which was removed from POSIX 2008.
struct timeb { struct timeb {
time_t time; time_t time;

View File

@ -44,6 +44,8 @@
#define ALIGNBYTES (sizeof(uintptr_t) - 1) #define ALIGNBYTES (sizeof(uintptr_t) - 1)
#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES) #define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES)
int __sdidinit;
#define NDYNAMIC 10 /* add ten more whenever necessary */ #define NDYNAMIC 10 /* add ten more whenever necessary */
#define std(flags, file) \ #define std(flags, file) \
@ -112,6 +114,9 @@ __sfp(void)
int n; int n;
struct glue *g; struct glue *g;
if (!__sdidinit)
__sinit();
_THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex); _THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex);
for (g = &__sglue; g != NULL; g = g->next) { for (g = &__sglue; g != NULL; g = g->next) {
for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
@ -144,21 +149,48 @@ found:
return (fp); return (fp);
} }
static void __stdio_cleanup(void) { /*
* 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)
{
/* (void) _fwalk(fclose); */ /* (void) _fwalk(fclose); */
(void) _fwalk(__sflush); /* `cheating' */ (void) _fwalk(__sflush); /* `cheating' */
} }
void __libc_init_stdio(void) { /*
// Initialize stdin/stdout/stderr (for the recursive mutex). http://b/18208568. * __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. */
for (size_t i = 0; i < 3; ++i) { for (size_t i = 0; i < 3; ++i) {
_FILEEXT_SETUP(__sF+i, __sFext+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) { for (size_t i = 0; i < FOPEN_MAX - 3; ++i) {
_FILEEXT_SETUP(usual+i, usualext+i); _FILEEXT_SETUP(usual+i, usualext+i);
} }
// Make sure we clean up on exit. /* make sure we clean up on exit */
__atexit_register_cleanup(__stdio_cleanup); /* conservative */ __atexit_register_cleanup(_cleanup); /* conservative */
__sdidinit = 1;
_THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex);
} }

View File

@ -153,8 +153,10 @@ __LIBC32_LEGACY_PUBLIC__ int __srefill(FILE*);
__LIBC32_LEGACY_PUBLIC__ int __swsetup(FILE*); __LIBC32_LEGACY_PUBLIC__ int __swsetup(FILE*);
/* These were referenced by a couple of different pieces of middleware and the Crystax NDK. */ /* 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__ int __sflags(const char*, int*);
__LIBC32_LEGACY_PUBLIC__ FILE* __sfp(void); __LIBC32_LEGACY_PUBLIC__ FILE* __sfp(void);
__LIBC32_LEGACY_PUBLIC__ void __sinit(void);
__LIBC32_LEGACY_PUBLIC__ void __smakebuf(FILE*); __LIBC32_LEGACY_PUBLIC__ void __smakebuf(FILE*);
/* These are referenced by the Greed for Glory franchise. */ /* These are referenced by the Greed for Glory franchise. */
@ -168,6 +170,7 @@ __LIBC32_LEGACY_PUBLIC__ int _fwalk(int (*)(FILE *));
#pragma GCC visibility push(hidden) #pragma GCC visibility push(hidden)
int __sflush_locked(FILE *); int __sflush_locked(FILE *);
void _cleanup(void);
int __swhatbuf(FILE *, size_t *, int *); int __swhatbuf(FILE *, size_t *, int *);
wint_t __fgetwc_unlock(FILE *); wint_t __fgetwc_unlock(FILE *);
wint_t __ungetwc(wint_t, FILE *); wint_t __ungetwc(wint_t, FILE *);
@ -234,10 +237,6 @@ struct __suio;
extern int __sfvwrite(FILE *, struct __suio *); extern int __sfvwrite(FILE *, struct __suio *);
wint_t __fputwc_unlock(wchar_t wc, FILE *fp); 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 #pragma GCC visibility pop
__END_DECLS __END_DECLS

View File

@ -51,6 +51,11 @@ lflush(FILE *fp)
int int
__srefill(FILE *fp) __srefill(FILE *fp)
{ {
/* make sure stdio is set up */
if (!__sdidinit)
__sinit();
fp->_r = 0; /* largely a convenience for callers */ fp->_r = 0; /* largely a convenience for callers */
#if !defined(__ANDROID__) #if !defined(__ANDROID__)