On Monday 23 January 2012, Joe Orton wrote:
> > > Good catch on ctx->bytes_in. I'd add: why is
> > > core_output_filter_ctx_t in a public header?
> >
> >
> >
> > There is no good reason other than that other core filter structs
> > like core_filter_ctx and core_net_rec are exposed, too. And
> > those are actually used by the winnt MPM. I would prefer if all
> > these structs were private and core_filters.c would provide an
> > API to allocate them from the winnt MPM and add additional
> > buckets to the input brigade.
>
> Yes! I totally agree.
>
> > Is this something we should still do for 2.4.x (iff 2.4.0 is not
> > released)?
Attached is a simple patch to hide core input/output filter contexts.
The core_net_rec stays public. Obviously the winnt part is not tested
at all. The mod_ftp part compiles (after changing c->remote_ip
everywhere), docs are still missing.
This patch allows us to later add members to core_ctx_t without
breaking binary compatibility to mod_ftp. Without such a patch, the
size of core_ctx_t is part of the ABI, which is bad.
Opinions?
Index: modules/ftp/ftp_data_connection.c
===================================================================
--- modules/ftp/ftp_data_connection.c (Revision 1234692)
+++ modules/ftp/ftp_data_connection.c (Arbeitskopie)
@@ -280,18 +282,15 @@
for (f = cdata->input_filters; f; f = f->next) {
if (strcasecmp(f->frec->name, "CORE_IN") == 0) {
core_net_rec *net = f->ctx;
+ apr_bucket_brigade *bb;
apr_bucket *e;
- net->in_ctx = apr_pcalloc(fc->data_pool, sizeof(*net->in_ctx));
- net->in_ctx->b = apr_brigade_create(fc->data_pool,
- f->c->bucket_alloc);
- net->in_ctx->tmpbb =
- apr_brigade_create(net->in_ctx->b->p,
- net->in_ctx->b->bucket_alloc);
+ net->in_ctx = ap_create_core_ctx(f->c);
+ bb = ap_core_ctx_get_bb(net->in_ctx);
/* seed the brigade with our client data+control sockets */
e = ftp_bucket_datasock_create(fc, f->c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(net->in_ctx->b, e);
+ APR_BRIGADE_INSERT_TAIL(bb, e);
break;
}
}
diff --git a/include/ap_mmn.h b/include/ap_mmn.h
index 2f9e6bb..e77d655 100644
--- a/include/ap_mmn.h
+++ b/include/ap_mmn.h
@@ -385,12 +385,15 @@
* 20111203.1 (2.5.0-dev) Add ap_list_provider_groups()
* 20120109.0 (2.5.0-dev) Changes sizeof(overrides_t) in core config.
* 20120111.0 (2.5.0-dev) Remove sb_type from global_score.
+ * 20120123.0 (2.5.0-dev) Make core_output_filter_ctx_t and core_ctx_t
+ * private, add ap_create_core_ctx(),
+ * ap_core_ctx_get_bb()
*/
#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
#ifndef MODULE_MAGIC_NUMBER_MAJOR
-#define MODULE_MAGIC_NUMBER_MAJOR 20120111
+#define MODULE_MAGIC_NUMBER_MAJOR 20120123
#endif
#define MODULE_MAGIC_NUMBER_MINOR 0 /* 0...n */
diff --git a/include/httpd.h b/include/httpd.h
index 90bbc10..0e5cf35 100644
--- a/include/httpd.h
+++ b/include/httpd.h
@@ -1270,18 +1270,8 @@ struct server_rec {
void *context;
};
-typedef struct core_output_filter_ctx {
- apr_bucket_brigade *buffered_bb;
- apr_bucket_brigade *tmp_flush_bb;
- apr_pool_t *deferred_write_pool;
- apr_size_t bytes_in;
- apr_size_t bytes_written;
-} core_output_filter_ctx_t;
-
-typedef struct core_filter_ctx {
- apr_bucket_brigade *b;
- apr_bucket_brigade *tmpbb;
-} core_ctx_t;
+typedef struct core_output_filter_ctx core_output_filter_ctx_t;
+typedef struct core_filter_ctx core_ctx_t;
typedef struct core_net_rec {
/** Connection to the client */
@@ -1294,6 +1284,9 @@ typedef struct core_net_rec {
core_ctx_t *in_ctx;
} core_net_rec;
+AP_DECLARE(core_ctx_t *) ap_create_core_ctx(conn_rec *c);
+AP_DECLARE(apr_bucket_brigade *) ap_core_ctx_get_bb(core_ctx_t *ctx);
+
/**
* Get the context_document_root for a request. This is a generalization of
* the document root, which is too limited in the presence of mappers like
diff --git a/server/core_filters.c b/server/core_filters.c
index 42da5c2..275ff42 100644
--- a/server/core_filters.c
+++ b/server/core_filters.c
@@ -78,6 +78,32 @@ do { \
#undef APLOG_MODULE_INDEX
#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
+typedef struct core_output_filter_ctx {
+ apr_bucket_brigade *buffered_bb;
+ apr_bucket_brigade *tmp_flush_bb;
+ apr_pool_t *deferred_write_pool;
+ apr_size_t bytes_written;
+} core_output_filter_ctx_t;
+
+typedef struct core_filter_ctx {
+ apr_bucket_brigade *b;
+ apr_bucket_brigade *tmpbb;
+} core_ctx_t;
+
+
+AP_DECLARE(core_ctx_t *) ap_create_core_ctx(conn_rec *c)
+{
+ core_ctx_t *ctx = apr_palloc(c->pool, sizeof(*ctx));
+ ctx->b = apr_brigade_create(c->pool, c->bucket_alloc);
+ ctx->tmpbb = apr_brigade_create(c->pool, c->bucket_alloc);
+ return ctx;
+}
+
+AP_DECLARE(apr_bucket_brigade *) ap_core_ctx_get_bb(core_ctx_t *ctx)
+{
+ return ctx->b;
+}
+
int ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b,
ap_input_mode_t mode, apr_read_type_e block,
apr_off_t readbytes)
@@ -105,18 +131,10 @@ int ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b,
if (!ctx)
{
- /*
- * Note that this code is never executed on Windows because the winnt
- * MPM does the setup of net->in_ctx.
- * XXX: This should be fixed.
- */
- ctx = apr_pcalloc(f->c->pool, sizeof(*ctx));
- ctx->b = apr_brigade_create(f->c->pool, f->c->bucket_alloc);
- ctx->tmpbb = apr_brigade_create(ctx->b->p, ctx->b->bucket_alloc);
+ net->in_ctx = ctx = ap_create_core_ctx(f->c);
/* seed the brigade with the client socket. */
e = apr_bucket_socket_create(net->client_socket, f->c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(ctx->b, e);
- net->in_ctx = ctx;
}
else if (APR_BRIGADE_EMPTY(ctx->b)) {
return APR_EOF;
diff --git a/server/mpm/winnt/child.c b/server/mpm/winnt/child.c
index ab4fddc..30a525a 100644
--- a/server/mpm/winnt/child.c
+++ b/server/mpm/winnt/child.c
@@ -812,7 +812,6 @@ static DWORD __stdcall worker_main(void *thread_num_val)
}
else if (e)
{
- core_ctx_t *ctx;
core_net_rec *net;
ap_filter_t *filt;
@@ -820,24 +819,20 @@ static DWORD __stdcall worker_main(void *thread_num_val)
while ((strcmp(filt->frec->name, "core_in") != 0) && filt->next)
filt = filt->next;
net = filt->ctx;
- ctx = net->in_ctx;
- if (net->in_ctx)
- ctx = net->in_ctx;
- else
+ if (net->in_ctx == NULL)
{
- ctx = apr_pcalloc(c->pool, sizeof(*ctx));
- ctx->b = apr_brigade_create(c->pool, c->bucket_alloc);
- ctx->tmpbb = apr_brigade_create(c->pool, c->bucket_alloc);
+ core_ctx_t *ctx = ap_create_core_ctx(c);
+ apr_bucket_brigade *bb = ap_core_ctx_get_bb(ctx);
/* seed the brigade with AcceptEx read heap bucket */
e = context->overlapped.Pointer;
- APR_BRIGADE_INSERT_HEAD(ctx->b, e);
+ APR_BRIGADE_INSERT_HEAD(bb, e);
/* also seed the brigade with the client socket. */
e = apr_bucket_socket_create(net->client_socket,
c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(ctx->b, e);
+ APR_BRIGADE_INSERT_TAIL(bb, e);
net->in_ctx = ctx;
}
}