mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-24 05:32:21 +00:00
d13a9281bd
We currently have to deal with multiple initialization stages in a way that can be confusing, because certain parts rely on others having been properly initialized. Most calls consist in adding lists to existing lists, whose heads are initialized in the declaration so this is easy. But some calls create new pools and require pools to be properly initialized. Pools currently are thread-local and as such cannot be pre-initialized, requiring run-time checks. All this could be simplified by using multiple boot stages and allowing functions to be registered at various stages. One approach might be to use gcc's constructor priorities, but this requires gcc >= 4.3 which eliminates a wide spectrum of working compilers, and some versions of certain compilers (like clang 3.0) are known for silently ignore these priorities. Instead we can use our own init function registration mechanism. A first attempt was made using register_function() calls in all constructors but this made the code more painful. This patch's approach is different. It creates sections containing arrays of pointers to "initcall" descriptors. An initcall contains a pointer to a function and an argument. Each section corresponds to a specific initialization stage. Each module creates such descriptors for various calls it requires. The main() function starts by scanning each of these sections in turn to process these initcalls. This will make it possible to remove many constructors from various modules, by simply placing initcalls for the requested functions next to the keyword lists that need to be called. A first attempt was made by placing the initcalls directly into the sections instead of creating an array of pointers, but it becomes sensitive to the array's alignment which depends on the compiler and the linker, so it seems too fragile. For now we support 6 init stages : - STG_PREPARE : preset variables, tables and list heads - STG_LOCK : initialize spinlocks and rwlocks - STG_ALLOC : allocate the required structures - STG_POOL : create pools - STG_REGISTER : register static lists (keywords etc) - STG_INIT : subsystems normal initialization These ones are declared directly in the files where they are needed using one of the INITCALL* macros, passing 0 to 3 pointers as arguments. The API should possibly be extended to support a return value to give a status to the caller, and to support a unified API, possibly a bit more flexibility in the arguments. In this case it might make sense to support a set of macros to register functions having a different API and to pass the function type in the initcall itself. Special thanks to Olivier for showing how to scan sections as this is not something particularly well documented and exactly what I've been missing to achieve this. |
||
---|---|---|
.. | ||
accept4.h | ||
base64.h | ||
buf.h | ||
buffer.h | ||
cfgparse.h | ||
chunk.h | ||
compat.h | ||
compiler.h | ||
config.h | ||
debug.h | ||
defaults.h | ||
epoll.h | ||
errors.h | ||
h2.h | ||
hash.h | ||
hathreads.h | ||
hpack-dec.h | ||
hpack-enc.h | ||
hpack-huff.h | ||
hpack-tbl.h | ||
http-hdr.h | ||
http.h | ||
initcall.h | ||
ist.h | ||
istbuf.h | ||
memory.h | ||
mini-clist.h | ||
namespace.h | ||
net_helper.h | ||
regex.h | ||
splice.h | ||
standard.h | ||
syscall.h | ||
template.h | ||
ticks.h | ||
time.h | ||
tools.h | ||
uri_auth.h | ||
version.h | ||
xref.h |