summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Duncan Ogilvie2024-11-28 14:34:21 +0100
committerGravatar Duncan Ogilvie2024-11-28 14:34:21 +0100
commit3a1404c2e87daff1eb45c3f21182b7ede7a7a82b (patch)
tree2b20c20901e6275d24e1eb7424999c02d29978d1
parenta5df0a66409e565a46f6f73f988d3496b991c7c0 (diff)
downloadlibplist-3a1404c2e87daff1eb45c3f21182b7ede7a7a82b.tar.gz
libplist-3a1404c2e87daff1eb45c3f21182b7ede7a7a82b.tar.bz2
Switch to more generic global initializer method
-rw-r--r--src/plist.c115
1 files changed, 41 insertions, 74 deletions
diff --git a/src/plist.c b/src/plist.c
index a425466..79448db 100644
--- a/src/plist.c
+++ b/src/plist.c
@@ -59,15 +59,6 @@ static int plist_debug = 0;
59#define PLIST_ERR(...) 59#define PLIST_ERR(...)
60#endif 60#endif
61 61
62extern void plist_xml_init(void);
63extern void plist_xml_deinit(void);
64extern void plist_bin_init(void);
65extern void plist_bin_deinit(void);
66extern void plist_json_init(void);
67extern void plist_json_deinit(void);
68extern void plist_ostep_init(void);
69extern void plist_ostep_deinit(void);
70
71#ifndef bswap16 62#ifndef bswap16
72#define bswap16(x) ((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8)) 63#define bswap16(x) ((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8))
73#endif 64#endif
@@ -114,13 +105,41 @@ extern void plist_ostep_deinit(void);
114#endif 105#endif
115#endif 106#endif
116 107
117static void internal_plist_init(void) 108// Reference: https://stackoverflow.com/a/2390626/1806760
118{ 109// Initializer/finalizer sample for MSVC and GCC/Clang.
119 plist_bin_init(); 110// 2010-2016 Joe Lowe. Released into the public domain.
120 plist_xml_init(); 111
121 plist_json_init(); 112#ifdef __cplusplus
122 plist_ostep_init(); 113 #define INITIALIZER(f) \
123} 114 static void f(void); \
115 struct f##_t_ { f##_t_(void) { f(); } }; static f##_t_ f##_; \
116 static void f(void)
117#elif defined(_MSC_VER)
118 #pragma section(".CRT$XCU",read)
119 #define INITIALIZER2_(f,p) \
120 static void f(void); \
121 __declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \
122 __pragma(comment(linker,"/include:" p #f "_")) \
123 static void f(void)
124 #ifdef _WIN64
125 #define INITIALIZER(f) INITIALIZER2_(f,"")
126 #else
127 #define INITIALIZER(f) INITIALIZER2_(f,"_")
128 #endif
129#else
130 #define INITIALIZER(f) \
131 static void f(void) __attribute__((__constructor__)); \
132 static void f(void)
133#endif
134
135extern void plist_xml_init(void);
136extern void plist_xml_deinit(void);
137extern void plist_bin_init(void);
138extern void plist_bin_deinit(void);
139extern void plist_json_init(void);
140extern void plist_json_deinit(void);
141extern void plist_ostep_init(void);
142extern void plist_ostep_deinit(void);
124 143
125static void internal_plist_deinit(void) 144static void internal_plist_deinit(void)
126{ 145{
@@ -130,66 +149,14 @@ static void internal_plist_deinit(void)
130 plist_ostep_deinit(); 149 plist_ostep_deinit();
131} 150}
132 151
133#ifdef WIN32 152INITIALIZER(internal_plist_init)
134typedef volatile struct {
135 LONG lock;
136 int state;
137} thread_once_t;
138
139static thread_once_t init_once = {0, 0};
140static thread_once_t deinit_once = {0, 0};
141
142static void thread_once(thread_once_t *once_control, void (*init_routine)(void))
143{
144 while (InterlockedExchange(&(once_control->lock), 1) != 0) {
145 Sleep(1);
146 }
147 if (!once_control->state) {
148 once_control->state = 1;
149 init_routine();
150 }
151 InterlockedExchange(&(once_control->lock), 0);
152}
153#else
154static pthread_once_t init_once = PTHREAD_ONCE_INIT;
155static pthread_once_t deinit_once = PTHREAD_ONCE_INIT;
156#define thread_once pthread_once
157#endif
158
159#ifndef HAVE_ATTRIBUTE_CONSTRUCTOR
160 #if defined(__llvm__) || defined(__GNUC__)
161 #define HAVE_ATTRIBUTE_CONSTRUCTOR
162 #endif
163#endif
164
165#ifdef HAVE_ATTRIBUTE_CONSTRUCTOR
166static void __attribute__((constructor)) libplist_initialize(void)
167{ 153{
168 thread_once(&init_once, internal_plist_init); 154 plist_bin_init();
169} 155 plist_xml_init();
170 156 plist_json_init();
171static void __attribute__((destructor)) libplist_deinitialize(void) 157 plist_ostep_init();
172{ 158 atexit(internal_plist_deinit);
173 thread_once(&deinit_once, internal_plist_deinit);
174}
175#elif defined(WIN32)
176BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved)
177{
178 switch (dwReason) {
179 case DLL_PROCESS_ATTACH:
180 thread_once(&init_once, internal_plist_init);
181 break;
182 case DLL_PROCESS_DETACH:
183 thread_once(&deinit_once, internal_plist_deinit);
184 break;
185 default:
186 break;
187 }
188 return 1;
189} 159}
190#else
191#warning No compiler support for constructor/destructor attributes, some features might not be available.
192#endif
193 160
194#ifndef HAVE_MEMMEM 161#ifndef HAVE_MEMMEM
195// see https://sourceware.org/legacy-ml/libc-alpha/2007-12/msg00000.html 162// see https://sourceware.org/legacy-ml/libc-alpha/2007-12/msg00000.html