#include "apr_hash.h"
#include "apr_thread_proc.h" /* for RLIMIT stuff */
#include "apr_hooks.h"
+#include "apr_optional.h"
#define APR_WANT_IOVEC
#define APR_WANT_STRFUNC
#include "mod_core.h"
#include "mod_proxy.h"
#include "ap_listen.h"
+#include "ap_mpm.h"
#include "mod_so.h" /* for ap_find_loaded_module_symbol */
/* Handles for core filters */
AP_DECLARE_DATA ap_filter_rec_t *ap_subreq_core_filter_handle;
AP_DECLARE_DATA ap_filter_rec_t *ap_core_output_filter_handle;
+AP_DECLARE_DATA ap_filter_rec_t *ap_core_mpm_write_filter_handle;
AP_DECLARE_DATA ap_filter_rec_t *ap_content_length_filter_handle;
AP_DECLARE_DATA ap_filter_rec_t *ap_net_time_filter_handle;
AP_DECLARE_DATA ap_filter_rec_t *ap_core_input_filter_handle;
+static APR_OPTIONAL_FN_TYPE(ap_mpm_custom_write_filter) *mpm_write_func;
+
/* magic pointer for ErrorDocument xxx "default" */
static char errordocument_default;
static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
{
+ int mpm_write = 0;
+
logio_add_bytes_out = APR_RETRIEVE_OPTIONAL_FN(ap_logio_add_bytes_out);
ident_lookup = APR_RETRIEVE_OPTIONAL_FN(ap_ident_lookup);
+ if (ap_mpm_query(AP_MPMQ_CUSTOM_WRITE, &mpm_write) == APR_SUCCESS
+ && mpm_write == 1) {
+ mpm_write_func = APR_RETRIEVE_OPTIONAL_FN(ap_mpm_custom_write_filter);
+
+ ap_core_output_filter_handle =
+ ap_register_output_filter("CORE", mpm_write_func,
+ NULL, AP_FTYPE_NETWORK);
+ }
+ else {
+ ap_core_output_filter_handle =
+ ap_register_output_filter("CORE", ap_core_output_filter,
+ NULL, AP_FTYPE_NETWORK);
+ }
+
ap_set_version(pconf);
ap_setup_make_content_type(pconf);
return OK;
ap_set_module_config(net->c->conn_config, &core_module, csd);
ap_add_input_filter_handle(ap_core_input_filter_handle, net, NULL, net->c);
- ap_add_output_filter_handle(ap_core_output_filter_handle, net, NULL, net->c);
+
+ ap_add_output_filter_handle(ap_core_output_filter_handle, net,
+ NULL, net->c);
+
return DONE;
}
ap_content_length_filter_handle =
ap_register_output_filter("CONTENT_LENGTH", ap_content_length_filter,
NULL, AP_FTYPE_PROTOCOL);
- ap_core_output_filter_handle =
- ap_register_output_filter("CORE", ap_core_output_filter,
- NULL, AP_FTYPE_NETWORK);
+
+
ap_subreq_core_filter_handle =
ap_register_output_filter("SUBREQ_CORE", ap_sub_req_output_filter,
NULL, AP_FTYPE_CONTENT_SET);
static apr_pollset_t *event_pollset;
+extern apr_status_t ap_mpm_custom_write_filter(ap_filter_t *f,
+ apr_bucket_brigade *bb);
+
/* The structure used to pass unique initialization info to each thread */
typedef struct
{
case AP_MPMQ_IS_ASYNC:
*result = 1;
return APR_SUCCESS;
+ case AP_MPMQ_CUSTOM_WRITE:
+ *result = 1;
+ return APR_SUCCESS;
case AP_MPMQ_HARD_LIMIT_DAEMONS:
*result = server_limit;
return APR_SUCCESS;
* to retrieve it, so register as REALLY_FIRST
*/
ap_hook_pre_config(worker_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
+
+ APR_REGISTER_OPTIONAL_FN(ap_mpm_custom_write_filter);
}
static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy,
--- /dev/null
+/* Copyright 2005 The Apache Software Foundation or its licensors, as
+ * applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_buckets.h"
+#include "apr_errno.h"
+#include "apr_support.h"
+#include "httpd.h"
+#include "http_connection.h"
+#include "util_filter.h"
+
+apr_status_t ap_mpm_custom_write_filter(ap_filter_t *f,
+ apr_bucket_brigade *bb)
+{
+ /* write you own C-O-F here */
+ return ap_core_output_filter(f, bb);
+}
+