1// Copyright 2017 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "libc.h"
6#include "threads_impl.h"
7#include <stdint.h>
8#include <stdlib.h>
9#include <threads.h>
10
11struct tls_dtor {
12    struct tls_dtor* next;
13    void (*func)(void*);
14    void* arg;
15};
16
17void __tls_run_dtors(void) {
18    struct tls_dtor *cur;
19    thrd_t self = __thrd_current();
20    while (self->tls_dtors) {
21        cur = self->tls_dtors;
22        self->tls_dtors = self->tls_dtors->next;
23        cur->func(cur->arg);
24        free(cur);
25    }
26}
27
28int __cxa_thread_atexit_impl(void (*func)(void*), void* arg, void* dso) {
29    struct tls_dtor* new_td = malloc(sizeof(struct tls_dtor));
30    if (!new_td) {
31        return -1;
32    }
33    new_td->func = func;
34    new_td->arg = arg;
35
36    // Prepend function to the list, the thread local destructors have to be
37    // called in an order determined by the sequenced-before rule according to
38    // C++ standard [basic.start.term].
39    thrd_t self = __thrd_current();
40    new_td->next = self->tls_dtors;
41    self->tls_dtors = new_td;
42
43    return 0;
44}
45