aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2014-12-22 19:43:04 +0000
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2014-12-22 19:43:04 +0000
commit9303922d4787ef1d166264d452c0608323e7bead (patch)
tree850dcf658c1ac3e8986667d09cd21d77cb74054b
parent684be54c9fd602b52870ea3c477e435aae4e5b49 (diff)
downloadlibmicrohttpd-9303922d4787ef1d166264d452c0608323e7bead.tar.gz
libmicrohttpd-9303922d4787ef1d166264d452c0608323e7bead.zip
Add and use header for multiplatform support of Init/Deinit functions
-rw-r--r--src/include/autoinit_funcs.h242
-rw-r--r--src/microhttpd/daemon.c15
2 files changed, 247 insertions, 10 deletions
diff --git a/src/include/autoinit_funcs.h b/src/include/autoinit_funcs.h
new file mode 100644
index 00000000..dfc54616
--- /dev/null
+++ b/src/include/autoinit_funcs.h
@@ -0,0 +1,242 @@
1/*
2 * AutoinitFuncs: Automatic Initialization and Deinitialization Functions
3 * Copyright(C) 2014 Karlson2k (Evgeny Grin)
4 *
5 * This header is free software; you can redistribute it and / or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This header is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this header; if not, see
17 * <http://www.gnu.org/licenses/>.
18 */
19
20/*
21 General usage is simple: include this header, declare or define two
22 functions with zero parameters (void) and any return type: one for
23 initialization and one for deinitialization, add
24 _SET_INIT_AND_DEINIT_FUNCS(FuncInitName, FuncDeInitName) to the code
25 and functions will be automatically called during application startup
26 and shutdown.
27 This is useful for libraries as libraries doesn't have direct access
28 to main() functions.
29 Example:
30 -------------------------------------------------
31 #include <stdlib.h>
32 #include "autoinit_funcs.h"
33
34 int someVar;
35 void* somePtr;
36
37 void libInit(void)
38 {
39 someVar = 3;
40 somePtr = malloc(100);
41 }
42
43 void libDeinit(void)
44 {
45 free(somePtr);
46 }
47
48 _SET_INIT_AND_DEINIT_FUNCS(libInit,libDeinit);
49 -------------------------------------------------
50
51 If initializer or deinitializer functions is not needed, just define
52 it as empty function.
53
54 This header should work with GCC, clang, MSVC (2010 or later).
55 Supported C and C++ languages; application, static and dynamic (DLL)
56 libraries; non-optimized (Debug) and optimized (Release) compilation
57 and linking.
58
59 For more information see header code and comments in code.
60 */
61#ifndef AUTOINIT_FUNCS_INCLUDED
62#define AUTOINIT_FUNCS_INCLUDED 1
63
64/**
65* Current version of the header.
66* 0x01093001 = 1.9.30-1.
67*/
68#define AUTOINIT_FUNCS_VERSION 0x01000001
69
70#if defined(__GNUC__)
71#/* if possible - check for supported attribute */
72#ifdef __has_attribute
73#if !__has_attribute(constructor) || !__has_attribute(destructor)
74#define _GNUC_ATTR_CONSTR_NOT_SUPPORTED 1
75#endif /* !__has_attribute(constructor) || !__has_attribute(destructor) */
76#endif /* __has_attribute */
77#endif /* __GNUC__ */
78
79#if defined(__GNUC__) && !defined(_GNUC_ATTR_CONSTR_NOT_SUPPORTED)
80
81#define GNUC_SET_INIT_AND_DEINIT(FI,FD) \
82 void __attribute__ ((constructor)) _GNUC_init_helper_##FI(void) \
83 { (void)(FI)(); } \
84 void __attribute__ ((destructor)) _GNUC_deinit_helper_##FD(void) \
85 { (void)(FD)(); } \
86 struct _GNUC_dummy_str_##FI{int i;}
87
88#define _SET_INIT_AND_DEINIT_FUNCS(FI,FD) GNUC_SET_INIT_AND_DEINIT(FI,FD)
89#define _AUTOINIT_FUNCS_ARE_SUPPORTED 1
90
91#elif defined (_MSC_FULL_VER) && _MSC_VER+0 >= 1600
92
93/* Make sure that your project/sources define:
94 _LIB if building a static library (_LIB is ignored if _CONSOLE is defined);
95 _USRDLL if building DLL-library;
96 not defined both _LIB and _USRDLL if building an application */
97
98/* Define AUTOINIT_FUNCS_DECLARE_STATIC_REG if you need macro declaration
99 for registering static initialization functions even if you building DLL */
100/* Define AUTOINIT_FUNCS_FORCE_STATIC_REG if you want to set main macro
101 _SET_INIT_AND_DEINIT_FUNCS to static version even if building a DLL*/
102
103/* Stringify macros */
104#define _INSTRMACRO(a) #a
105#define _STRMACRO(a) _INSTRMACRO(a)
106
107#if !defined(_USRDLL) || defined(AUTOINIT_FUNCS_DECLARE_STATIC_REG)
108
109/* required for atexit() */
110#include <stdlib.h>
111
112/* Use "C" linkage for variable to simplify variable decoration */
113#ifdef __cplusplus
114#define W32_INITVARDECL extern "C"
115#else
116#define W32_INITVARDECL extern
117#endif
118
119/* How variable is decorated by compiler */
120#if defined(_M_X64) || defined(_M_AMD64)
121#define W32_VARDECORPREFIX
122#define W32_DECORVARNAME(v) v
123#define W32_VARDECORPEFIXSTR ""
124#elif defined(_M_IX86) || defined(_X86_)
125#define W32_VARDECORPREFIX _
126#define W32_DECORVARNAME(v) _##v
127#define W32_VARDECORPEFIXSTR "_"
128#else
129#error Do not know how to decorate symbols for this architecture
130#endif
131
132/* Internal variable prefix (can be any) */
133#define W32_INITHELPERVARNAME(f) _initHelperDummy_##f
134#define W32_INITHELPERVARNAMEDECORSTR(f) W32_VARDECORPEFIXSTR _STRMACRO(W32_INITHELPERVARNAME(f))
135
136/* Declare section (segment), put variable pointing to init function to chosen segment,
137 force linker to include variable to avoid omitting by optimizer */
138/* Initialization function must be declared as
139 int __cdecl FuncName(void) */
140/* Return value is ignored for C++ initializers */
141/* For C initializers: startup process is aborted if initializer return non-zero */
142#define W32_FPTR_IN_SEG(S,F) \
143 __pragma(section(S,long,read)) \
144 __pragma(comment(linker, "/INCLUDE:" W32_INITHELPERVARNAMEDECORSTR(F))) \
145 W32_INITVARDECL __declspec(allocate(S)) int(__cdecl *W32_INITHELPERVARNAME(F))(void) = &F
146
147/* Section (segment) names for pointers to initializers */
148#define W32_SEG_INIT_C_USER ".CRT$XCU"
149#define W32_SEG_INIT_C_LIB ".CRT$XCL"
150#define W32_SEG_INIT_CXX_USER ".CRT$XIU"
151#define W32_SEG_INIT_CXX_LIB ".CRT$XIL"
152
153/* Declare macro for different initializers sections */
154/* Macro can be used several times to register several initializers */
155/* Once function is registered as initializer, it will be called automatically
156 during application startup */
157/* "lib" initializers are called before "user" initializers */
158/* "C" initializers are called before "C++" initializers */
159#define W32_REG_INIT_C_USER(F) W32_FPTR_IN_SEG(W32_SEG_INIT_C_USER,F)
160#define W32_REG_INIT_C_LIB(F) W32_FPTR_IN_SEG(W32_SEG_INIT_C_LIB,F)
161#define W32_REG_INIT_CXX_USER(F) W32_FPTR_IN_SEG(W32_SEG_INIT_CXX_USER,F)
162#define W32_REG_INIT_CXX_LIB(F) W32_FPTR_IN_SEG(W32_SEG_INIT_CXX_LIB,F)
163
164/* Choose main register macro based on language and program type */
165/* Assuming that _LIB or _USRDLL is defined for static or DLL-library */
166/* Macro can be used several times to register several initializers */
167/* Once function is registered as initializer, it will be called automatically
168 during application startup */
169/* Define AUTOINIT_FUNCS_FORCE_USER_LVL_INIT to register initializers
170 at user level even if building library */
171#ifdef __cplusplus
172#if ((defined(_LIB) && !defined(_CONSOLE)) || defined(_USRDLL)) && !defined(AUTOINIT_FUNCS_FORCE_USER_LVL_INIT)
173#define W32_REGISTER_INIT(F) W32_REG_INIT_CXX_LIB(F)
174#else /* ! _LIB && ! _DLL */
175#define W32_REGISTER_INIT(F) W32_REG_INIT_CXX_USER(F)
176#endif /* ! _LIB && ! _DLL */
177#else /* !__cplusplus*/
178#if ((defined(_LIB) && !defined(_CONSOLE)) || defined(_USRDLL)) && !defined(AUTOINIT_FUNCS_FORCE_USER_LVL_INIT)
179#define W32_REGISTER_INIT(F) W32_REG_INIT_C_LIB(F)
180#else /* ! _LIB && ! _DLL */
181#define W32_REGISTER_INIT(F) W32_REG_INIT_C_USER(F)
182#endif /* ! _LIB && ! _DLL */
183#endif /* !__cplusplus*/
184
185#else /* _USRDLL */
186
187#ifndef WIN32_LEAN_AND_MEAN
188#define WIN32_LEAN_AND_MEAN 1
189#endif /* WIN32_LEAN_AND_MEAN */
190/* Required for DllMain */
191#include <Windows.h>
192#endif /* _USRDLL */
193
194
195#if !defined(_USRDLL) || defined(AUTOINIT_FUNCS_FORCE_STATIC_REG)
196#define W32_SET_INIT_AND_DEINIT(FI,FD) \
197 void __cdecl _W32_deinit_helper_##FD(void) \
198 { (void)(FD)(); } \
199 int __cdecl _W32_init_helper_##FI(void) \
200 { (void)(FI)(); atexit(_W32_deinit_helper_##FD); return 0; } \
201 W32_REGISTER_INIT(_W32_init_helper_##FI)
202#else /* _USRDLL */
203
204/* If DllMain is already present in code, define AUTOINIT_FUNCS_CALL_USR_DLLMAIN
205 and rename DllMain to usr_DllMain */
206#ifndef AUTOINIT_FUNCS_CALL_USR_DLLMAIN
207#define W32_SET_INIT_AND_DEINIT(FI,FD) \
208 BOOL WINAPI DllMain(HINSTANCE hinst,DWORD reason,LPVOID unused) \
209 { if(DLL_PROCESS_ATTACH==reason) {(void)(FI)();} \
210 else if(DLL_PROCESS_DETACH==reason) {(void)(FD)();} \
211 return TRUE; \
212 } struct _W32_dummy_strc_##FI{int i;}
213#else /* AUTOINIT_FUNCS_CALL_USR_DLLMAIN */
214#define W32_SET_INIT_AND_DEINIT(FI,FD) \
215 BOOL WINAPI usr_DllMain(HINSTANCE hinst,DWORD reason,LPVOID unused); \
216 BOOL WINAPI DllMain(HINSTANCE hinst,DWORD reason,LPVOID unused) \
217 { if(DLL_PROCESS_ATTACH==reason) {(void)(FI)();} \
218 else if(DLL_PROCESS_DETACH==reason) {(void)(FD)();} \
219 return usr_DllMain(hinst,reason,unused); \
220 } struct _W32_dummy_strc_##FI{int i;}
221#endif /* AUTOINIT_FUNCS_CALL_USR_DLLMAIN */
222#endif /* _USRDLL */
223
224#define _SET_INIT_AND_DEINIT_FUNCS(FI,FD) W32_SET_INIT_AND_DEINIT(FI,FD)
225/* Indicate that automatic initializers/deinitializers are supported */
226#define _AUTOINIT_FUNCS_ARE_SUPPORTED 1
227
228#else /* !__GNUC__ && !_MSC_FULL_VER */
229
230/* Define EMIT_ERROR_IF_AUTOINIT_FUNCS_ARE_NOT_SUPPORTED before inclusion of header to
231 abort compilation if automatic initializers/deinitializers are not supported */
232#ifdef EMIT_ERROR_IF_AUTOINIT_FUNCS_ARE_NOT_SUPPORTED
233#error Compiler/platform don not support automatic calls of user-defined initializer and deinitializer
234#endif /* EMIT_ERROR_IF_AUTOINIT_FUNCS_ARE_NOT_SUPPORTED */
235
236/* Do nothing */
237#define _SET_INIT_AND_DEINIT_FUNCS(FI,FD)
238/* Indicate that automatic initializers/deinitializers are not supported */
239#define _AUTOINIT_FUNCS_ARE_NOT_SUPPORTED 1
240
241#endif /* !__GNUC__ && !_MSC_FULL_VER */
242#endif /* !AUTOINIT_FUNCS_INCLUDED */
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 66453094..0816a4a9 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -37,6 +37,7 @@
37#include "connection.h" 37#include "connection.h"
38#include "memorypool.h" 38#include "memorypool.h"
39#include <limits.h> 39#include <limits.h>
40#include "autoinit_funcs.h"
40 41
41#if HAVE_SEARCH_H 42#if HAVE_SEARCH_H
42#include <search.h> 43#include <search.h>
@@ -4538,14 +4539,6 @@ MHD_is_feature_supported(enum MHD_FEATURE feature)
4538} 4539}
4539 4540
4540 4541
4541#ifdef __GNUC__
4542#define FUNC_CONSTRUCTOR(f) static void __attribute__ ((constructor)) f
4543#define FUNC_DESTRUCTOR(f) static void __attribute__ ((destructor)) f
4544#else // !__GNUC__
4545#define FUNC_CONSTRUCTOR(f) _MHD_EXTERN void f
4546#define FUNC_DESTRUCTOR(f) _MHD_EXTERN void f
4547#endif // __GNUC__
4548
4549#if HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600 4542#if HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600
4550#if defined(MHD_USE_POSIX_THREADS) 4543#if defined(MHD_USE_POSIX_THREADS)
4551GCRY_THREAD_OPTION_PTHREAD_IMPL; 4544GCRY_THREAD_OPTION_PTHREAD_IMPL;
@@ -4587,7 +4580,7 @@ static struct gcry_thread_cbs gcry_threads_w32 = {
4587/** 4580/**
4588 * Initialize do setup work. 4581 * Initialize do setup work.
4589 */ 4582 */
4590FUNC_CONSTRUCTOR (MHD_init) () 4583void MHD_init(void)
4591{ 4584{
4592 mhd_panic = &mhd_panic_std; 4585 mhd_panic = &mhd_panic_std;
4593 mhd_panic_cls = NULL; 4586 mhd_panic_cls = NULL;
@@ -4619,7 +4612,7 @@ FUNC_CONSTRUCTOR (MHD_init) ()
4619} 4612}
4620 4613
4621 4614
4622FUNC_DESTRUCTOR (MHD_fini) () 4615void MHD_fini(void)
4623{ 4616{
4624#if HTTPS_SUPPORT 4617#if HTTPS_SUPPORT
4625 gnutls_global_deinit (); 4618 gnutls_global_deinit ();
@@ -4630,5 +4623,7 @@ FUNC_DESTRUCTOR (MHD_fini) ()
4630#endif 4623#endif
4631} 4624}
4632 4625
4626_SET_INIT_AND_DEINIT_FUNCS(MHD_init, MHD_fini);
4627
4633/* end of daemon.c */ 4628/* end of daemon.c */
4634 4629