Author: gozer
Date: Fri Mar 17 17:32:33 2006
New Revision: 386784

URL: http://svn.apache.org/viewcvs?rev=386784&view=rev
Log:
Added $r->connection->pnotes, identical to $r->pnotes, but
for the entire lifetime of the connection


Added:
    perl/modperl/trunk/t/modperl/pnotes.t
    perl/modperl/trunk/xs/Apache2/ConnectionUtil/
    perl/modperl/trunk/xs/Apache2/ConnectionUtil/Apache2__ConnectionUtil.h
Modified:
    perl/modperl/trunk/Changes
    perl/modperl/trunk/src/modules/perl/modperl_config.c
    perl/modperl/trunk/src/modules/perl/modperl_config.h
    perl/modperl/trunk/src/modules/perl/modperl_types.h
    perl/modperl/trunk/src/modules/perl/modperl_util.c
    perl/modperl/trunk/src/modules/perl/modperl_util.h
    perl/modperl/trunk/t/response/TestModperl/pnotes.pm
    perl/modperl/trunk/xs/Apache2/RequestUtil/Apache2__RequestUtil.h
    perl/modperl/trunk/xs/maps/modperl_functions.map
    perl/modperl/trunk/xs/tables/current/ModPerl/FunctionTable.pm

Modified: perl/modperl/trunk/Changes
URL: 
http://svn.apache.org/viewcvs/perl/modperl/trunk/Changes?rev=386784&r1=386783&r2=386784&view=diff
==============================================================================
--- perl/modperl/trunk/Changes (original)
+++ perl/modperl/trunk/Changes Fri Mar 17 17:32:33 2006
@@ -12,6 +12,10 @@
 
 =item 2.0.3-dev
 
+Added $r->connection->pnotes, identical to $r->pnotes, but
+for the entire lifetime of the connection
+[Geoffrey Young, Gozer]
+
 Fixed problems with add_config() and thread-safety: [Gozer]
 - $s->add_config is not allowed anymore after server startup
 - $r->add_config can only affect configuration for the current

Modified: perl/modperl/trunk/src/modules/perl/modperl_config.c
URL: 
http://svn.apache.org/viewcvs/perl/modperl/trunk/src/modules/perl/modperl_config.c?rev=386784&r1=386783&r2=386784&view=diff
==============================================================================
--- perl/modperl/trunk/src/modules/perl/modperl_config.c (original)
+++ perl/modperl/trunk/src/modules/perl/modperl_config.c Fri Mar 17 17:32:33 
2006
@@ -147,6 +147,16 @@
     return rcfg;
 }
 
+modperl_config_con_t *modperl_config_con_new(conn_rec *c)
+{
+    modperl_config_con_t *ccfg = 
+        (modperl_config_con_t *)apr_pcalloc(c->pool, sizeof(*ccfg));
+
+    MP_TRACE_d(MP_FUNC, "0x%lx\n", (unsigned long)ccfg);
+
+    return ccfg;
+}
+
 modperl_config_srv_t *modperl_config_srv_new(apr_pool_t *p, server_rec *s)
 {
     modperl_config_srv_t *scfg = (modperl_config_srv_t *)

Modified: perl/modperl/trunk/src/modules/perl/modperl_config.h
URL: 
http://svn.apache.org/viewcvs/perl/modperl/trunk/src/modules/perl/modperl_config.h?rev=386784&r1=386783&r2=386784&view=diff
==============================================================================
--- perl/modperl/trunk/src/modules/perl/modperl_config.h (original)
+++ perl/modperl/trunk/src/modules/perl/modperl_config.h Fri Mar 17 17:32:33 
2006
@@ -26,6 +26,8 @@
 
 modperl_config_req_t *modperl_config_req_new(request_rec *r);
 
+modperl_config_con_t *modperl_config_con_new(conn_rec *c);
+
 void *modperl_config_srv_create(apr_pool_t *p, server_rec *s);
 
 void *modperl_config_srv_merge(apr_pool_t *p, void *basev, void *addv);
@@ -78,6 +80,19 @@
 #define MP_dRCFG \
     modperl_config_req_t *rcfg = modperl_config_req_get(r)
 
+#define modperl_config_con_init(c, ccfg)                 \
+    if (!ccfg) {                                         \
+        ccfg = modperl_config_con_new(c);                \
+        modperl_set_module_config(c->conn_config, ccfg); \
+    }
+
+#define modperl_config_con_get(c)                               \
+    (c ? (modperl_config_con_t *)                               \
+     modperl_get_module_config(c->conn_config) : NULL)
+
+#define MP_dCCFG \
+    modperl_config_con_t *ccfg = modperl_config_con_get(c)
+    
 #define modperl_config_dir_get(r)                               \
     (r ? (modperl_config_dir_t *)                               \
      modperl_get_module_config(r->per_dir_config) : NULL)

Modified: perl/modperl/trunk/src/modules/perl/modperl_types.h
URL: 
http://svn.apache.org/viewcvs/perl/modperl/trunk/src/modules/perl/modperl_types.h?rev=386784&r1=386783&r2=386784&view=diff
==============================================================================
--- perl/modperl/trunk/src/modules/perl/modperl_types.h (original)
+++ perl/modperl/trunk/src/modules/perl/modperl_types.h Fri Mar 17 17:32:33 2006
@@ -258,7 +258,7 @@
 } modperl_config_req_t;
 
 typedef struct {
-    MpAV *handlers_connection[MP_HANDLER_NUM_CONNECTION];
+    HV *pnotes;
 } modperl_config_con_t;
 
 typedef struct {

Modified: perl/modperl/trunk/src/modules/perl/modperl_util.c
URL: 
http://svn.apache.org/viewcvs/perl/modperl/trunk/src/modules/perl/modperl_util.c?rev=386784&r1=386783&r2=386784&view=diff
==============================================================================
--- perl/modperl/trunk/src/modules/perl/modperl_util.c (original)
+++ perl/modperl/trunk/src/modules/perl/modperl_util.c Fri Mar 17 17:32:33 2006
@@ -829,11 +829,59 @@
     return data ? *(int *)data : 0;
  }
 
-SV *modperl_pnotes(pTHX_ HV **pnotes, SV *key, SV *val, request_rec *r) {
+#ifdef USE_ITHREADS
+typedef struct {
+    HV **pnotes;
+    PerlInterpreter *perl;
+} modperl_cleanup_pnotes_data_t;
+#endif
+ 
+static MP_INLINE
+apr_status_t modperl_cleanup_pnotes(void *data) {
+    HV **pnotes = data;
+
+    if (*pnotes) {
+#ifdef USE_ITHREADS
+        modperl_cleanup_pnotes_data_t *cleanup_data = data;
+        dTHXa(cleanup_data->perl);
+        pnotes = cleanup_data->pnotes;
+#else
+        pnotes = data;
+#endif
+        SvREFCNT_dec(*pnotes);
+        *pnotes = Nullhv;
+    }
+
+    return APR_SUCCESS;   
+}
+
+SV *modperl_pnotes(pTHX_ HV **pnotes, SV *key, SV *val, 
+                   request_rec *r, conn_rec *c) {
     SV *retval = Nullsv;
 
     if (!*pnotes) {
         *pnotes = newHV();
+
+        /* XXX: It would be nice to be able to do this with r->pnotes, but
+         * it's currently impossible, as 
modperl_config.c:modperl_config_request_cleanup()
+         * is responsible for running the CleanupHandlers, and it's cleanup 
callback is
+         * registered very early. If we register our cleanup here, we'll be 
running 
+         * *before* the CleanupHandlers, and they might still want to use 
pnotes...
+         */
+        if (c && !r) {
+            apr_pool_t *pool = r ? r->pool : c->pool;
+#ifdef USE_ITHREADS
+            modperl_cleanup_pnotes_data_t *cleanup_data = 
+                apr_palloc(pool, sizeof(*cleanup_data));
+            cleanup_data->pnotes = pnotes;
+            cleanup_data->perl = aTHX;
+#else
+            void *cleanup_data = pnotes;
+#endif
+            apr_pool_cleanup_register(pool, cleanup_data,
+                                      modperl_cleanup_pnotes,
+                                      apr_pool_cleanup_null);
+        }
     }
 
     if (key) {

Modified: perl/modperl/trunk/src/modules/perl/modperl_util.h
URL: 
http://svn.apache.org/viewcvs/perl/modperl/trunk/src/modules/perl/modperl_util.h?rev=386784&r1=386783&r2=386784&view=diff
==============================================================================
--- perl/modperl/trunk/src/modules/perl/modperl_util.h (original)
+++ perl/modperl/trunk/src/modules/perl/modperl_util.h Fri Mar 17 17:32:33 2006
@@ -145,6 +145,7 @@
 void modperl_restart_count_inc(server_rec *base_server);
 int  modperl_restart_count(void);
 
-SV *modperl_pnotes(pTHX_ HV **pnotes, SV *key, SV *val, request_rec *r);
+SV *modperl_pnotes(pTHX_ HV **pnotes, SV *key, SV *val,
+                   request_rec *r, conn_rec *c);
 
 #endif /* MODPERL_UTIL_H */

Added: perl/modperl/trunk/t/modperl/pnotes.t
URL: 
http://svn.apache.org/viewcvs/perl/modperl/trunk/t/modperl/pnotes.t?rev=386784&view=auto
==============================================================================
--- perl/modperl/trunk/t/modperl/pnotes.t (added)
+++ perl/modperl/trunk/t/modperl/pnotes.t Fri Mar 17 17:32:33 2006
@@ -0,0 +1,27 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest qw(GET_BODY_ASSERT);
+use Apache::Test;
+use Apache::TestUtil;
+
+my $module = 'TestModperl::pnotes';
+my $url    = Apache::TestRequest::module2url($module);
+
+t_debug("connecting to $url");
+
+plan tests => (22 * 3);
+
+# first with keepalives
+Apache::TestRequest::user_agent(reset => 1, keep_alive => 1);
+t_debug("issuing first request");
+print GET_BODY_ASSERT "$url?1";
+
+# now close the connection
+t_debug("issuing second request");
+print GET_BODY_ASSERT "$url?2", Connection => 'close';
+
+# finally, check for a cleared $c->pnotes
+t_debug("issuing final request");
+print GET_BODY_ASSERT "$url?3";
+

Modified: perl/modperl/trunk/t/response/TestModperl/pnotes.pm
URL: 
http://svn.apache.org/viewcvs/perl/modperl/trunk/t/response/TestModperl/pnotes.pm?rev=386784&r1=386783&r2=386784&view=diff
==============================================================================
--- perl/modperl/trunk/t/response/TestModperl/pnotes.pm (original)
+++ perl/modperl/trunk/t/response/TestModperl/pnotes.pm Fri Mar 17 17:32:33 2006
@@ -4,6 +4,7 @@
 use warnings FATAL => 'all';
 
 use Apache2::RequestUtil ();
+use Apache2::ConnectionUtil ();
 
 use Apache::Test;
 use Apache::TestUtil;
@@ -11,38 +12,89 @@
 use Apache2::Const -compile => 'OK';
 
 sub handler {
-    my $r = shift;
-
-    plan $r, tests => 9;
 
-    ok $r->pnotes;
+    my $r = shift;
 
-    ok t_cmp($r->pnotes('pnotes_foo', 'pnotes_bar'),
-             'pnotes_bar',
-             q{$r->pnotes(key,val)});
-
-    ok t_cmp($r->pnotes('pnotes_foo'),
-             'pnotes_bar',
-             q{$r->pnotes(key)});
-
-    ok t_cmp(ref($r->pnotes), 'HASH', q{ref($r->pnotes)});
-
-    ok t_cmp($r->pnotes()->{'pnotes_foo'}, 'pnotes_bar',
-             q{$r->pnotes()->{}});
-
-    # unset the entry (but the entry remains with undef value)
-    $r->pnotes('pnotes_foo', undef);
-    ok t_cmp($r->pnotes('pnotes_foo'), undef,
-             q{unset entry contents});
-    my $exists = exists $r->pnotes->{'pnotes_foo'};
-    $exists = 1 if $] < 5.008001; # changed in perl 5.8.1
-    ok $exists;
-
-    # now delete completely (possible only via the hash inteface)
-    delete $r->pnotes()->{'pnotes_foo'};
-    ok t_cmp($r->pnotes('pnotes_foo'), undef,
-             q{deleted entry contents});
-    ok !exists $r->pnotes->{'pnotes_foo'};
+    # make it ok to call ok() here while plan()ing elsewhere
+    Apache::Test::init_test_pm($r);
+    
+    Test::_reset_globals() if Test->can('_reset_globals');
+    $Test::ntest   = 1 + (22 * ($r->args - 1));
+    $Test::planned = 22;
+
+    my $c = $r->connection;
+
+    # we call this handler 3 times.
+    # $r->pnotes('request') should be unset each time
+    # $c->pnotes('connection') should be unset the first
+    # time but set the second time due to the keepalive
+    # request.  the second request then cleans up after
+    # itself, leaving $c->pnotes again unset at the
+    # start of the third request
+    if ($r->args == 2) {
+        ok t_cmp($c->pnotes('connection'),
+                 'CSET',
+                 '$c->pnotes() persists across keepalive requests');
+    }
+    else {
+        t_debug('testing $c->pnotes is empty');
+        ok (! $c->pnotes('connection'));
+    }
+
+    # $r->pnotes should be reset each time
+    t_debug('testing $r->pnotes is empty');
+    ok (! $r->pnotes('request'));
+
+    foreach my $map ({type => 'r', object => $r},
+                     {type => 'c', object => $c}) {
+
+        my $type = $map->{type};
+
+        my $o    = $map->{object};
+
+        t_debug("testing $type->pnotes call");
+        ok $o->pnotes;
+
+        ok t_cmp($o->pnotes('pnotes_foo', 'pnotes_bar'),
+                 'pnotes_bar',
+                 "$type->pnotes(key,val)");
+
+        ok t_cmp($o->pnotes('pnotes_foo'),
+                 'pnotes_bar',
+                 "$type->pnotes(key)");
+
+        ok t_cmp(ref($o->pnotes), 'HASH', "ref($type->pnotes)");
+
+        ok t_cmp($o->pnotes()->{'pnotes_foo'}, 'pnotes_bar',
+                 "$type->pnotes()->{}");
+
+        # unset the entry (but the entry remains with undef value)
+        $o->pnotes('pnotes_foo', undef);
+        ok t_cmp($o->pnotes('pnotes_foo'), undef,
+                 "unset $type contents");
+
+        my $exists = exists $o->pnotes->{'pnotes_foo'};
+        $exists = 1 if $] < 5.008001; # changed in perl 5.8.1
+        ok $exists;
+
+        # now delete completely (possible only via the hash inteface)
+        delete $o->pnotes()->{'pnotes_foo'};
+        ok t_cmp($o->pnotes('pnotes_foo'), undef,
+                 "deleted $type contents");
+        ok !exists $o->pnotes->{'pnotes_foo'};
+    }
+
+    # set pnotes so we can test unset on later connections
+    $r->pnotes(request => 'RSET');
+    $c->pnotes(connection => 'CSET');
+
+    ok t_cmp($r->pnotes('request'),
+             'RSET',
+             '$r->pnotes() set');
+
+    ok t_cmp($c->pnotes('connection'),
+             'CSET',
+             '$c->pnotes() set');
 
     Apache2::Const::OK;
 }

Added: perl/modperl/trunk/xs/Apache2/ConnectionUtil/Apache2__ConnectionUtil.h
URL: 
http://svn.apache.org/viewcvs/perl/modperl/trunk/xs/Apache2/ConnectionUtil/Apache2__ConnectionUtil.h?rev=386784&view=auto
==============================================================================
--- perl/modperl/trunk/xs/Apache2/ConnectionUtil/Apache2__ConnectionUtil.h 
(added)
+++ perl/modperl/trunk/xs/Apache2/ConnectionUtil/Apache2__ConnectionUtil.h Fri 
Mar 17 17:32:33 2006
@@ -0,0 +1,28 @@
+/* Copyright 2001-2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+static MP_INLINE
+SV *mpxs_Apache2__Connection_pnotes(pTHX_ conn_rec *c, SV *key, SV *val)
+{
+    MP_dCCFG;
+
+    modperl_config_con_init(c, ccfg);
+    
+    if (!ccfg) {
+        return &PL_sv_undef;
+    }
+    
+    return modperl_pnotes(aTHX_ &ccfg->pnotes, key, val, NULL, c);
+}

Modified: perl/modperl/trunk/xs/Apache2/RequestUtil/Apache2__RequestUtil.h
URL: 
http://svn.apache.org/viewcvs/perl/modperl/trunk/xs/Apache2/RequestUtil/Apache2__RequestUtil.h?rev=386784&r1=386783&r2=386784&view=diff
==============================================================================
--- perl/modperl/trunk/xs/Apache2/RequestUtil/Apache2__RequestUtil.h (original)
+++ perl/modperl/trunk/xs/Apache2/RequestUtil/Apache2__RequestUtil.h Fri Mar 17 
17:32:33 2006
@@ -217,7 +217,7 @@
         return &PL_sv_undef;
     }
 
-    return modperl_pnotes(aTHX_ &rcfg->pnotes, key, val, r);
+    return modperl_pnotes(aTHX_ &rcfg->pnotes, key, val, r, NULL);
 }
 
 #define mpxs_Apache2__RequestRec_dir_config(r, key, sv_val) \

Modified: perl/modperl/trunk/xs/maps/modperl_functions.map
URL: 
http://svn.apache.org/viewcvs/perl/modperl/trunk/xs/maps/modperl_functions.map?rev=386784&r1=386783&r2=386784&view=diff
==============================================================================
--- perl/modperl/trunk/xs/maps/modperl_functions.map (original)
+++ perl/modperl/trunk/xs/maps/modperl_functions.map Fri Mar 17 17:32:33 2006
@@ -93,6 +93,9 @@
 MODULE=Apache2::Connection
  mpxs_Apache2__Connection_client_socket | | c, s=NULL
 
+MODULE=Apache2::ConnectionUtil   PACKAGE=guess
+ mpxs_Apache2__Connection_pnotes | | c, key=Nullsv, val=Nullsv
+
 MODULE=Apache2::Filter
  modperl_filter_attributes | MPXS_ | ... | MODIFY_CODE_ATTRIBUTES
 

Modified: perl/modperl/trunk/xs/tables/current/ModPerl/FunctionTable.pm
URL: 
http://svn.apache.org/viewcvs/perl/modperl/trunk/xs/tables/current/ModPerl/FunctionTable.pm?rev=386784&r1=386783&r2=386784&view=diff
==============================================================================
--- perl/modperl/trunk/xs/tables/current/ModPerl/FunctionTable.pm (original)
+++ perl/modperl/trunk/xs/tables/current/ModPerl/FunctionTable.pm Fri Mar 17 
17:32:33 2006
@@ -1493,6 +1493,16 @@
     ]
   },
   {
+    'return_type' => 'modperl_config_con_t *',
+    'name' => 'modperl_config_con_new',
+    'args' => [
+      {
+        'type' => 'conn_rec *',
+        'name' => 'c'
+      }
+    ]
+  },
+  {
     'return_type' => 'apr_status_t',
     'name' => 'modperl_config_request_cleanup',
     'args' => [
@@ -6229,6 +6239,28 @@
       {
         'type' => 'ap_conf_vector_t *',
         'name' => 'dir_config'
+      }
+    ]
+  },
+  {
+    'return_type' => 'SV *',
+    'name' => 'mpxs_Apache2__Connection_pnotes',
+    'args' => [
+      {
+        'type' => 'PerlInterpreter *',
+        'name' => 'my_perl'
+      },
+      {
+        'type' => 'conn_rec *',
+        'name' => 'c'
+      },
+      {
+        'type' => 'SV *',
+        'name' => 'key'
+      },
+      {
+        'type' => 'SV *',
+        'name' => 'val'
       }
     ]
   },


Reply via email to