diff options
| author | 2024-11-28 14:34:21 +0100 | |
|---|---|---|
| committer | 2024-11-28 14:34:21 +0100 | |
| commit | 3a1404c2e87daff1eb45c3f21182b7ede7a7a82b (patch) | |
| tree | 2b20c20901e6275d24e1eb7424999c02d29978d1 /src | |
| parent | a5df0a66409e565a46f6f73f988d3496b991c7c0 (diff) | |
| download | libplist-3a1404c2e87daff1eb45c3f21182b7ede7a7a82b.tar.gz libplist-3a1404c2e87daff1eb45c3f21182b7ede7a7a82b.tar.bz2 | |
Switch to more generic global initializer method
Diffstat (limited to 'src')
| -rw-r--r-- | src/plist.c | 115 |
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 | ||
| 62 | extern void plist_xml_init(void); | ||
| 63 | extern void plist_xml_deinit(void); | ||
| 64 | extern void plist_bin_init(void); | ||
| 65 | extern void plist_bin_deinit(void); | ||
| 66 | extern void plist_json_init(void); | ||
| 67 | extern void plist_json_deinit(void); | ||
| 68 | extern void plist_ostep_init(void); | ||
| 69 | extern 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 | ||
| 117 | static 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 | |||
| 135 | extern void plist_xml_init(void); | ||
| 136 | extern void plist_xml_deinit(void); | ||
| 137 | extern void plist_bin_init(void); | ||
| 138 | extern void plist_bin_deinit(void); | ||
| 139 | extern void plist_json_init(void); | ||
| 140 | extern void plist_json_deinit(void); | ||
| 141 | extern void plist_ostep_init(void); | ||
| 142 | extern void plist_ostep_deinit(void); | ||
| 124 | 143 | ||
| 125 | static void internal_plist_deinit(void) | 144 | static 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 | 152 | INITIALIZER(internal_plist_init) |
| 134 | typedef volatile struct { | ||
| 135 | LONG lock; | ||
| 136 | int state; | ||
| 137 | } thread_once_t; | ||
| 138 | |||
| 139 | static thread_once_t init_once = {0, 0}; | ||
| 140 | static thread_once_t deinit_once = {0, 0}; | ||
| 141 | |||
| 142 | static 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 | ||
| 154 | static pthread_once_t init_once = PTHREAD_ONCE_INIT; | ||
| 155 | static 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 | ||
| 166 | static 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(); | |
| 171 | static 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) | ||
| 176 | BOOL 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 |
