summaryrefslogtreecommitdiffstats
path: root/modules/experimental
diff options
context:
space:
mode:
authorSander Temme <sctemme@apache.org>2007-01-04 02:07:45 +0100
committerSander Temme <sctemme@apache.org>2007-01-04 02:07:45 +0100
commitf0c8f2096344d1feb75b659c41eca3bac5dc19db (patch)
tree774f9823608f69ec06c0a03e354db714313c0b13 /modules/experimental
parent Correctly evaluate the HTTPS condition string. (diff)
downloadapache2-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.c240
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;
}