xref: /netbsd-src/external/bsd/libc++/dist/libcxxrt/src/cxa_atexit.c (revision ccec91a1a97277b5fa1e64b269648792fb078e34)
1*ccec91a1Sjoerg /**
2*ccec91a1Sjoerg  * Copyright (c) 2012 David Chisnall.
3*ccec91a1Sjoerg  *
4*ccec91a1Sjoerg  * Permission is hereby granted, free of charge, to any person obtaining a copy
5*ccec91a1Sjoerg  * of this software and associated documentation files (the "Software"), to
6*ccec91a1Sjoerg  * deal in the Software without restriction, including without limitation the
7*ccec91a1Sjoerg  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8*ccec91a1Sjoerg  * sell copies of the Software, and to permit persons to whom the Software is
9*ccec91a1Sjoerg  * furnished to do so, subject to the following conditions:
10*ccec91a1Sjoerg  *
11*ccec91a1Sjoerg  * The above copyright notice and this permission notice shall be included in
12*ccec91a1Sjoerg  * all copies or substantial portions of the Software.
13*ccec91a1Sjoerg  *
14*ccec91a1Sjoerg  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*ccec91a1Sjoerg  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*ccec91a1Sjoerg  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17*ccec91a1Sjoerg  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18*ccec91a1Sjoerg  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19*ccec91a1Sjoerg  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20*ccec91a1Sjoerg  * IN THE SOFTWARE.
21*ccec91a1Sjoerg  *
22*ccec91a1Sjoerg  */
23*ccec91a1Sjoerg 
24*ccec91a1Sjoerg /* Special thanks to TBricks for partially funding this work */
25*ccec91a1Sjoerg 
26*ccec91a1Sjoerg #ifdef __sun__
27*ccec91a1Sjoerg #include <pthread.h>
28*ccec91a1Sjoerg #include <stdlib.h>
29*ccec91a1Sjoerg 
30*ccec91a1Sjoerg static struct atexit_handler {
31*ccec91a1Sjoerg   void (*f)(void *);
32*ccec91a1Sjoerg   void *p;
33*ccec91a1Sjoerg   void *d;
34*ccec91a1Sjoerg   struct atexit_handler *next;
35*ccec91a1Sjoerg } *head;
36*ccec91a1Sjoerg 
37*ccec91a1Sjoerg static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
38*ccec91a1Sjoerg 
__cxa_atexit(void (* f)(void *),void * p,void * d)39*ccec91a1Sjoerg int __cxa_atexit( void (*f)(void *), void *p, void *d) {
40*ccec91a1Sjoerg   pthread_mutex_lock(&lock);
41*ccec91a1Sjoerg   struct atexit_handler *h = malloc(sizeof(*h));
42*ccec91a1Sjoerg   if (!h) {
43*ccec91a1Sjoerg     pthread_mutex_unlock(&lock);
44*ccec91a1Sjoerg     return 1;
45*ccec91a1Sjoerg   }
46*ccec91a1Sjoerg   h->f = f;
47*ccec91a1Sjoerg   h->p = p;
48*ccec91a1Sjoerg   h->d = d;
49*ccec91a1Sjoerg   h->next = head;
50*ccec91a1Sjoerg   head = h;
51*ccec91a1Sjoerg   pthread_mutex_unlock(&lock);
52*ccec91a1Sjoerg   return 0;
53*ccec91a1Sjoerg }
54*ccec91a1Sjoerg 
__cxa_finalize(void * d)55*ccec91a1Sjoerg void __cxa_finalize(void *d ) {
56*ccec91a1Sjoerg   pthread_mutex_lock(&lock);
57*ccec91a1Sjoerg   struct atexit_handler **last = &head;
58*ccec91a1Sjoerg   for (struct atexit_handler *h = head ; h ; h = h->next) {
59*ccec91a1Sjoerg     if ((h->d == d) || (d == 0)) {
60*ccec91a1Sjoerg       *last = h->next;
61*ccec91a1Sjoerg       h->f(h->p);
62*ccec91a1Sjoerg       free(h);
63*ccec91a1Sjoerg     } else {
64*ccec91a1Sjoerg       last = &h->next;
65*ccec91a1Sjoerg     }
66*ccec91a1Sjoerg   }
67*ccec91a1Sjoerg   pthread_mutex_unlock(&lock);
68*ccec91a1Sjoerg }
69*ccec91a1Sjoerg #endif
70