Преглед на файлове

support __cxa_atexit, and registering atexit functions from atexit handlers

mildly tested; may have bugs. the locking should be updated not to use
spinlocks but that's outside the scope of this one module.
Rich Felker преди 13 години
родител
ревизия
b7c683be35
променени са 1 файла, в които са добавени 26 реда и са изтрити 7 реда
  1. 26 7
      src/exit/atexit.c

+ 26 - 7
src/exit/atexit.c

@@ -1,5 +1,6 @@
 #include <stddef.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <limits.h>
 #include "libc.h"
 
@@ -9,26 +10,33 @@
 static struct fl
 {
 	struct fl *next;
-	void (*f[COUNT])(void);
+	void (*f[COUNT])(void *);
+	void *a[COUNT];
 } builtin, *head;
 
+static int lock;
+
 void __funcs_on_exit()
 {
 	int i;
+	void (*func)(void *), *arg;
+	LOCK(&lock);
 	for (; head; head=head->next) {
 		for (i=COUNT-1; i>=0 && !head->f[i]; i--);
-		for (; i>=0; i--) head->f[i]();
+		if (i<0) continue;
+		func = head->f[i];
+		arg = head->a[i];
+		head->f[i] = 0;
+		UNLOCK(&lock);
+		func(arg);
+		LOCK(&lock);
 	}
 }
 
-int atexit(void (*func)(void))
+int __cxa_atexit(void (*func)(void *), void *arg, void *dso)
 {
-	static int lock;
 	int i;
 
-	/* Hook for atexit extensions */
-	if (libc.atexit) return libc.atexit(func);
-
 	LOCK(&lock);
 
 	/* Defer initialization of head so it can be in BSS */
@@ -48,7 +56,18 @@ int atexit(void (*func)(void))
 	/* Append function to the list. */
 	for (i=0; i<COUNT && head->f[i]; i++);
 	head->f[i] = func;
+	head->a[i] = arg;
 
 	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);
+}