X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Fexit%2Fatexit.c;h=160d277aeb76a3837f856052ec9b93653eabdb2b;hb=370679ba984d8a466d635234dc7a3084e98c0071;hp=6f00e374395501dcbb9b932eed4c070187ff53db;hpb=f753049a50132a23849ef89a8af5ff86ad595c25;p=musl diff --git a/src/exit/atexit.c b/src/exit/atexit.c index 6f00e374..160d277a 100644 --- a/src/exit/atexit.c +++ b/src/exit/atexit.c @@ -1,7 +1,7 @@ -#include #include -#include +#include #include "libc.h" +#include "lock.h" /* Ensure that at least 32 atexit handlers can be registered without malloc */ #define COUNT 32 @@ -9,46 +9,64 @@ static struct fl { struct fl *next; - void (*f[COUNT])(void); + void (*f[COUNT])(void *); + void *a[COUNT]; } builtin, *head; +static int slot; +static volatile int lock[1]; + void __funcs_on_exit() { - int i; - for (; head; head=head->next) { - for (i=COUNT-1; i>=0 && !head->f[i]; i--); - for (; i>=0; i--) head->f[i](); + void (*func)(void *), *arg; + LOCK(lock); + for (; head; head=head->next, slot=COUNT) while(slot-->0) { + func = head->f[slot]; + arg = head->a[slot]; + UNLOCK(lock); + func(arg); + LOCK(lock); } } -int atexit(void (*func)(void)) +void __cxa_finalize(void *dso) { - static int lock; - int i; - - /* Hook for atexit extensions */ - if (libc.atexit) return libc.atexit(func); +} - LOCK(&lock); +int __cxa_atexit(void (*func)(void *), void *arg, void *dso) +{ + LOCK(lock); /* Defer initialization of head so it can be in BSS */ if (!head) head = &builtin; /* If the current function list is full, add a new one */ - if (head->f[COUNT-1]) { + if (slot==COUNT) { struct fl *new_fl = calloc(sizeof(struct fl), 1); if (!new_fl) { - UNLOCK(&lock); + UNLOCK(lock); return -1; } new_fl->next = head; head = new_fl; + slot = 0; } /* Append function to the list. */ - for (i=0; if[i]; i++); - head->f[i] = func; + head->f[slot] = func; + head->a[slot] = arg; + slot++; - UNLOCK(&lock); + UNLOCK(lock); return 0; } + +static void call(void *p) +{ + ((void (*)(void))(uintptr_t)p)(); +} + +int atexit(void (*func)(void)) +{ + return __cxa_atexit(call, (void *)(uintptr_t)func, 0); +}