develooper Front page | perl.cvs.mod_parrot | Postings from January 2009

[svn:mod_parrot] r581 - in mod_parrot/trunk: . build/lib build/lib/Generator build/maps/httpd include lib lib/ModParrot/Apache src t/response/TestAPI

From:
jhorwitz
Date:
January 5, 2009 14:33
Subject:
[svn:mod_parrot] r581 - in mod_parrot/trunk: . build/lib build/lib/Generator build/maps/httpd include lib lib/ModParrot/Apache src t/response/TestAPI
Message ID:
20090105223318.72B96CB9F9@x12.develooper.com
Author: jhorwitz
Date: Mon Jan  5 14:33:17 2009
New Revision: 581

Added:
   mod_parrot/trunk/build/lib/Generator/ApacheServerRec.pm
   mod_parrot/trunk/build/maps/httpd/server_rec.map
   mod_parrot/trunk/t/response/TestAPI/server_rec.pir
Modified:
   mod_parrot/trunk/Makefile.in
   mod_parrot/trunk/build/lib/generate_source.pl
   mod_parrot/trunk/include/mod_parrot.h
   mod_parrot/trunk/lib/ModParrot/Apache/RequestRec.pir
   mod_parrot/trunk/lib/mod_parrot.pir
   mod_parrot/trunk/src/context.c
   mod_parrot/trunk/src/mod_parrot.c
   mod_parrot/trunk/src/nci.c
   mod_parrot/trunk/t/response/TestAPI/request_rec.pir

Log:
initial implementation of ModParrot;Apache;ServerRec
register & unregister context PMC (GC was causing segfaults after ServerRec changes)


Modified: mod_parrot/trunk/Makefile.in
==============================================================================
--- mod_parrot/trunk/Makefile.in	(original)
+++ mod_parrot/trunk/Makefile.in	Mon Jan  5 14:33:17 2009
@@ -46,6 +46,7 @@
 	$(SRC_DIR)/module.lo
 
 MPLIBS=	lib/ModParrot/Apache/RequestRec.pbc \
+	lib/ModParrot/Apache/ServerRec.pbc \
 	lib/ModParrot/Apache/Constants.pbc \
 	lib/ModParrot/Apache/Module.pbc \
 	lib/ModParrot/APR/Pool.pbc \

Added: mod_parrot/trunk/build/lib/Generator/ApacheServerRec.pm
==============================================================================
--- (empty file)
+++ mod_parrot/trunk/build/lib/Generator/ApacheServerRec.pm	Mon Jan  5 14:33:17 2009
@@ -0,0 +1,241 @@
+# $Id$
+#
+# Copyright (c) 2005, 2007, 2009 Ian Joyce, 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.
+
+package ModParrot::Config::Generator::ApacheServerRec;
+
+use strict;
+use warnings;
+
+our $VERSION = '0.01';
+
+use Carp;
+use BaseGenerator;
+
+use base 'ModParrot::Config::Generator::BaseGenerator';
+
+sub run 
+{
+    my $self = shift;
+
+    my $map = $self->get_map('build/maps/httpd/server_rec.map');
+
+    $self->build_attribs($map);
+
+    $self->generate_c_source($map);
+    $self->generate_pir_source($map);
+    $self->generate_pir_dlfunc_source($map);
+}
+
+sub build_attribs
+{
+    my ($self, $map) = @_;
+
+    foreach my $record (@$map) {
+        if ($record->{'return_type'} eq 'int') {
+            $record->{'sig'} = 'iJpii';
+            $record->{'pir_type'} = 'int';
+        }
+        else {
+            $record->{'sig'} = 'tJpti';
+            $record->{'pir_type'} = 'string';
+        }
+    }
+}
+
+sub generate_pir_dlfunc_source
+{
+    my ($self, $map) = @_;
+
+    my $source;
+
+    foreach my $record (@$map) {
+        $source .= $self->merge($self->get_dlfunc_template(), $record);
+    }
+
+    $self->write_file('pir', 'server_rec_dlfunc.pir', $source);
+}
+
+sub get_dlfunc_template
+{
+    my $template = <<'END'
+dlfunc func, nul, "mpnci_server_rec_%%NAME%%", "%%SIG%%"
+set_root_global [ 'ModParrot'; 'NCI' ], "server_rec_%%NAME%%", func
+
+END
+;
+
+    return $template;
+}
+
+sub generate_c_source
+{
+    my ($self, $map) = @_;
+
+    my $source;
+    my $prototype;
+
+    foreach my $record (@$map) {
+        my $function = $self->get_c_function($record);
+        $source .= $function;
+
+        # This gets the prototype.
+        $function =~ /(.*)/;
+        $prototype .= "$1;\n";
+    }
+
+    $self->write_file('nci', 'server_rec.c', "$prototype\n$source");
+}
+
+sub generate_pir_source
+{
+    my ($self, $map) = @_;
+
+    my $source;
+
+    foreach my $record (@$map) {
+        $source .= $self->get_pir_method($record);
+    }
+
+    $self->write_file('pir', 'server_rec.pir', $source);
+}
+
+sub get_pir_method
+{
+    my ($self, $record) = @_;
+
+    my $template = $record->{'return_type'} eq 'int'
+        ? $self->get_pir_int_template()
+        : $self->get_pir_string_template();
+
+    return $self->merge($template, $record);
+}
+
+sub get_pir_int_template
+{
+    my $self = shift;
+
+    my $template = <<'END'
+.sub %%NAME%% :method
+    .param int data :optional
+    .param int update :opt_flag
+    .local pmc s
+    .local pmc server_rec_%%NAME%%
+    .local int %%NAME%%
+
+    getattribute s, self, 'server_rec'
+
+    server_rec_%%NAME%% = get_root_global [ 'ModParrot'; 'NCI' ], 'server_rec_%%NAME%%'
+    %%NAME%% = server_rec_%%NAME%%( s , data, update )
+
+    .return(%%NAME%%)
+.end
+
+END
+;
+
+    return $template;
+}
+
+sub get_pir_string_template
+{
+    my $self = shift;
+
+    my $template = <<'END'
+.sub %%NAME%% :method
+    .param %%PIR_TYPE%% data :optional
+    .param int update :opt_flag
+    .local pmc s
+    .local pmc server_rec_%%NAME%%
+    .local %%PIR_TYPE%% %%NAME%%
+
+    getattribute s, self, 'server_rec'
+
+    if update goto call_it
+    data = ""
+
+call_it:
+    server_rec_%%NAME%% = get_root_global [ 'ModParrot'; 'NCI' ], 'server_rec_%%NAME%%'
+    %%NAME%% = server_rec_%%NAME%%( s , data, update )
+
+    .return(%%NAME%%)
+.end
+
+END
+;
+
+    return $template;
+}
+
+sub get_c_function
+{
+    my ($self, $record) = @_;
+
+    my @arguments = ('server_rec *s');
+    if ($record->{'access'} eq 'rw') {
+        push @arguments, $record->{'return_type'} . $record->{'name'};
+    }
+    else {
+        confess "TODO: read only access to server_rec";
+    }
+    $record->{'args'} = join ', ', @arguments;
+
+    my $template = $record->{'return_type'} eq 'int'
+        ? $self->get_c_int_template()
+        : $self->get_c_char_template();
+
+    return $self->merge($template, $record);
+}
+
+sub get_c_int_template
+{
+    my $self = shift;
+
+    my $template = <<'END'
+%%RETURN_TYPE%% mpnci_server_rec_%%NAME%%(Parrot_Interp interp, server_rec *s, int %%NAME%%, int update)
+{
+    if (update == 1) {
+        s->%%NAME%% = %%NAME%%;
+    }
+    return s->%%NAME%%;
+}
+
+END
+;
+
+    return $template;
+}
+
+sub get_c_char_template
+{
+    my $self = shift;
+
+    my $template = <<'END'
+%%RETURN_TYPE%%mpnci_server_rec_%%NAME%%(Parrot_Interp interp, server_rec *s, char *%%NAME%%, int update)
+{
+    if (update == 1) {
+        modparrot_context *ctxp = get_interp_ctx(interp);
+        s->%%NAME%% = (char *)apr_pstrdup(ctxp->pool, %%NAME%%);
+    }
+    return s->%%NAME%%;
+}
+
+END
+;
+
+    return $template;
+}
+
+1;

Modified: mod_parrot/trunk/build/lib/generate_source.pl
==============================================================================
--- mod_parrot/trunk/build/lib/generate_source.pl	(original)
+++ mod_parrot/trunk/build/lib/generate_source.pl	Mon Jan  5 14:33:17 2009
@@ -22,6 +22,7 @@
 
 use Generator::ApacheConstants;
 use Generator::ApacheRequestRec;
+use Generator::ApacheServerRec;
 use Generator::ModParrotConstants;
 
 my $apache_include_dir = '/usr/local/apache2/include/';
@@ -48,5 +49,6 @@
 );
 
 ModParrot::Config::Generator::ApacheConstants->new(%args)->run();
-ModParrot::Config::Generator::ApacheRequestRec->new(%args)->run();
 ModParrot::Config::Generator::ModParrotConstants->new(%args)->run();
+ModParrot::Config::Generator::ApacheRequestRec->new(%args)->run();
+ModParrot::Config::Generator::ApacheServerRec->new(%args)->run();

Added: mod_parrot/trunk/build/maps/httpd/server_rec.map
==============================================================================
--- (empty file)
+++ mod_parrot/trunk/build/maps/httpd/server_rec.map	Mon Jan  5 14:33:17 2009
@@ -0,0 +1,29 @@
+# This is currently hand generated.
+# At some point we may want to just parse
+# apaches headers to get this info.
+
+#process             |              | rw
+#next                |              | rw
+defn_name           | const char * | rw
+defn_line_number    | int          | rw
+server_admin        | char *       | rw
+server_hostname     | char *       | rw
+port                | int          | rw
+error_fname         | char *       | rw
+#error_log           |              |
+loglevel            | int          | rw
+is_virtual          | int          | rw
+#module_config       |              | rw
+#lookup_defaults     |              | rw
+#addrs               |              | rw
+timeout             | int          | rw
+keep_alive_timeout  | int          | rw
+keep_alive_max      | int          | rw
+keep_alive          | int          | rw
+path                | const char * | rw
+pathlen             | int          | rw
+#names               |              | rw
+#wild_names          |              | rw
+limit_req_line      | int          | rw
+limit_req_fieldsize | int          | rw
+limit_req_fields    | int          | rw

Modified: mod_parrot/trunk/include/mod_parrot.h
==============================================================================
--- mod_parrot/trunk/include/mod_parrot.h	(original)
+++ mod_parrot/trunk/include/mod_parrot.h	Mon Jan  5 14:33:17 2009
@@ -53,6 +53,7 @@
     long count;                   /* number of interpreter invocations */
     int locked;                   /* 0=available, 1=in use */
     request_rec *r;               /* request_rec structure for this request */
+    apr_pool_t *pool;             /* the pool most specific to this phase */
     apr_pool_t *pconf;
     apr_pool_t *plog;
     apr_pool_t *ptemp;

Modified: mod_parrot/trunk/lib/ModParrot/Apache/RequestRec.pir
==============================================================================
--- mod_parrot/trunk/lib/ModParrot/Apache/RequestRec.pir	(original)
+++ mod_parrot/trunk/lib/ModParrot/Apache/RequestRec.pir	Mon Jan  5 14:33:17 2009
@@ -46,6 +46,9 @@
     .local pmc func
     .local pmc nul
 
+    load_bytecode "ModParrot/Apache/ServerRec.pbc"
+    load_bytecode "ModParrot/APR/Pool.pbc"
+
     null nul
 
     newclass rr_class, [ 'ModParrot'; 'Apache'; 'RequestRec' ]
@@ -641,6 +644,30 @@
     .return(pool)
 .end
 
+=item C<ModParrot;Apache;ServerRec server()>
+
+=over 4
+
+Returns the request's server object.
+
+=back
+
+=cut
+
+.sub server :method
+    .local pmc r, s, func
+
+    func = get_root_global [ 'ModParrot'; 'NCI' ], 'request_rec_server'
+    getattribute r, self, 'r'
+    s = func(r)
+    $P0 = get_class [ 'ModParrot'; 'Apache'; 'ServerRec' ]
+    $P1 = new 'Hash'
+    $P1['server_rec'] = s
+    $P2 = new $P0, $P1
+
+    .return($P2)
+.end
+
 =back
 
 =head1 AUTHOR

Modified: mod_parrot/trunk/lib/mod_parrot.pir
==============================================================================
--- mod_parrot/trunk/lib/mod_parrot.pir	(original)
+++ mod_parrot/trunk/lib/mod_parrot.pir	Mon Jan  5 14:33:17 2009
@@ -29,6 +29,7 @@
     loadlib $P0, 'modparrot_group.so'
 
     .include "build/src/pir/request_rec_dlfunc.pir"
+    .include "build/src/pir/server_rec_dlfunc.pir"
 
     dlfunc func, nul, "mpnci_null", "p"
     set_root_global [ 'ModParrot'; 'NCI' ], "null", func
@@ -72,6 +73,9 @@
     dlfunc func, nul, "mpnci_request_rec_pool", "pJp"
     set_root_global [ 'ModParrot'; 'NCI' ], "request_rec_pool", func
 
+    dlfunc func, nul, "mpnci_request_rec_server", "pJp"
+    set_root_global [ 'ModParrot'; 'NCI' ], "request_rec_server", func
+
     dlfunc func, nul, "mpnci_rwrite", "iJPip"
     set_root_global [ 'ModParrot'; 'NCI' ], "rwrite", func
 

Modified: mod_parrot/trunk/src/context.c
==============================================================================
--- mod_parrot/trunk/src/context.c	(original)
+++ mod_parrot/trunk/src/context.c	Mon Jan  5 14:33:17 2009
@@ -142,6 +142,7 @@
 
     typenum = Parrot_PMC_typenum(interp, "UnManagedStruct");
     p = Parrot_PMC_new(interp, typenum);
+    Parrot_register_pmc(interp, p);
     Parrot_PMC_set_pointer(interp, p, ctx);
     Parrot_store_global_s(
         interp,
@@ -180,7 +181,16 @@
 
 static apr_status_t modparrot_ctx_cleanup(void *data)
 {
+    Parrot_PMC p;
     modparrot_context *ctxp = (modparrot_context *)data;
+    if (ctxp->interp) {
+        p = Parrot_find_global_s(
+            ctxp->interp,
+            string_from_literal(ctxp->interp, "_modparrot"),
+            string_from_literal(ctxp->interp, "__context")
+        );
+        Parrot_unregister_pmc(ctxp->interp, p);
+    }
     release_ctx(ctxp);
 }
 

Modified: mod_parrot/trunk/src/mod_parrot.c
==============================================================================
--- mod_parrot/trunk/src/mod_parrot.c	(original)
+++ mod_parrot/trunk/src/mod_parrot.c	Mon Jan  5 14:33:17 2009
@@ -265,6 +265,9 @@
     /* we're FIRST, so reset the module index */
     ctxp->module_index = -1;
 
+    /* set the most specific pool */
+    ctxp->pool = r->pool;
+
     return DECLINED;
 }
 
@@ -281,6 +284,9 @@
     /* we're REALLY_FIRST, so reset the module index */
     ctxp->module_index = -1;
 
+    /* set the most specific pool */
+    ctxp->pool = c->pool;
+
     /* we only do setup */
     return DECLINED;
 }
@@ -429,6 +435,9 @@
     /* we're REALLY_FIRST, so reset the module index */
     ctxp->module_index = -1;
 
+    /* set the most specific pool */
+    ctxp->pool = c->pool;
+
     /* we only do setup */
     return DECLINED;
 }
@@ -494,6 +503,9 @@
     max_threads = 1;
 #endif /* MPM_IS_THREADED */
 
+    /* set the most specific pool */
+    ctxp->pool = p;
+
     release_ctx(ctxp);
 }
 
@@ -552,6 +564,9 @@
     /* we're FIRST, so reset the module index */
     ctxp->module_index = -1;
 
+    /* set the most specific pool */
+    ctxp->pool = pconf;
+
     /* we only do setup */
     return DECLINED;
 }
@@ -619,6 +634,9 @@
         /* we're FIRST, so reset the module index */
         ctxp->module_index = -1;
 
+        /* set the most specific pool */
+        ctxp->pool = pconf;
+
         /* load ParrotLoad files */
         modparrot_load_files(ctxp->interp, s, mpcfg->preload);
 
@@ -640,6 +658,12 @@
             }
             vsctxp->pconf = pconf;
 
+            /* we're FIRST, so reset the module index */
+            vsctxp->module_index = -1;
+
+            /* set the most specific pool */
+            ctxp->pool = pconf;
+
             /* load ParrotLoad files */
             modparrot_load_files(vsctxp->interp, vs, vscfg->preload);
 

Modified: mod_parrot/trunk/src/nci.c
==============================================================================
--- mod_parrot/trunk/src/nci.c	(original)
+++ mod_parrot/trunk/src/nci.c	Mon Jan  5 14:33:17 2009
@@ -33,6 +33,7 @@
 #include "modparrot_config.h"
 
 #include "../build/src/nci/request_rec.c"
+#include "../build/src/nci/server_rec.c"
 
 extern module AP_MODULE_DECLARE_DATA parrot_module;
 
@@ -57,6 +58,12 @@
     return(r->per_dir_config);
 }
 
+struct server_rec *mpnci_request_rec_server(Parrot_Interp interp,
+    request_rec *r)
+{
+    return(r->server);
+}
+
 apr_pool_t *mpnci_conf_pool(Parrot_Interp interp)
 {
     modparrot_context *ctxp;

Modified: mod_parrot/trunk/t/response/TestAPI/request_rec.pir
==============================================================================
--- mod_parrot/trunk/t/response/TestAPI/request_rec.pir	(original)
+++ mod_parrot/trunk/t/response/TestAPI/request_rec.pir	Mon Jan  5 14:33:17 2009
@@ -9,7 +9,7 @@
 
     ap_const = get_root_global [ 'ModParrot'; 'Apache'; 'Constants' ], 'table'
 
-    r.'puts'("1..38\n")
+    r.'puts'("1..39\n")
 
   # XXX this should be fatal on failure
   START_1:
@@ -432,6 +432,17 @@
   OK_38:
     r.'puts'("ok 38 - pool()\n")
 
+  START_39:
+    push_eh NOT_OK_39
+    $P0 = r.'server'()
+    pop_eh
+    $S0 = typeof $P0
+    if $S0 == 'ModParrot;Apache;ServerRec' goto OK_39
+  NOT_OK_39:
+    r.'puts'("not ")
+  OK_39:
+    r.'puts'("ok 39 - server()\n")
+
     # STILL TODO (not tested in original client-side tests)
     # assbackwards
     # proxyreq

Added: mod_parrot/trunk/t/response/TestAPI/server_rec.pir
==============================================================================
--- (empty file)
+++ mod_parrot/trunk/t/response/TestAPI/server_rec.pir	Mon Jan  5 14:33:17 2009
@@ -0,0 +1,25 @@
+# $Id$
+
+.namespace [ 'TestAPI::server_rec' ]
+
+.sub handler
+    .param pmc r
+    .local pmc ap_const, s
+    .local string results
+
+    ap_const = get_root_global [ 'ModParrot'; 'Apache'; 'Constants' ], 'table'
+
+    r.'puts'("1..1\n")
+
+  START_1:
+    s = r.'server'()
+    $S0 = typeof s
+    if $S0 == "ModParrot;Apache;ServerRec" goto OK_1
+  NOT_OK_1:
+    r.'puts'("not ")
+  OK_1:
+    r.'puts'("ok 1 - object\n")
+
+    $I0 = ap_const['OK']
+    .return($I0)
+.end



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About