diff options
author | Sander Temme <sctemme@apache.org> | 2007-01-04 02:07:45 +0100 |
---|---|---|
committer | Sander Temme <sctemme@apache.org> | 2007-01-04 02:07:45 +0100 |
commit | f0c8f2096344d1feb75b659c41eca3bac5dc19db (patch) | |
tree | 774f9823608f69ec06c0a03e354db714313c0b13 /modules/experimental | |
parent | Correctly evaluate the HTTPS condition string. (diff) | |
download | apache2-f0c8f2096344d1feb75b659c41eca3bac5dc19db.tar.xz apache2-f0c8f2096344d1feb75b659c41eca3bac5dc19db.zip |
Get rid of the global trace_add in favor of specific trace functions tailored to the server run phase and callback context. Add the final trace function (for no context) and start moving the EXAMPLE_LOG_EACH stuff to ap_log_perror instead of directly writing to stdout.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@492376 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules/experimental')
-rw-r--r-- | modules/experimental/mod_example.c | 240 |
1 files changed, 105 insertions, 135 deletions
diff --git a/modules/experimental/mod_example.c b/modules/experimental/mod_example.c index 60be19fea6..443675e5a9 100644 --- a/modules/experimental/mod_example.c +++ b/modules/experimental/mod_example.c @@ -345,127 +345,6 @@ static void example_log_each(apr_pool_t *p, server_rec *s, const char *note) } } -/* - * This routine is used to add a trace of a callback to the list. We're - * passed the server record (if available), the request record (if available), - * a pointer to our private configuration record (if available) for the - * environment to which the callback is supposed to apply, and some text. We - * turn this into a textual representation and add it to the tail of the list. - * The list can be displayed by the x_handler() routine. - * - * If the call occurs within a request context (i.e., we're passed a request - * record), we put the trace into the request apr_pool_t and attach it to the - * request via the notes mechanism. Otherwise, the trace gets added - * to the static (non-request-specific) list. - * - * Note that the r->notes table is only for storing strings; if you need to - * maintain per-request data of any other type, you need to use another - * mechanism. - */ - -#define TRACE_NOTE "example-trace" - -static void trace_add(server_rec *s, request_rec *r, x_cfg *mconfig, - const char *note) -{ - const char *sofar; - char *addon; - char *where; - apr_pool_t *p; - const char *trace_copy; - - /* - * Make sure our pools and tables are set up - we need 'em. - */ - setup_module_cells(); - /* - * Now, if we're in request-context, we use the request pool. - */ - if (r != NULL) { - p = r->pool; - if ((trace_copy = apr_table_get(r->notes, TRACE_NOTE)) == NULL) { - trace_copy = ""; - } - } - else { - /* - * We're not in request context, so the trace gets attached to our - * module-wide pool. We do the create/destroy every time we're called - * in non-request context; this avoids leaking memory in some of - * the subsequent calls that allocate memory only once (such as the - * key formation below). - * - * Make a new sub-pool and copy any existing trace to it. Point the - * trace cell at the copied value. - */ - apr_pool_create(&p, x_pool); - if (trace != NULL) { - trace = apr_pstrdup(p, trace); - } - /* - * Now, if we have a sub-pool from before, nuke it and replace with - * the one we just allocated. - */ - if (x_subpool != NULL) { - apr_pool_destroy(x_subpool); - } - x_subpool = p; - trace_copy = trace; - } - -#ifdef EXAMPLE_LOG_EACH - example_log_each(p, s, note); -#endif - - /* - * If we weren't passed a configuration record, we can't figure out to - * what location this call applies. This only happens for co-routines - * that don't operate in a particular directory or server context. If we - * got a valid record, extract the location (directory or server) to which - * it applies. - */ - where = (mconfig != NULL) ? mconfig->loc : "nowhere"; - where = (where != NULL) ? where : ""; - /* - * Now, if we're not in request context, see if we've been called with - * this particular combination before. The apr_table_t is allocated in the - * module's private pool, which doesn't get destroyed. - */ - if (r == NULL) { - char *key; - - key = apr_pstrcat(p, note, ":", where, NULL); - if (apr_table_get(static_calls_made, key) != NULL) { - /* - * Been here, done this. - */ - return; - } - else { - /* - * First time for this combination of routine and environment - - * log it so we don't do it again. - */ - apr_table_set(static_calls_made, key, "been here"); - } - } - addon = apr_pstrcat(p, - " <li>\n" - " <dl>\n" - " <dt><samp>", note, "</samp></dt>\n" - " <dd><samp>[", where, "]</samp></dd>\n" - " </dl>\n" - " </li>\n", - NULL); - sofar = (trace_copy == NULL) ? "" : trace_copy; - trace_copy = apr_pstrcat(p, sofar, addon, NULL); - if (r != NULL) { - apr_table_set(r->notes, TRACE_NOTE, trace_copy); - } - else { - trace = trace_copy; - } -} /* * This utility routine traces the hooks called when the server starts up. @@ -479,7 +358,7 @@ static void trace_startup(apr_pool_t *p, server_rec *s, x_cfg *mconfig, const char *sofar; char *where, *addon; -#ifdef EXAMPLE_LOG_EACH +#if EXAMPLE_LOG_EACH example_log_each(p, s, note); #endif @@ -516,6 +395,7 @@ static void trace_startup(apr_pool_t *p, server_rec *s, x_cfg *mconfig, * This utility route traces the hooks called as a request is handled. * It takes the current request as argument */ +#define TRACE_NOTE "example-trace" static void trace_request(const request_rec *r, const char *note) { @@ -523,7 +403,7 @@ static void trace_request(const request_rec *r, const char *note) char *addon, *where; x_cfg *cfg; -#ifdef EXAMPLE_LOG_EACH +#if EXAMPLE_LOG_EACH example_log_each(r->pool, r->server, note); #endif @@ -549,6 +429,80 @@ static void trace_request(const request_rec *r, const char *note) apr_table_set(r->notes, TRACE_NOTE, trace_copy); } +/* + * This utility routine traces the hooks called while processing a + * Connection. Its trace is kept in the pool notes of the pool associated + * with the Connection. + */ + +/* + * Key to get and set the userdata. We should be able to get away + * with a constant key, since in prefork mode the process will have + * the connection and its pool to itself entirely, and in + * multi-threaded mode each connection will have its own pool. + */ +#define CONN_NOTE "example-connection" + +static void trace_connection(conn_rec *c, const char *note) +{ + const char *trace_copy, *sofar; + char *addon, *where; + void *data; + x_cfg *cfg; + +#if EXAMPLE_LOG_EACH + example_log_each(c->pool, c->base_server, note); +#endif + + cfg = our_cconfig(c); + + where = (cfg != NULL) ? cfg->loc : "nowhere"; + where = (where != NULL) ? where : ""; + + addon = apr_pstrcat(c->pool, + " <li>\n" + " <dl>\n" + " <dt><samp>", note, "</samp></dt>\n" + " <dd><samp>[", where, "]</samp></dd>\n" + " </dl>\n" + " </li>\n", + NULL); + + /* Find existing notes and copy */ + apr_pool_userdata_get(&data, CONN_NOTE, c->pool); + sofar = (data == NULL) ? "" : (const char *) data; + + /* Tack addon onto copy */ + trace_copy = apr_pstrcat(c->pool, sofar, addon, NULL); + + /* + * Stash copy back into pool notes. This call has a cleanup + * parameter, but we're not using it because the string has been + * allocated from that same pool. There is also an unused return + * value: we have nowhere to communicate any error that might + * occur, and will have to check for the existence of this data on + * the other end. + */ + apr_pool_userdata_set((const void *) trace_copy, CONN_NOTE, + NULL, c->pool); +} + +static void trace_nocontext(apr_pool_t *p, const char *file, int line, + const char *note) +{ + /* + * Since we have no request or connection to trace, or any idea + * from where this routine was called, there's really not much we + * can do. If we are not logging everything by way of the + * EXAMPLE_LOG_EACH constant, do nothing in this routine. + */ + +#ifdef EXAMPLE_LOG_EACH + ap_log_perror(file, line, APLOG_NOTICE, 0, p, note); +#endif +} + + /*--------------------------------------------------------------------------*/ /* We prototyped the various syntax for command handlers (routines that */ /* are called when the configuration parser detects a directive declared */ @@ -1029,7 +983,9 @@ static int x_handler(request_rec *r) { x_cfg *dcfg; int result; - char *note; + char *note, *conn_trace; + void *conn_data; + apr_status_t status; dcfg = our_dconfig(r); /* @@ -1098,8 +1054,19 @@ static int x_handler(request_rec *r) ap_rputs(" indicates a location in the URL or filesystem\n", r); ap_rputs(" namespace.\n", r); ap_rputs(" </P>\n", r); - ap_rprintf(r, " <H2>Static callbacks so far:</H2>\n <OL>\n%s </OL>\n", + ap_rprintf(r, " <H2>Startup callbacks so far:</H2>\n <OL>\n%s </OL>\n", trace); + ap_rputs(" <H2>Connection-specific callbacks so far:</H2>\n", r); + + status = apr_pool_userdata_get(&conn_data, CONN_NOTE, + r->connection->pool); + if ((status == APR_SUCCESS) && conn_data) { + ap_rprintf(r, " <OL>\n%s </OL>\n", (char *) conn_data); + } else { + ap_rputs(" <P>No connection-specific callback information was " + "retrieved.</P>\n", r); + } + ap_rputs(" <H2>Request-specific callbacks so far:</H2>\n", r); ap_rprintf(r, " <OL>\n%s </OL>\n", apr_table_get(r->notes, TRACE_NOTE)); ap_rputs(" <H2>Environment for <EM>this</EM> call:</H2>\n", r); @@ -1159,13 +1126,16 @@ static int x_quick_handler(request_rec *r, int lookup_uri) static int x_pre_connection(conn_rec *c, void *csd) { x_cfg *cfg; + char *note; cfg = our_cconfig(c); /* * Log the call and exit. */ - trace_add(NULL, NULL, cfg, "x_pre_connection()"); + note = apr_psprintf(c->pool, "x_pre_connection(c = %x, p = %x)", + c, c->pool); + trace_connection(c, note); return OK; } @@ -1183,7 +1153,7 @@ static int x_process_connection(conn_rec *c) x_cfg *cfg; cfg = our_cconfig(c); - trace_add(NULL, NULL, cfg, "x_process_connection()"); + trace_connection(c, "x_process_connection()"); return DECLINED; } @@ -1386,7 +1356,7 @@ static conn_rec *x_create_connection(apr_pool_t *p, server_rec *server, apr_socket_t *csd, long conn_id, void *sbh, apr_bucket_alloc_t *alloc) { - trace_add(server, NULL, NULL, "x_create_connection()"); + trace_nocontext(p, __FILE__, __LINE__, "x_create_connection()"); return NULL; } @@ -1401,7 +1371,7 @@ static int x_get_mgmt_items(apr_pool_t *p, const char *val, apr_hash_t *ht) /* We have nothing to do here but trace the call, and no context * in which to trace it. */ - trace_add(NULL, NULL, NULL, "x_check_config()"); + trace_nocontext(p, __FILE__, __LINE__, "x_check_config()"); return DECLINED; } @@ -1414,11 +1384,11 @@ static int x_get_mgmt_items(apr_pool_t *p, const char *val, apr_hash_t *ht) */ static int x_create_request(request_rec *r) { - /* We have a request_rec, but it is not filled in enough - * to give us a usable configuration. So, add trace with - * NULL pointers. + /* + * We have a request_rec, but it is not filled in enough to give + * us a usable configuration. So, add a trace without context. */ - trace_add(NULL, NULL, NULL, "x_create_request()"); + trace_nocontext( r->pool, __FILE__, __LINE__, "x_create_request()"); return DECLINED; } @@ -1430,7 +1400,7 @@ static int x_create_request(request_rec *r) */ static int x_pre_mpm(apr_pool_t *p, ap_scoreboard_e sb_type) { - trace_add(NULL, NULL, NULL, "x_pre_mpm()"); + trace_nocontext(p, __FILE__, __LINE__, "x_pre_mpm()"); return DECLINED; } @@ -1442,7 +1412,7 @@ static int x_pre_mpm(apr_pool_t *p, ap_scoreboard_e sb_type) */ static int x_monitor(apr_pool_t *p) { - trace_add(NULL, NULL, NULL, "x_monitor()"); + trace_nocontext(p, __FILE__, __LINE__, "x_monitor()"); return DECLINED; } |