summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Chisnall <theraven@theravensnest.org>2012-02-28 19:20:58 +0000
committerDavid Chisnall <theraven@theravensnest.org>2012-02-28 19:20:58 +0000
commitb9c89de0416513998e06bf23115191717416a416 (patch)
treeba3a0302e9f21c13f49c3443d00e3e84d5daa1fa /src
parent69c4c6f192271918d1bf64a84d3f8a41d1e943ac (diff)
downloadlibcxxrt-b9c89de0416513998e06bf23115191717416a416.tar.gz
libcxxrt-b9c89de0416513998e06bf23115191717416a416.tar.bz2
libcxxrt-b9c89de0416513998e06bf23115191717416a416.tar.xz
Add some stuff that's missing on Solaris (required for correctly running
static destructors).
Diffstat (limited to 'src')
-rw-r--r--src/cxa_atexit.c44
-rw-r--r--src/cxa_finalize.c8
2 files changed, 52 insertions, 0 deletions
diff --git a/src/cxa_atexit.c b/src/cxa_atexit.c
new file mode 100644
index 0000000..48d6d1d
--- /dev/null
+++ b/src/cxa_atexit.c
@@ -0,0 +1,44 @@
+#ifdef __sun__
+#include <pthread.h>
+#include <stdlib.h>
+
+static struct atexit_handler {
+ void (*f)(void *);
+ void *p;
+ void *d;
+ struct atexit_handler *next;
+} *head;
+
+static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+
+int __cxa_atexit( void (*f)(void *), void *p, void *d) {
+ pthread_mutex_lock(&lock);
+ struct atexit_handler *h = malloc(sizeof(*d));
+ if (!h) {
+ pthread_mutex_unlock(&lock);
+ return 1;
+ }
+ h->f = f;
+ h->p = p;
+ h->d = d;
+ h->next = head;
+ head = h;
+ pthread_mutex_unlock(&lock);
+ return 0;
+}
+
+void __cxa_finalize(void *d ) {
+ pthread_mutex_lock(&lock);
+ struct atexit_handler **last = &head;
+ for (struct atexit_handler *h = head ; h ; h = h->next) {
+ if ((h->d == d) || (d == 0)) {
+ *last = h->next;
+ h->f(h->p);
+ free(h);
+ } else {
+ last = &head->next;
+ }
+ }
+ pthread_mutex_unlock(&lock);
+}
+#endif
diff --git a/src/cxa_finalize.c b/src/cxa_finalize.c
new file mode 100644
index 0000000..c870ca8
--- /dev/null
+++ b/src/cxa_finalize.c
@@ -0,0 +1,8 @@
+void __cxa_finalize(void *d );
+
+extern void __dso_handle;
+
+__attribute((destructor))
+static void cleanup(void) {
+ __cxa_finalize(&__dso_handle);
+}