diff options
Diffstat (limited to 'libc')
-rw-r--r-- | libc/Android.mk | 2 | ||||
-rw-r--r-- | libc/arch-arm64/bionic/crtbegin.c | 1 | ||||
-rw-r--r-- | libc/arch-common/bionic/crtbegin.c | 1 | ||||
-rw-r--r-- | libc/arch-common/bionic/crtbegin_so.c | 1 | ||||
-rw-r--r-- | libc/arch-common/bionic/pthread_atfork.h | 29 | ||||
-rw-r--r-- | libc/arch-mips/bionic/crtbegin.c | 1 | ||||
-rw-r--r-- | libc/bionic/pthread_atfork.cpp | 122 | ||||
-rw-r--r-- | libc/upstream-openbsd/lib/libc/stdlib/atexit.c (renamed from libc/stdlib/atexit.c) | 16 | ||||
-rw-r--r-- | libc/upstream-openbsd/lib/libc/stdlib/atexit.h (renamed from libc/stdlib/atexit.h) | 0 |
9 files changed, 32 insertions, 141 deletions
diff --git a/libc/Android.mk b/libc/Android.mk index 8ed969fe9..4a199e747 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -63,7 +63,6 @@ libc_common_src_files := \ stdio/sprintf.c \ stdio/stdio.c \ stdio/stdio_ext.cpp \ - stdlib/atexit.c \ stdlib/exit.c \ # Fortify implementations of libc functions. @@ -482,6 +481,7 @@ libc_upstream_openbsd_ndk_src_files := \ upstream-openbsd/lib/libc/stdio/wprintf.c \ upstream-openbsd/lib/libc/stdio/wscanf.c \ upstream-openbsd/lib/libc/stdio/wsetup.c \ + upstream-openbsd/lib/libc/stdlib/atexit.c \ upstream-openbsd/lib/libc/stdlib/atoi.c \ upstream-openbsd/lib/libc/stdlib/atol.c \ upstream-openbsd/lib/libc/stdlib/atoll.c \ diff --git a/libc/arch-arm64/bionic/crtbegin.c b/libc/arch-arm64/bionic/crtbegin.c index 7e2c5d766..fec0b11af 100644 --- a/libc/arch-arm64/bionic/crtbegin.c +++ b/libc/arch-arm64/bionic/crtbegin.c @@ -67,4 +67,3 @@ __asm__ ( #include "../../arch-common/bionic/__dso_handle.h" #include "../../arch-common/bionic/atexit.h" -#include "../../arch-common/bionic/pthread_atfork.h" diff --git a/libc/arch-common/bionic/crtbegin.c b/libc/arch-common/bionic/crtbegin.c index c46405c4f..fa9f3f32b 100644 --- a/libc/arch-common/bionic/crtbegin.c +++ b/libc/arch-common/bionic/crtbegin.c @@ -59,7 +59,6 @@ void _start() { #include "__dso_handle.h" #include "atexit.h" -#include "pthread_atfork.h" #ifdef __i386__ # include "../../arch-x86/bionic/__stack_chk_fail_local.h" #endif diff --git a/libc/arch-common/bionic/crtbegin_so.c b/libc/arch-common/bionic/crtbegin_so.c index 3754363ab..641e45a4e 100644 --- a/libc/arch-common/bionic/crtbegin_so.c +++ b/libc/arch-common/bionic/crtbegin_so.c @@ -56,7 +56,6 @@ void __on_dlclose() { # include "__dso_handle_so.h" # include "atexit.h" #endif -#include "pthread_atfork.h" #ifdef __i386__ # include "../../arch-x86/bionic/__stack_chk_fail_local.h" #endif diff --git a/libc/arch-common/bionic/pthread_atfork.h b/libc/arch-common/bionic/pthread_atfork.h deleted file mode 100644 index 0c48a1269..000000000 --- a/libc/arch-common/bionic/pthread_atfork.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -extern void* __dso_handle; - -extern int __register_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void), void* dso); - -#ifndef _LIBC -// Libc used to export this in previous versions, therefore it needs -// to remain global for binary compatibility. -__attribute__ ((visibility ("hidden"))) -#endif -int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void)) { - return __register_atfork(prepare, parent, child, &__dso_handle); -} - diff --git a/libc/arch-mips/bionic/crtbegin.c b/libc/arch-mips/bionic/crtbegin.c index d72ec7b8d..50e9eeb02 100644 --- a/libc/arch-mips/bionic/crtbegin.c +++ b/libc/arch-mips/bionic/crtbegin.c @@ -92,4 +92,3 @@ __asm__ ( #include "../../arch-common/bionic/__dso_handle.h" #include "../../arch-common/bionic/atexit.h" -#include "../../arch-common/bionic/pthread_atfork.h" diff --git a/libc/bionic/pthread_atfork.cpp b/libc/bionic/pthread_atfork.cpp index 093ffd240..d1c4ad0c4 100644 --- a/libc/bionic/pthread_atfork.cpp +++ b/libc/bionic/pthread_atfork.cpp @@ -30,8 +30,6 @@ #include <pthread.h> #include <stdlib.h> -#include "private/bionic_macros.h" - struct atfork_t { atfork_t* next; atfork_t* prev; @@ -39,143 +37,79 @@ struct atfork_t { void (*prepare)(void); void (*child)(void); void (*parent)(void); - - void* dso_handle; }; -class atfork_list_t { - public: - atfork_list_t() : first_(nullptr), last_(nullptr) {} - - template<typename F> - void walk_forward(F f) { - for (atfork_t* it = first_; it != nullptr; it = it->next) { - f(it); - } - } - - template<typename F> - void walk_backwards(F f) { - for (atfork_t* it = last_; it != nullptr; it = it->prev) { - f(it); - } - } - - void push_back(atfork_t* entry) { - entry->next = nullptr; - entry->prev = last_; - if (entry->prev != nullptr) { - entry->prev->next = entry; - } - if (first_ == nullptr) { - first_ = entry; - } - last_ = entry; - } - - template<typename F> - void remove_if(F predicate) { - atfork_t* it = first_; - while (it != nullptr) { - if (predicate(it)) { - atfork_t* entry = it; - it = it->next; - remove(entry); - } else { - it = it->next; - } - } - } - - private: - void remove(atfork_t* entry) { - if (entry->prev != nullptr) { - entry->prev->next = entry->next; - } else { - first_ = entry->next; - } - - if (entry->next != nullptr) { - entry->next->prev = entry->prev; - } else { - last_ = entry->prev; - } - - free(entry); - } - - atfork_t* first_; - atfork_t* last_; - - DISALLOW_COPY_AND_ASSIGN(atfork_list_t); +struct atfork_list_t { + atfork_t* first; + atfork_t* last; }; static pthread_mutex_t g_atfork_list_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -static atfork_list_t g_atfork_list; +static atfork_list_t g_atfork_list = { NULL, NULL }; void __bionic_atfork_run_prepare() { // We lock the atfork list here, unlock it in the parent, and reset it in the child. // This ensures that nobody can modify the handler array between the calls // to the prepare and parent/child handlers. + // + // TODO: If a handler tries to mutate the list, they'll block. We should probably copy + // the list before forking, and have prepare, parent, and child all work on the consistent copy. pthread_mutex_lock(&g_atfork_list_mutex); // Call pthread_atfork() prepare handlers. POSIX states that the prepare // handlers should be called in the reverse order of the parent/child // handlers, so we iterate backwards. - g_atfork_list.walk_backwards([](atfork_t* it) { - if (it->prepare != nullptr) { + for (atfork_t* it = g_atfork_list.last; it != NULL; it = it->prev) { + if (it->prepare != NULL) { it->prepare(); } - }); + } } void __bionic_atfork_run_child() { - g_atfork_list.walk_forward([](atfork_t* it) { - if (it->child != nullptr) { + for (atfork_t* it = g_atfork_list.first; it != NULL; it = it->next) { + if (it->child != NULL) { it->child(); } - }); + } g_atfork_list_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; } void __bionic_atfork_run_parent() { - g_atfork_list.walk_forward([](atfork_t* it) { - if (it->parent != nullptr) { + for (atfork_t* it = g_atfork_list.first; it != NULL; it = it->next) { + if (it->parent != NULL) { it->parent(); } - }); + } pthread_mutex_unlock(&g_atfork_list_mutex); } -// __register_atfork is the name used by glibc -extern "C" int __register_atfork(void (*prepare)(void), void (*parent)(void), - void(*child)(void), void* dso) { +int pthread_atfork(void (*prepare)(void), void (*parent)(void), void(*child)(void)) { atfork_t* entry = reinterpret_cast<atfork_t*>(malloc(sizeof(atfork_t))); - if (entry == nullptr) { + if (entry == NULL) { return ENOMEM; } entry->prepare = prepare; entry->parent = parent; entry->child = child; - entry->dso_handle = dso; pthread_mutex_lock(&g_atfork_list_mutex); - g_atfork_list.push_back(entry); + // Append 'entry' to the list. + entry->next = NULL; + entry->prev = g_atfork_list.last; + if (entry->prev != NULL) { + entry->prev->next = entry; + } + if (g_atfork_list.first == NULL) { + g_atfork_list.first = entry; + } + g_atfork_list.last = entry; pthread_mutex_unlock(&g_atfork_list_mutex); return 0; } - -extern "C" __LIBC_HIDDEN__ void __unregister_atfork(void* dso) { - pthread_mutex_lock(&g_atfork_list_mutex); - g_atfork_list.remove_if([&](const atfork_t* entry) { - return entry->dso_handle == dso; - }); - pthread_mutex_unlock(&g_atfork_list_mutex); -} - diff --git a/libc/stdlib/atexit.c b/libc/upstream-openbsd/lib/libc/stdlib/atexit.c index df2b1b5d5..6532b382e 100644 --- a/libc/stdlib/atexit.c +++ b/libc/upstream-openbsd/lib/libc/stdlib/atexit.c @@ -35,15 +35,11 @@ #include <string.h> #include <unistd.h> #include "atexit.h" -#include "private/thread_private.h" +#include "thread_private.h" struct atexit *__atexit; static int restartloop; -/* BEGIN android-changed: __unregister_atfork is used by __cxa_finalize */ -extern void __unregister_atfork(void* dso); -/* END android-changed */ - /* * Function pointers are stored in a linked list of pages. The list * is initially empty, and pages are allocated on demand. The first @@ -66,7 +62,7 @@ __cxa_atexit(void (*func)(void *), void *arg, void *dso) { struct atexit *p = __atexit; struct atexit_fn *fnp; - size_t pgsize = getpagesize(); + int pgsize = getpagesize(); int ret = -1; if (pgsize < sizeof(*p)) @@ -165,12 +161,6 @@ restart: __atexit = NULL; } _ATEXIT_UNLOCK(); - - /* BEGIN android-changed: call __unregister_atfork if dso is not null */ - if (dso != NULL) { - __unregister_atfork(dso); - } - /* END android-changed */ } /* @@ -180,7 +170,7 @@ void __atexit_register_cleanup(void (*func)(void)) { struct atexit *p; - size_t pgsize = getpagesize(); + int pgsize = getpagesize(); if (pgsize < sizeof(*p)) return; diff --git a/libc/stdlib/atexit.h b/libc/upstream-openbsd/lib/libc/stdlib/atexit.h index 3de2aa3bf..3de2aa3bf 100644 --- a/libc/stdlib/atexit.h +++ b/libc/upstream-openbsd/lib/libc/stdlib/atexit.h |