Re: RubyInitHandler Problems
Shugo Maeda <[email protected]> Thu, 05 Aug 2004 15:06:47 +0900
| Newsgroups | gmane.comp.apache.mod-ruby |
|---|---|
| Message-ID | <[email protected]> |
Hi,
Michael Granger wrote:
> I've had some success with putting initialization code in a spot that
> runs when the file is first required, but it'd be nice to have a
> ChildInitHandler, too. Would it be difficult to add, Shugo-san?
How about this patch?
A simple example is here:
---- sample-child-init-handler.rb --------
require 'singleton'
class SampleChildInitHandler
include Singleton
def child_init(r)
r.server.log_error("ChildInit#child_init called")
return Apache::OK
end
end
---------------------------
---- httpd.conf -----------
RubyRequire sample-child-init-handler
RubyChildInitHandler SampleChildInitHandler.instance
---------------------------
Shugo
Index: mod_ruby.c
===================================================================
--- mod_ruby.c (revision 16)
+++ mod_ruby.c (working copy)
@@ -174,6 +174,9 @@
{"RubyCleanupHandler", ruby_cmd_cleanup_handler,
NULL, OR_ALL, TAKE1,
"set cleanup handler object"},
+ {"RubyChildInitHandler", ruby_cmd_child_init_handler,
+ NULL, RSRC_CONF, TAKE1,
+ "set child init handler object"},
{NULL}
};
@@ -484,9 +487,11 @@
VALUE errmsg, reqobj;
errmsg = ruby_get_error_info(state);
- reqobj = (VALUE) ap_get_module_config(r->request_config, &ruby_module);
- if (reqobj)
- rb_apache_request_set_error(reqobj, errmsg, ruby_errinfo);
+ if (r->request_config) {
+ reqobj = (VALUE) ap_get_module_config(r->request_config, &ruby_module);
+ if (reqobj)
+ rb_apache_request_set_error(reqobj, errmsg, ruby_errinfo);
+ }
ruby_log_error_string(r->server, errmsg);
}
@@ -776,12 +781,29 @@
APR_CLEANUP_RETURN_SUCCESS();
}
+static request_rec *fake_request_rec(server_rec *s, pool *p, char *hook)
+{
+ request_rec *r = (request_rec *) ap_pcalloc(p, sizeof(request_rec));
+ r->pool = p;
+ r->server = s;
+ r->per_dir_config = NULL;
+ r->request_config = NULL;
+ r->uri = hook;
+ r->notes = NULL;
+ return r;
+}
+
+static int ruby_handler(request_rec *, array_header *, ID, int, int);
+
#ifdef APACHE2
static void ruby_child_init(pool *p, server_rec *s)
#else /* Apache 1.x */
static void ruby_child_init(server_rec *s, pool *p)
#endif
{
+ ruby_server_config *conf;
+ request_rec *r;
+
if (!ruby_running()) {
#if APR_HAS_THREADS
apr_status_t status;
@@ -807,6 +829,11 @@
ap_register_cleanup(p, NULL, ruby_child_cleanup, ap_null_cleanup);
ruby_is_running = 1;
}
+
+ r = fake_request_rec(s, p, "RubyChildInitHandler");
+ conf = get_server_config(r->server);
+ ruby_handler(r, conf->ruby_child_init_handler,
+ rb_intern("child_init"), 0, 0);
}
static void mod_ruby_clearenv()
@@ -981,7 +1008,7 @@
mod_ruby_setup_loadpath(sconf, dconf);
ruby_debug = Qfalse;
ruby_verbose = Qfalse;
- if (dconf->kcode)
+ if (dconf && dconf->kcode)
rb_set_kcode(dconf->kcode);
rb_request = rb_get_request_object(r);
rb_stdin = rb_stdout = rb_request;
@@ -1091,7 +1118,7 @@
sconf = get_server_config(r->server);
dconf = get_dir_config(r);
- safe_level = dconf->safe_level;
+ safe_level = dconf ? dconf->safe_level : MR_DEFAULT_SAFE_LEVEL;
handlers = (char **) handlers_arr->elts;
handlers_len = handlers_arr->nelts;
iarg->retval = DECLINED;
Index: mod_ruby.h
===================================================================
--- mod_ruby.h (revision 16)
+++ mod_ruby.h (working copy)
@@ -101,6 +101,7 @@
array_header *load_path;
table *env;
int timeout;
+ array_header *ruby_child_init_handler;
} ruby_server_config;
typedef struct {
@@ -165,8 +166,10 @@
((ruby_server_config *) ap_get_module_config(s->module_config, \
&ruby_module))
#define get_dir_config(r) \
- ((ruby_dir_config *) ap_get_module_config(r->per_dir_config, \
- &ruby_module))
+ (r->per_dir_config ? \
+ ((ruby_dir_config *) ap_get_module_config(r->per_dir_config, \
+ &ruby_module)) : \
+ NULL)
#if APR_HAS_THREADS
typedef void *(*ruby_interp_func_t)(void*);
Index: ruby_config.c
===================================================================
--- ruby_config.c (revision 16)
+++ ruby_config.c (working copy)
@@ -46,9 +46,21 @@
conf->load_path = ap_make_array(p, 1, sizeof(char*));
conf->env = ap_make_table(p, 1);
conf->timeout = MR_DEFAULT_TIMEOUT;
+ conf->ruby_child_init_handler = NULL;
return conf;
}
+static array_header *merge_handlers(pool *p,
+ array_header *base,
+ array_header *add)
+{
+ if (base == NULL)
+ return add;
+ if (add == NULL)
+ return base;
+ return ap_append_arrays(p, add, base);
+}
+
void *ruby_merge_server_config(pool *p, void *basev, void *addv)
{
ruby_server_config *new =
@@ -67,6 +79,9 @@
}
new->env = ap_overlay_tables(p, add->env, base->env);
new->timeout = add->timeout ? add->timeout : base->timeout;
+ new->ruby_child_init_handler =
+ merge_handlers(p, base->ruby_child_init_handler,
+ add->ruby_child_init_handler);
return (void *) new;
}
@@ -95,17 +110,6 @@
return conf;
}
-static array_header *merge_handlers(pool *p,
- array_header *base,
- array_header *add)
-{
- if (base == NULL)
- return add;
- if (add == NULL)
- return base;
- return ap_append_arrays(p, add, base);
-}
-
void *ruby_merge_dir_config(pool *p, void *basev, void *addv)
{
ruby_dir_config *new =
@@ -409,6 +413,15 @@
return NULL;
}
+const char *ruby_cmd_child_init_handler(cmd_parms *cmd,
+ void *dummy, char *arg)
+{
+ ruby_server_config *conf = get_server_config(cmd->server);
+
+ push_handler(cmd->pool, conf->ruby_child_init_handler, arg);
+ return NULL;
+}
+
/*
* Local variables:
* mode: C
Index: ruby_config.h
===================================================================
--- ruby_config.h (revision 16)
+++ ruby_config.h (working copy)
@@ -54,6 +54,7 @@
const char *ruby_cmd_post_read_request_handler(cmd_parms*, ruby_dir_config*, char*);
const char *ruby_cmd_init_handler(cmd_parms*, ruby_dir_config*, char*);
const char *ruby_cmd_cleanup_handler(cmd_parms*, ruby_dir_config*, char*);
+const char *ruby_cmd_child_init_handler(cmd_parms*, void*, char*);
#endif /* !RUBY_CONFIG_H */
Index: request.c
===================================================================
--- request.c (revision 16)
+++ request.c (working copy)
@@ -125,6 +125,8 @@
request_rec *r = (request_rec *) data;
VALUE reqobj;
+ if (r->request_config == NULL)
+ APR_CLEANUP_RETURN_SUCCESS();
reqobj = (VALUE) ap_get_module_config(r->request_config, &ruby_module);
if (reqobj == 0) APR_CLEANUP_RETURN_SUCCESS();
if (TYPE(reqobj) == T_DATA) {
@@ -173,20 +175,23 @@
#endif
rb_apache_register_object(obj);
- ap_set_module_config(r->request_config, &ruby_module, (void *) obj);
+ if (r->request_config)
+ ap_set_module_config(r->request_config, &ruby_module, (void *) obj);
ap_register_cleanup(r->pool, (void *) r,
cleanup_request_object, ap_null_cleanup);
- switch (dconf->output_mode) {
- case MR_OUTPUT_SYNC_HEADER:
- FL_SET(obj, REQ_SYNC_HEADER);
- break;
- case MR_OUTPUT_SYNC:
- FL_SET(obj, REQ_SYNC_HEADER);
- FL_SET(obj, REQ_SYNC_OUTPUT);
- break;
- case MR_OUTPUT_NOSYNC:
- default:
- break;
+ if (dconf) {
+ switch (dconf->output_mode) {
+ case MR_OUTPUT_SYNC_HEADER:
+ FL_SET(obj, REQ_SYNC_HEADER);
+ break;
+ case MR_OUTPUT_SYNC:
+ FL_SET(obj, REQ_SYNC_HEADER);
+ FL_SET(obj, REQ_SYNC_OUTPUT);
+ break;
+ case MR_OUTPUT_NOSYNC:
+ default:
+ break;
+ }
}
return obj;
}
@@ -196,13 +201,12 @@
VALUE reqobj;
if (r == NULL) return Qnil;
- reqobj = (VALUE) ap_get_module_config(r->request_config, &ruby_module);
- if (reqobj) {
- return reqobj;
+ if (r->request_config) {
+ reqobj = (VALUE) ap_get_module_config(r->request_config, &ruby_module);
+ if (reqobj)
+ return reqobj;
}
- else {
- return apache_request_new(r);
- }
+ return apache_request_new(r);
}
static request_data *get_request_data(VALUE obj)