perl-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stas Bekman <s...@stason.org>
Subject Re: [MP2] failed to resolve handler `Apache::PerlSections'
Date Fri, 05 Dec 2003 01:16:38 GMT
Stas Bekman wrote:
[...]
> The problem seems to be as following: Apache::Status somehow 
> autovivifies Apache::PerlSections stash, while Apache/PerlSections.pm 
> wasn't loaded yet. That's why preloading Apache::PerlSections solves the 
> problem. Our code does not attempt to load packages whose stashes exist, 
> which is obviously wrong. I'll post a patch soonish. I think instead of 
> checking for the stash, we need to check %INC.

It was a bit trickier than I thought, but now the code is even simpler to 
follow. This should solve your problem Enrico. 'make test' pass 100% with this 
patch.

Index: src/modules/perl/modperl_mgv.c
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_mgv.c,v
retrieving revision 1.27
diff -u -r1.27 modperl_mgv.c
--- src/modules/perl/modperl_mgv.c	18 Sep 2003 07:58:46 -0000	1.27
+++ src/modules/perl/modperl_mgv.c	5 Dec 2003 01:06:47 -0000
@@ -181,6 +181,31 @@
  }
  #endif

+
+static void package2filename(apr_pool_t *p, const char *package,
+                             char **filename, int *len)
+{
+    *filename = apr_palloc(p, (strlen(package)+4)*sizeof(char));
+    const char *s;
+    char *d;
+
+    for (s = package, d = *filename; *s; s++, d++) {
+        if (*s == ':' && s[1] == ':') {
+            *d = '/';
+            s++;
+        }
+        else {
+            *d = *s;
+        }
+    }
+    *d++ = '.';
+    *d++ = 'p';
+    *d++ = 'm';
+    *d   = '\0';
+
+    *len = d - *filename;
+}
+
  /* currently used for complex filters attributes parsing */
  /* XXX: may want to generalize it for any handlers */
  #define MODPERL_MGV_DEEP_RESOLVE(handler, p) \
@@ -259,25 +284,44 @@
          }
      }

-    if (!(stash || (stash = gv_stashpv(name, FALSE))) &&
-        MpHandlerAUTOLOAD(handler)) {
-        MP_TRACE_h(MP_FUNC,
-                   "package %s not defined, attempting to load\n", name);
-
-        if (modperl_require_module(aTHX_ name, FALSE)) {
-            MP_TRACE_h(MP_FUNC, "loaded %s package\n", name);
-            if (!(stash = gv_stashpv(name, FALSE))) {
-                MP_TRACE_h(MP_FUNC, "%s package still does not exist\n",
-                           name);
+    if (!stash && MpHandlerAUTOLOAD(handler)) {
+        int len;
+        char *filename;
+        SV **svp;
+
+        package2filename(p, name, &filename, &len);
+        svp = hv_fetch(GvHVn(PL_incgv), filename, len, 0);
+
+        if (!(svp && *svp != &PL_sv_undef)) { /* not in %INC */
+            MP_TRACE_h(MP_FUNC,
+                       "package %s not in %INC, attempting to load '%s'\n",
+                       name, filename);
+
+            if (modperl_require_module(aTHX_ name, FALSE)) {
+                MP_TRACE_h(MP_FUNC, "loaded %s package\n", name);
+            }
+            else {
+                MP_TRACE_h(MP_FUNC, "failed to load %s package\n", name);
                  return 0;
              }
          }
          else {
-            MP_TRACE_h(MP_FUNC, "failed to load %s package\n", name);
-            return 0;
+            MP_TRACE_h(MP_FUNC, "package %s seems to be loaded\n"
+                       "  $INC{%s)='%s';\n",
+                       name, filename, SvPV_nolen(*svp));
          }
      }
-
+
+    /* try to lookup the stash only after loading the module, to avoid
+     * the case where a stash is autovivified by a user before the
+     * module was loaded, preventing from loading the module
+     */
+    if (!(stash || (stash = gv_stashpv(name, FALSE)))) {
+        MP_TRACE_h(MP_FUNC, "package %s seems to be loaded, "
+                   "but can't find its stash\n", name);
+        return 0;
+    }
+
      if ((gv = gv_fetchmethod(stash, handler_name)) && (cv = GvCV(gv))) {
          if (CvFLAGS(cv) & CVf_METHOD) { /* sub foo : method {}; */
              MpHandlerMETHOD_On(handler);

__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org


Mime
View raw message