No more black magic on init/exit calls.
authorFlorent Bruneau <florent.bruneau@polytechnique.org>
Tue, 14 Oct 2008 22:21:10 +0000 (00:21 +0200)
committerFlorent Bruneau <florent.bruneau@polytechnique.org>
Tue, 14 Oct 2008 22:21:10 +0000 (00:21 +0200)
Signed-off-by: Florent Bruneau <florent.bruneau@polytechnique.org>
common.ld [deleted file]
common/common.c
common/common.h
mk/common.mk

diff --git a/common.ld b/common.ld
deleted file mode 100644 (file)
index e9b8470..0000000
--- a/common.ld
+++ /dev/null
@@ -1,10 +0,0 @@
-SECTIONS {
-    .rodata : {
-        . = ALIGN(8);
-        __madinit = . ;
-        *( MAD_INIT )
-        QUAD(0)
-        *( MAD_EXIT )
-        __madexit = . ;
-    }
-}
index dc0e194..9fdf961 100644 (file)
@@ -280,8 +280,16 @@ int common_setup(const char* pidfilename, bool unsafe, const char* runas_user,
     return EXIT_SUCCESS;
 }
 
-extern initcall_t __madinit[];
-extern exitcall_t __madexit[];
+#include "array.h"
+
+ARRAY(exitcall_t)
+
+static A(exitcall_t) __exit = ARRAY_INIT;
+
+void common_register_exit(exitcall_t _exit)
+{
+    array_add(__exit, _exit);
+}
 
 static void common_shutdown(void)
 {
@@ -289,23 +297,22 @@ static void common_shutdown(void)
         info("stopping...");
     }
     pidfile_close();
-    for (int i = -1; __madexit[i]; i--) {
-        (*__madexit[i])();
+    for (int i = array_len(__exit) - 1 ; i >= 0 ; --i) {
+        array_elt(__exit, i)();
     }
+    array_wipe(__exit);
 }
 
-static void __attribute__((__constructor__,__used__))
-common_initialize(void)
+void common_init(void)
 {
+    static bool __ran = false;
+    if (__ran) {
+        return;
+    }
     if (atexit(common_shutdown)) {
         fputs("Cannot hook my atexit function, quitting !\n", stderr);
         abort();
     }
-
-    for (int i = 0; __madinit[i]; i++) {
-        if ((*__madinit[i])()) {
-            exit(EXIT_FAILURE);
-        }
-    }
+    __ran = true;
 }
 
index 7a176a4..40eb0a2 100644 (file)
 typedef int  (*initcall_t)(void);
 typedef void (*exitcall_t)(void);
 
-#define __init __attribute__((__used__,__section__("MAD_INIT,__text,regular")))
-#define __exit __attribute__((__used__,__section__("MAD_EXIT,__text,regular")))
-
-#define module_init(fn)  static __init initcall_t __init_##fn = fn;
-#define module_exit(fn)  static __exit exitcall_t __exit_##fn = fn;
+void common_register_exit(exitcall_t _exit);
+void common_init(void);
+
+#define module_init(fn)                                                        \
+    __attribute__((constructor,used))                                          \
+    static void __init_wrapper__ ## fn (void) {                                \
+        common_init();                                                         \
+        if (fn() != 0) {                                                       \
+            exit(-1);                                                          \
+        }                                                                      \
+    }
+#define module_exit(fn)                                                        \
+    __attribute__((constructor,used))                                          \
+    static void __exit_wrapper ## fn(void) {                                   \
+        common_init();                                                         \
+        common_register_exit(fn);                                              \
+    }
 
 #define likely(expr)    __builtin_expect((expr) != 0, 1)
 #define unlikely(expr)  __builtin_expect((expr) != 0, 0)
index 7c81a6b..ace4e89 100644 (file)
@@ -1,7 +1,7 @@
 include ../mk/cflags.mk
 
 prefix ?= /usr/local
-LDFLAGS += -Wl,--warn-common -L/opt/local/lib
+LDFLAGS += -L/opt/local/lib
 CFLAGS  += --std=gnu99 -I../ -I../common -I/opt/local/include
 
 INSTALL_PROGS = $(addprefix install-,$(PROGRAMS))
@@ -50,7 +50,7 @@ $(LIBS:=.a): $$(patsubst %.c,.%.o,$$($$(patsubst %.a,%,$$@)_SOURCES)) Makefile
        $(AR) rcs $@ $(filter %.o,$^)
 
 $(PROGRAMS) $(TESTS): $$(patsubst %.c,.%.o,$$($$@_SOURCES)) Makefile ../common.ld
-       $(CC) -o $@ $(filter %.ld,$^) $(filter %.o,$^) $(LDFLAGS) $($@_LIBADD) $(filter %.a,$^)
+       $(CC) -o $@ $(filter %.o,$^) $(LDFLAGS) $($@_LIBADD) $(filter %.a,$^)
 
 -include $(foreach p,$(PROGRAMS) $(TESTS),$(patsubst %.c,.%.dep,$(filter %.c,$($p_SOURCES))))