|
|
Author: jhorwitz
Date: Sat Jul 19 08:22:53 2008
New Revision: 360
Added:
mod_parrot/trunk/src/module.c
Modified:
mod_parrot/trunk/Makefile.in
mod_parrot/trunk/call_list.txt
mod_parrot/trunk/docs/apache-conf.txt
mod_parrot/trunk/include/mod_parrot.h
mod_parrot/trunk/include/modparrot_config.h
mod_parrot/trunk/lib/mod_parrot.pir
mod_parrot/trunk/src/mod_parrot.c
mod_parrot/trunk/src/modparrot_config.c
mod_parrot/trunk/src/nci.c
Log:
partial implementation of custom apache directives:
- ParrotLoadImmediate starts interpreter early and runs bytecode/PIR
- refactored bytecode loading code to be more reusable
- modparrot_add_module adds a module specified by Parrot at runtime
- NCI support for modparrot_add_module
Modified: mod_parrot/trunk/Makefile.in
==============================================================================
--- mod_parrot/trunk/Makefile.in (original)
+++ mod_parrot/trunk/Makefile.in Sat Jul 19 08:22:53 2008
@@ -28,14 +28,16 @@
$(SRC_DIR)/parrot_util.c \
$(SRC_DIR)/modparrot_config.c \
$(SRC_DIR)/nci.c \
- $(SRC_DIR)/context.c
+ $(SRC_DIR)/context.c \
+ $(SRC_DIR)/module.c
OBJ_FILES= \
$(SRC_DIR)/mod_parrot.lo \
$(SRC_DIR)/parrot_util.lo \
$(SRC_DIR)/modparrot_config.lo \
$(SRC_DIR)/nci.lo \
- $(SRC_DIR)/context.lo
+ $(SRC_DIR)/context.lo \
+ $(SRC_DIR)/module.lo
MPLIBS= lib/Apache/RequestRec \
lib/Apache/Constants \
Modified: mod_parrot/trunk/call_list.txt
==============================================================================
--- mod_parrot/trunk/call_list.txt (original)
+++ mod_parrot/trunk/call_list.txt Sat Jul 19 08:22:53 2008
@@ -18,3 +18,4 @@
v pit
v ptt
v Jtiiipt
+p JtP
Modified: mod_parrot/trunk/docs/apache-conf.txt
==============================================================================
--- mod_parrot/trunk/docs/apache-conf.txt (original)
+++ mod_parrot/trunk/docs/apache-conf.txt Sat Jul 19 08:22:53 2008
@@ -22,6 +22,13 @@
Context: server config (will eventually be allowed in directory config)
Description: Load PBC, PIR, or high level language code
+ParrotLoadImmediate
+-------------------
+Syntax: ParrotLoadImmediate path
+Default: none
+Context: server config
+Description: Start the interpreter, load and run PBC or PIR
+
ParrotTrace
-----------
Syntax: ParrotTrace level
Modified: mod_parrot/trunk/include/mod_parrot.h
==============================================================================
--- mod_parrot/trunk/include/mod_parrot.h (original)
+++ mod_parrot/trunk/include/mod_parrot.h Sat Jul 19 08:22:53 2008
@@ -71,3 +71,6 @@
modparrot_context *get_interp_ctx(Parrot_Interp);
void set_interp_ctx(Parrot_Interp, modparrot_context *);
modparrot_context *modparrot_startup(apr_pool_t *, server_rec *);
+void modparrot_load_file(Parrot_Interp, server_rec *, char *, char *);
+module *modparrot_add_module(Parrot_Interp, apr_pool_t *, const char *,
+ Parrot_PMC);
Modified: mod_parrot/trunk/include/modparrot_config.h
==============================================================================
--- mod_parrot/trunk/include/modparrot_config.h (original)
+++ mod_parrot/trunk/include/modparrot_config.h Sat Jul 19 08:22:53 2008
@@ -107,6 +107,7 @@
const char *modparrot_cmd_trace(cmd_parms *, void *, const char *);
const char *modparrot_cmd_language(cmd_parms *, void *, const char *);
const char *modparrot_cmd_load(cmd_parms *, void *, const char *);
+const char *modparrot_cmd_load_immediate(cmd_parms *, void *, const char *);
const char *modparrot_cmd_include_path(cmd_parms *, void *, const char *);
const char *modparrot_cmd_add_type(cmd_parms *, void *, const char *, const
char *);
const char *modparrot_cmd_add_handler(cmd_parms *, void *, const char *, const
char *);
Modified: mod_parrot/trunk/lib/mod_parrot.pir
==============================================================================
--- mod_parrot/trunk/lib/mod_parrot.pir (original)
+++ mod_parrot/trunk/lib/mod_parrot.pir Sat Jul 19 08:22:53 2008
@@ -57,6 +57,9 @@
dlfunc func, nul, "mpnci_ap_log_rerror", "vJtiiipt"
set_root_global [ '_modparrot'; 'NCI' ], "ap_log_rerror", func
+ dlfunc func, nul, "mpnci_add_apache_module", "pJtP"
+ set_root_global [ '_modparrot'; 'NCI' ], "add_apache_module", func
+
dlfunc func, nul, "mpnci_conf_pool", "pJ"
set_root_global [ '_modparrot'; 'NCI' ], "conf_pool", func
Modified: mod_parrot/trunk/src/mod_parrot.c
==============================================================================
--- mod_parrot/trunk/src/mod_parrot.c (original)
+++ mod_parrot/trunk/src/mod_parrot.c Sat Jul 19 08:22:53 2008
@@ -57,6 +57,26 @@
/* have we started? this can be global since it's written to at startup */
int mp_is_started = 0;
+void modparrot_load_file(Parrot_Interp interp, server_rec *s, char *hll,
+ char *file)
+{
+ int ret;
+
+ char *ext = strrchr(file, '.');
+ /* load any PBC files */
+ if (ext && (!strcmp(ext, ".pbc") || !strcmp(ext, ".pir") ||
+ !strcmp(ext, ".pasm"))) {
+ modparrot_load_bytecode(interp, file);
+ }
+ else {
+ /* call the HLL load handler to handle the loading */
+ if (!modparrot_hll_handler(interp, hll, "load", file,
+ &ret)) {
+ MPLOG_ERRORF(s, "no HLL load handler for '%s'", hll);
+ }
+ }
+}
+
/* should we return something? */
static void modparrot_load_files(Parrot_Interp interp, server_rec *s,
apr_array_header_t *files)
@@ -66,19 +86,7 @@
for (i = 0; i < files->nelts; i++) {
modparrot_handler_info *l =
&((modparrot_handler_info *)files->elts)[i];
- char *ext = strrchr(l->id, '.');
- /* load any PBC files */
- if (ext && (!strcmp(ext, ".pbc") || !strcmp(ext, ".pir") ||
- !strcmp(ext, ".pasm"))) {
- modparrot_load_bytecode(interp, l->id);
- }
- else {
- /* call the HLL load handler to handle the loading */
- if (!modparrot_hll_handler(interp, l->hll, "load", l->id,
- &ret)) {
- MPLOG_ERRORF(s, "no HLL load handler for '%s'", l->hll);
- }
- }
+ modparrot_load_file(interp, s, l->hll, l->id);
}
}
@@ -149,7 +157,7 @@
return(ctxp);
}
-/* public interface for starting an interpreter (used for early startups) */
+/* public interface for starting an interpreter */
modparrot_context *modparrot_startup(apr_pool_t *p, server_rec *s)
{
modparrot_context *ctxp;
@@ -169,8 +177,13 @@
return NULL;
}
+ /* we assume that the passed in pool is the configuration pool. we'll use
+ * this for early startups, but it will be overwritten by later handlers.
+ */
+ ctxp->pconf = p;
+
mp_is_started = 1;
- return ctxp;
+ return(ctxp);
}
int modparrot_hll_handler(Parrot_Interp interp, char *hll, char *hll_handler,
@@ -1238,6 +1251,13 @@
RSRC_CONF,
"preload Parrot code"
),
+ AP_INIT_ITERATE(
+ "ParrotLoadImmediate",
+ modparrot_cmd_load_immediate,
+ NULL,
+ RSRC_CONF,
+ "start interpreter early and load Parrot code"
+ ),
AP_INIT_TAKE1(
"ParrotIncludePath",
modparrot_cmd_include_path,
Modified: mod_parrot/trunk/src/modparrot_config.c
==============================================================================
--- mod_parrot/trunk/src/modparrot_config.c (original)
+++ mod_parrot/trunk/src/modparrot_config.c Sat Jul 19 08:22:53 2008
@@ -288,6 +288,26 @@
return NULL;
}
+const char *modparrot_cmd_load_immediate(cmd_parms *cmd, void *mconfig,
+ const char *handler)
+{
+ modparrot_srv_config *cfg;
+ modparrot_handler_info *l;
+ modparrot_context *ctxp;
+
+ cfg = GET_SERVER_CONFIG(cmd);
+ l = (modparrot_handler_info *)apr_array_push(cfg->preload);
+
+ if (!mp_is_started) {
+ ctxp = modparrot_startup(cmd->pool, cmd->server);
+ }
+
+ parse_handler(cmd->pool, handler, l);
+ modparrot_load_file(ctxp->interp, cmd->server, l->hll, l->id);
+
+ return NULL;
+}
+
const char *modparrot_cmd_open_logs_handler(cmd_parms *cmd, void *mconfig,
const char *handler)
{
modparrot_srv_config *cfg;
Added: mod_parrot/trunk/src/module.c
==============================================================================
--- (empty file)
+++ mod_parrot/trunk/src/module.c Sat Jul 19 08:22:53 2008
@@ -0,0 +1,120 @@
+/* $Id$ */
+
+/* Copyright (c) 2008 Jeff Horwitz
+ *
+ * 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 "httpd.h"
+#include "http_log.h"
+#include "http_protocol.h"
+#include "http_config.h"
+#include "http_request.h"
+#include "http_core.h"
+#include "http_connection.h"
+#include "http_main.h"
+#include "mpm.h"
+
+#include "parrot/parrot.h"
+#include "parrot/embed.h"
+#include "parrot/extend.h"
+
+#include "mod_parrot.h"
+#include "modparrot_config.h"
+#include "modparrot_log.h"
+
+extern module AP_MODULE_DECLARE_DATA parrot_module;
+AP_DECLARE_DATA extern module *ap_top_module;
+const char *modparrot_cmd_test(cmd_parms *, void *, const char *);
+
+static apr_status_t modparrot_remove_module(void *data)
+{
+ module *modp = (module *)data;
+ ap_remove_loaded_module(modp);
+ return APR_SUCCESS;
+}
+
+static void modparrot_insert_module(module *modp)
+{
+ module *m;
+
+ for (m = ap_top_module; m; m = m->next) {
+ if (m == &parrot_module) {
+ module *next = m->next;
+ m->next = modp;
+ modp->next = next;
+ break;
+ }
+ }
+}
+
+/* this is very leaky */
+module *modparrot_add_module(Parrot_Interp interp, apr_pool_t *p,
+ const char *name, Parrot_PMC cmd_array)
+{
+ int i, num;
+ module *modp = (module *)apr_pcalloc(p, sizeof(*modp));
+
+ if (!cmd_array) return(NULL);
+ num = Parrot_PMC_get_intval(interp, cmd_array);
+ if (!num) return(NULL);
+
+ command_rec *cmds =
+ (command_rec *)apr_pcalloc(p, sizeof(command_rec)*(num+1));
+
+ for (i = 0; i < num; i++) {
+ Parrot_PMC val;
+ Parrot_PMC cmd;
+ cmd = Parrot_PMC_get_pmc_keyed_int(interp, cmd_array, i);
+ val = Parrot_PMC_get_pmc_keyed_str(interp, cmd,
+ MAKE_PARROT_STRING("name"));
+ cmds[i].name = Parrot_PMC_get_cstring(interp, val);
+
+ val = Parrot_PMC_get_pmc_keyed_str(interp, cmd,
+ MAKE_PARROT_STRING("args_how"));
+ cmds[i].args_how = Parrot_PMC_get_intval(interp, val);
+
+ val = Parrot_PMC_get_pmc_keyed_str(interp, cmd,
+ MAKE_PARROT_STRING("func"));
+ /* XXX need proxy function */
+ /* cmds[i].func = Parrot_PMC_get_cstring(interp, val); */
+ cmds[i].func = NULL;
+
+ val = Parrot_PMC_get_pmc_keyed_str(interp, cmd,
+ MAKE_PARROT_STRING("req_override"));
+ cmds[i].req_override = Parrot_PMC_get_intval(interp, val);
+
+ val = Parrot_PMC_get_pmc_keyed_str(interp, cmd,
+ MAKE_PARROT_STRING("errmsg"));
+ cmds[i].errmsg = Parrot_PMC_get_cstring(interp, val);
+ }
+
+ modp->version = MODULE_MAGIC_NUMBER_MAJOR;
+ modp->minor_version = MODULE_MAGIC_NUMBER_MINOR;
+ modp->module_index = -1;
+ modp->name = (char *)apr_pstrdup(p, name);
+ modp->magic = MODULE_MAGIC_COOKIE;
+
+ modp->dynamic_load_handle = NULL; /* use for our data */
+
+ modp->cmds = cmds; /* our command vector */
+
+ modparrot_insert_module(modp);
+
+ ap_add_loaded_module(modp, p);
+
+ apr_pool_cleanup_register(p, modp, modparrot_remove_module,
+ apr_pool_cleanup_null);
+
+ return(modp);
+}
Modified: mod_parrot/trunk/src/nci.c
==============================================================================
--- mod_parrot/trunk/src/nci.c (original)
+++ mod_parrot/trunk/src/nci.c Sat Jul 19 08:22:53 2008
@@ -176,3 +176,15 @@
{
ap_log_rerror(file, line, level, status, r, "%s", msg);
}
+
+module *mpnci_add_apache_module(Parrot_Interp interp, char *name,
+ Parrot_PMC cmd_array)
+{
+ modparrot_context *ctxp;
+ module *modp;
+
+ ctxp = get_interp_ctx(interp);
+ if (!ctxp) return NULL;
+ modp = modparrot_add_module(interp, ctxp->pconf, name, cmd_array);
+ return(modp);
+}
|
|