diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2018-12-27 15:36:51 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2018-12-27 15:36:51 +0000 |
commit | 05fa8834c6644f12405ea713c48693bf2d1864f1 (patch) | |
tree | c6b6391884370c75972a2e432d42ebbb076a0cdf /stdlib/cxa_atexit.c | |
parent | 525c181a5a9a95e24d2111b7792608151a40eb84 (diff) | |
parent | 963c37d5c0eb62b38f8764b23931c0dcdd497a13 (diff) |
Merge commit 'refs/top-bases/t/bigmem' into t/bigmemt/bigmem
Diffstat (limited to 'stdlib/cxa_atexit.c')
-rw-r--r-- | stdlib/cxa_atexit.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/stdlib/cxa_atexit.c b/stdlib/cxa_atexit.c index 61c6e51294..6d65f7e615 100644 --- a/stdlib/cxa_atexit.c +++ b/stdlib/cxa_atexit.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1999-2016 Free Software Foundation, Inc. +/* Copyright (C) 1999-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -21,21 +21,29 @@ #include <libc-lock.h> #include "exit.h" -#include <atomic.h> #include <sysdep.h> #undef __cxa_atexit +/* See concurrency notes in stdlib/exit.h where this lock is declared. */ +__libc_lock_define_initialized (, __exit_funcs_lock) + int attribute_hidden __internal_atexit (void (*func) (void *), void *arg, void *d, struct exit_function_list **listp) { - struct exit_function *new = __new_exitfn (listp); + struct exit_function *new; + + __libc_lock_lock (__exit_funcs_lock); + new = __new_exitfn (listp); if (new == NULL) - return -1; + { + __libc_lock_unlock (__exit_funcs_lock); + return -1; + } #ifdef PTR_MANGLE PTR_MANGLE (func); @@ -43,8 +51,8 @@ __internal_atexit (void (*func) (void *), void *arg, void *d, new->func.cxa.fn = (void (*) (void *, int)) func; new->func.cxa.arg = arg; new->func.cxa.dso_handle = d; - atomic_write_barrier (); new->flavor = ef_cxa; + __libc_lock_unlock (__exit_funcs_lock); return 0; } @@ -60,14 +68,11 @@ __cxa_atexit (void (*func) (void *), void *arg, void *d) libc_hidden_def (__cxa_atexit) -/* We change global data, so we need locking. */ -__libc_lock_define_initialized (static, lock) - - static struct exit_function_list initial; struct exit_function_list *__exit_funcs = &initial; uint64_t __new_exitfn_called; +/* Must be called with __exit_funcs_lock held. */ struct exit_function * __new_exitfn (struct exit_function_list **listp) { @@ -76,7 +81,10 @@ __new_exitfn (struct exit_function_list **listp) struct exit_function *r = NULL; size_t i = 0; - __libc_lock_lock (lock); + if (__exit_funcs_done) + /* Exit code is finished processing all registered exit functions, + therefore we fail this registration. */ + return NULL; for (l = *listp; l != NULL; p = l, l = l->next) { @@ -127,7 +135,5 @@ __new_exitfn (struct exit_function_list **listp) ++__new_exitfn_called; } - __libc_lock_unlock (lock); - return r; } |