Child Initialization
static void module_child_init(server_rec *pServer,pool *pPool)
An Apache server may consist of many processes (on Unix, for example)
or a single process with many threads (on Win32) or, in the future, a
combination of the two. module_child_init()
is
called once for each instance of a heavyweight process, that is,
whatever level of execution corresponds to a separate address space,
file handles, etc. In the case of Unix, this is once per child
process, but on Win32 it is called only once in total,
not once per thread. This is because threads
share address space and other resources. There is not currently a
corresponding per-thread call, but there may be in the future. There
is a corresponding call for child exit, described later in this
chapter.
See Example 21-11 (1.3) for an excerpt from mod_unique_id.c.
Example 21-11. mod_unique_id.c
static void unique_id_child_init(server_rec *s, pool *p) { pid_t pid; #ifndef NO_GETTIMEOFDAY struct timeval tv; #endif pid = getpid(); cur_unique_id.pid = pid; if (cur_unique_id.pid != pid) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_CRIT, s, "oh no! pids are greater than 32-bits! I'm broken!"); } cur_unique_id.in_addr = global_in_addr; #ifndef NO_GETTIMEOFDAY if (gettimeofday(&tv, NULL) == -1) { cur_unique_id.counter = 0; } else { cur_unique_id.counter = tv.tv_usec / 10; } #else cur_unique_id.counter = 0; #endif cur_unique_id.pid = htonl(cur_unique_id.pid); cur_unique_id.counter = htons(cur_unique_id.counter); }
mod_unique_id.c ’s purpose in life is to provide an ID for each request that is unique across all web servers everywhere (or, at least at a particular site). To do this, it uses various bits of uniqueness, including the process ID of the child and the time at which it was forked, which is why it uses this hook.
The same function in 2.0 is a little simpler, because APR takes away the platform dependencies:
static void unique_id_child_init(apr_pool_t *p, server_rec *s) { pid_t pid; apr_time_t tv; pid = getpid(); cur_unique_id.pid = pid; if ((pid_t)cur_unique_id.pid != pid) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_CRIT, 0, s, "oh no! pids are greater than 32-bits! I'm broken!"); } cur_unique_id.in_addr = global_in_addr; tv = apr_time_now(); cur_unique_id.counter = (unsigned short)(tv % APR_USEC_PER_SEC / 10); cur_unique_id.pid = htonl(cur_unique_id.pid); cur_unique_id.counter = htons(cur_unique_id.counter); }