You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl-cvs@perl.apache.org by sb...@locus.apache.org on 2000/08/05 22:48:13 UTC

cvs commit: modperl-site/guide CHANGES browserbugs.html config.html control.html correct_headers.html databases.html debug.html download.html index.html index_long.html install.html intro.html mod_perl_guide.pdf.gz modules.html performance.html perl.html porting.html scenario.html security.html snippets.html start.html troubleshooting.html

sbekman     00/08/05 13:48:12

  Modified:    guide    CHANGES browserbugs.html config.html control.html
                        correct_headers.html databases.html debug.html
                        download.html index.html index_long.html
                        install.html intro.html mod_perl_guide.pdf.gz
                        modules.html performance.html perl.html
                        porting.html scenario.html security.html
                        snippets.html start.html troubleshooting.html
  Log:
  * License: People asked me to redistribute mod_perl Guide in other
    ways than just mirroring the mod_perl site. Therefore I've licensed
    the guide under GPL and included the required info in the CPAN
    package.
  
  * perl:
  
    o added "Using Non-Hardcoded Configuration Module Names" (Chris Winters)
  
  * debug:
  
    o updated: "How can I find out if a mod_perl code has a memory leak"
  
    o rewritten:
      Handling the 'User pressed Stop button' case
        Detecting Aborted Connections
        The Importance of Cleanup Code
          Critical Section
          Safe Resource Locking and Cleanup Code
  
  * config:
  
    o added a sub header "Running CGI, PerlRun, and Registry Scripts
      located in the same Directory" to make the info more prominent to
      find. (Ron Pero)
  
    o PerlAddVar info was added
  
  * control
  
    o "Swapping Prevention" rewritten from scratch and moved from
      performance chapter to control chapter (Ed Phillips, Barrie
      Slaymaker, Joshua Chamas)
  
    o "Preparing for Machine Reboot" -- added a section describing the
      chkconfig(8) use (Andreas Koenig)
  
  * porting:
  
    o the wrong suggested solution to the nested sub problem was
      spotted!!! (Hunter Monroe, Hailei Dai) it's fixed now.
  
    o update: "Terminating requests and processes, the exit() and
      child_terminate() functions" -- under perl5.6 you don't need to
      override exit anymore! (Doug, Eric Cholet)
  
    o s/PerlTaintMode/PerlTaintCheck/ (Gunther Birznieks)
  
  * review:
  
    o Mark Summerfield has reviewed these chapters: modules,
    browserbugs, security and start.
  
  * performance:
  
    o "CGI.pm vs Apache::Request" and "Apache::args vs
      Apache::Request::param" were merged into a single section called:
      "Apache::args vs Apache::Request::param vs CGI::param"
  
    o The first example showing the use of ab was corrected (Joe
      Schaefer)
  
    o rewritten:
  
      + Apache::Registry PerlHandler versus Custom PerlHandler
      + Keeping the Shared Memory Limit
      + Limiting the Size of the Processes
      + Limiting Other Resources Used by Apache Child Processes
  
  * modules:
  
    o "Apache::GTopLimit - Limit Apache httpd processes" merged into
      performance chapter.
  
    o Apache::PerlVINC configuration corrected (Patrick)
  
  * Minor corrections:
    o config (Carl Hansen, Ron Pero, Jeff Chan, Cliff Rayman, Marcel
  Grunauer)
    o control (Marcel Grunauer)
    o debug (Marcel Grunauer)
    o install (Ron Pero)
    o snippets (Ask Bjoern Hansen, Chris Nokleberg)
    o perl (Will Trillich, Cliff Rayman, Jason Rhinelander)
    o porting (Ged Haywood)
  
  Revision  Changes    Path
  1.25      +91 -0     modperl-site/guide/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/CHANGES,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- CHANGES	2000/06/07 22:45:29	1.24
  +++ CHANGES	2000/08/05 20:48:04	1.25
  @@ -2,6 +2,97 @@
   		### mod_perl Guide CHANGES file ###
   		###################################
   
  +
  +08.05.2000 ver 1.25
  +
  +* License: People asked me to redistribute mod_perl Guide in other
  +  ways than just mirroring the mod_perl site. Therefore I've licensed
  +  the guide under GPL and included the required info in the CPAN
  +  package.
  +
  +* perl:
  +
  +  o added "Using Non-Hardcoded Configuration Module Names" (Chris Winters)
  +
  +
  +* debug:
  +
  +  o updated: "How can I find out if a mod_perl code has a memory leak"
  +
  +  o rewritten:
  +    Handling the 'User pressed Stop button' case 
  +      Detecting Aborted Connections 
  +      The Importance of Cleanup Code 
  +        Critical Section 
  +        Safe Resource Locking and Cleanup Code 
  +
  +* config:
  +  
  +  o added a sub header "Running CGI, PerlRun, and Registry Scripts
  +    located in the same Directory" to make the info more prominent to
  +    find. (Ron Pero)
  +  
  +  o PerlAddVar info was added
  + 
  +* control
  +
  +  o "Swapping Prevention" rewritten from scratch and moved from
  +    performance chapter to control chapter (Ed Phillips, Barrie
  +    Slaymaker, Joshua Chamas)
  +
  +  o "Preparing for Machine Reboot" -- added a section describing the
  +    chkconfig(8) use (Andreas Koenig)
  +
  +* porting: 
  +
  +  o the wrong suggested solution to the nested sub problem was
  +    spotted!!! (Hunter Monroe, Hailei Dai) it's fixed now. 
  +
  +  o update: "Terminating requests and processes, the exit() and
  +    child_terminate() functions" -- under perl5.6 you don't need to
  +    override exit anymore! (Doug, Eric Cholet)
  +
  +  o s/PerlTaintMode/PerlTaintCheck/ (Gunther Birznieks)
  +
  +* review: 
  +
  +  o Mark Summerfield has reviewed these chapters: modules,
  +  browserbugs, security and start.
  +
  +* performance:
  +
  +  o "CGI.pm vs Apache::Request" and "Apache::args vs
  +    Apache::Request::param" were merged into a single section called:
  +    "Apache::args vs Apache::Request::param vs CGI::param"
  +
  +  o The first example showing the use of ab was corrected (Joe
  +    Schaefer)
  +
  +  o rewritten: 
  +
  +    + Apache::Registry PerlHandler versus Custom PerlHandler
  +    + Keeping the Shared Memory Limit 
  +    + Limiting the Size of the Processes
  +    + Limiting Other Resources Used by Apache Child Processes
  +
  +* modules:  
  +
  +  o "Apache::GTopLimit - Limit Apache httpd processes" merged into
  +    performance chapter.
  +
  +  o Apache::PerlVINC configuration corrected (Patrick)
  +
  +* Minor corrections: 
  +  o config (Carl Hansen, Ron Pero, Jeff Chan, Cliff Rayman, Marcel Grunauer)
  +  o control (Marcel Grunauer)
  +  o debug (Marcel Grunauer)
  +  o install (Ron Pero)
  +  o snippets (Ask Bjoern Hansen, Chris Nokleberg)
  +  o perl (Will Trillich, Cliff Rayman, Jason Rhinelander)
  +  o porting (Ged Haywood)
  +
  +
  +
   06.07.2000 ver 1.24
   
   * perl: "catching exceptions" -- a few corrections (Matt Sergeant)
  
  
  
  1.11      +5 -3      modperl-site/guide/browserbugs.html
  
  Index: browserbugs.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/browserbugs.html,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- browserbugs.html	2000/06/07 22:45:29	1.10
  +++ browserbugs.html	2000/08/05 20:48:04	1.11
  @@ -81,8 +81,10 @@
   <CENTER><H1><A NAME="Preventing_QUERY_STRING_from_get">Preventing QUERY_STRING from getting corrupted because of &amp;entity key names</A></H1></CENTER>
   <P>
   In a URL which contains a query string, if the string has multiple parts
  -separated by ampersands and it contains a key named ``reg'', for example <CODE>http://my.site.com/foo.pl?foo=bar&amp;reg=foobar</CODE>, then some browsers will interpret <CODE>&amp;reg</CODE> as a magic entity and encode it as <CODE>&amp;reg;</CODE>. This will result in a corrupted <CODE>QUERY_STRING</CODE>. If you encounter this problem, then either you should avoid using such
  -keys or you should separate parameter pairs with <CODE>;</CODE> instead of <CODE>&amp;</CODE>. Both <CODE>CGI.pm</CODE> and <CODE>Apache::Request</CODE> support a semicolon instead of an ampersand as a separator. So your URI
  +separated by ampersands and it contains a key named ``reg'', for example <CODE>http://my.site.com/foo.pl?foo=bar&amp;reg=foobar</CODE>, then some browsers will interpret <CODE>&amp;reg</CODE> as an SGML entity and encode it as
  +<CODE>&amp;reg;</CODE>. This will result in a corrupted <CODE>QUERY_STRING</CODE>. If you encounter this problem, then either you should avoid using such
  +keys or you should separate parameter pairs with <CODE>;</CODE> instead of <CODE>&amp;</CODE>.
  +<CODE>CGI.pm</CODE>, <CODE>Apache::Request</CODE> and <CODE>$r-&gt;args()</CODE> support a semicolon instead of an ampersand as a separator. So your URI
   should look like this: <CODE>http://my.site.com/foo.pl?foo=bar;reg=foobar</CODE>.
   
   <P>
  @@ -155,7 +157,7 @@
   <td align=center valign=center>
   
   <b><font size=-1>Written by <a
  -href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/21/2000
   </font></b>
   <br>
   
  
  
  
  1.27      +248 -153  modperl-site/guide/config.html
  
  Index: config.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/config.html,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- config.html	2000/06/07 22:45:29	1.26
  +++ config.html	2000/08/05 20:48:04	1.27
  @@ -50,6 +50,11 @@
   	<UL>
   
   		<LI><A HREF="#Alias_Configurations">Alias Configurations</A>
  +		<UL>
  +
  +			<LI><A HREF="#Running_CGI_PerlRun_and_Regist">Running CGI, PerlRun, and Registry Scripts located in the same Directory</A>
  +		</UL>
  +
   		<LI><A HREF="#_Location_Configuration">&lt;Location&gt; Configuration</A>
   		<LI><A HREF="#Overriding_Location_Setting_in">Overriding &lt;Location&gt; Setting in &quot;Sub-Location&quot;</A>
   		<LI><A HREF="#PerlModule_and_PerlRequire_Direc">PerlModule and PerlRequire Directives</A>
  @@ -366,7 +371,7 @@
   takes precedence in these cases. This can be a trap for the unwary.
   
   <UL>
  -<P><LI><STRONG><A NAME="item__Directory_directoryPath_">&lt;Directory directoryPath&gt; ... &lt;/Directory&gt;</A></STRONG>
  +<P><LI><STRONG><A NAME="item__lt_Directory_directoryPath_gt_">&lt;Directory directoryPath&gt; ... &lt;/Directory&gt;</A></STRONG>
   <P>
   Can appear in server and virtual host configurations.
   
  @@ -380,7 +385,7 @@
   The path given in the <CODE>&lt;Directory&gt;</CODE> directive is either the full path to a directory, or a wild-card string. In
   a wild-card string, <CODE>?</CODE>
   matches any single character, <CODE>*</CODE> matches any sequence of characters, and <CODE>[]</CODE> matches character ranges. (This is similar to the shell's file globs.) None
  -of the wildcards will match a <EM>/</EM> character. For example:
  +of the wildcards will match a <CODE>/</CODE> character. For example:
   
   <P>
   
  @@ -461,15 +466,19 @@
   files as well.
   
   <P>
  -The <CODE>&lt;Files&gt;</CODE> directive provides for access control by filename. It is comparable to the <CODE>&lt;Directory&gt;</CODE> and <CODE>&lt;Location&gt;</CODE> directives. It should be closed with the <CODE>&lt;/Files&gt;</CODE> directive. The directives given within this section will be applied to any
  +The <CODE>&lt;Files&gt;</CODE> directive provides for access control by filename. It is comparable to the <CODE>&lt;Directory&gt;</CODE> and
  +<CODE>&lt;Location&gt;</CODE> directives. It should be closed with the
  +<CODE>&lt;/Files&gt;</CODE> directive. The directives given within this section will be applied to any
   object with a basename (last component of filename) matching the specified
   filename.
   
   <P>
   <CODE>&lt;Files&gt;</CODE> sections are processed in the order they appear in the configuration file,
  -after the <CODE>&lt;Directory&gt;</CODE> sections and <EM>.htaccess</EM>
  -files are read, but before <CODE>&lt;Location&gt;</CODE> sections. Note that
  -<CODE>&lt;Files&gt;</CODE> can be nested inside <CODE>&lt;Directory&gt;</CODE> sections to restrict the portion of the filesystem they apply to.
  +after the <CODE>&lt;Directory&gt;</CODE> sections and
  +<EM>.htaccess</EM> files are read, but before <CODE>&lt;Location&gt;</CODE>
  +sections. Note that <CODE>&lt;Files&gt;</CODE> can be nested inside
  +<CODE>&lt;Directory&gt;</CODE> sections to restrict the portion of the filesystem they apply to. <CODE>&lt;Files&gt;</CODE> cannot be nested inside
  +<CODE>&lt;Location&gt;</CODE> sections however.
   
   <P>
   The filename argument should include a filename, or a wild-card string,
  @@ -496,19 +505,21 @@
       </table>
       <P>
   would match most common Internet graphics formats. Alternatively you can
  -use the <CODE>&lt;FilesMatch regex&gt;</CODE> ... <CODE>&lt;/FilesMatch&gt;</CODE> syntax.
  +use the <CODE>&lt;FilesMatch regex&gt;</CODE> ... <CODE>&lt;/FilesMatch&gt;</CODE>
  +syntax.
   
  -<P><LI><STRONG><A NAME="item__Location_URL_Location_">&lt;Location URL&gt; ... &lt;/Location&gt;</A></STRONG>
  +<P><LI><STRONG><A NAME="item__lt_Location_URL_gt_lt_Lo">&lt;Location URL&gt; ... &lt;/Location&gt;</A></STRONG>
   <P>
   Can appear in server and virtual host configurations.
   
   <P>
  -The <CODE>&lt;Location&gt;</CODE> directive provides for access control by URL. It is similar to the <CODE>&lt;Directory&gt;</CODE> directive, and starts a section which is terminated with the <CODE>&lt;/Location&gt;</CODE> directive.
  +The <CODE>&lt;Location&gt;</CODE> directive provides for access control by URL. It is similar to the <CODE>&lt;Directory&gt;</CODE> directive, and starts a section which is terminated with the <CODE>&lt;/Location&gt;</CODE>
  +directive.
   
   <P>
   <CODE>&lt;Location&gt;</CODE> sections are processed in the order they appear in the configuration file,
  -after the <CODE>&lt;Directory&gt;</CODE> sections, <EM>.htaccess</EM>
  -files and <CODE>&lt;Files&gt;</CODE> sections are read.
  +after the <CODE>&lt;Directory&gt;</CODE> sections,
  +<EM>.htaccess</EM> files and <CODE>&lt;Files&gt;</CODE> sections are read.
   
   <P>
   The <CODE>&lt;Location&gt;</CODE> section is the directive that is used most often with mod_perl.
  @@ -521,7 +532,8 @@
   <P>
   The URL may use wildcards. In a wild-card string, <CODE>?</CODE> matches any single character, and <CODE>*</CODE> matches any sequences of characters, <CODE>[]</CODE>
   groups characters to match. For regular expression matches use the
  -<CODE>&lt;LocationMatch regex&gt;</CODE> ... <CODE>&lt;/LocationMatch&gt;</CODE> syntax.
  +<CODE>&lt;LocationMatch regex&gt;</CODE> ... <CODE>&lt;/LocationMatch&gt;</CODE>
  +syntax.
   
   <P>
   The <CODE>&lt;Location&gt;</CODE> functionality is especially useful when combined with the <CODE>SetHandler</CODE> directive. For example to enable status requests, but allow them only from
  @@ -557,18 +569,22 @@
   which the rules of each section apply to requests. The order of merging is:
   
   <OL>
  -<P><LI><STRONG><A NAME="item__lt_Directory_gt_except_regula">&lt;Directory&gt; (except regular expressions) and .htaccess
  -are processed simultaneously, with .htaccess overriding
  -&lt;Directory&gt;</A></STRONG>
  -<P><LI><STRONG><A NAME="item__lt_DirectoryMatch_gt_and_lt_">&lt;DirectoryMatch&gt;, and &lt;Directory&gt; with regular
  -expressions</A></STRONG>
  -<P><LI><STRONG><A NAME="item__lt_Files_gt_and_lt_FilesMatch">&lt;Files&gt; and &lt;FilesMatch&gt; are processed simultaneously</A></STRONG>
  -<P><LI><STRONG><A NAME="item__lt_Location_gt_and_lt_Locatio">&lt;Location&gt; and &lt;LocationMatch&gt; are processed simultaneously</A></STRONG>
  +<P><LI><STRONG><A NAME="item__lt_Directory_gt_except_regula">&lt;Directory&gt; (except regular expressions) and
  +.htaccess are processed simultaneously, with .htaccess
  +overriding &lt;Directory&gt;</A></STRONG>
  +<P><LI><STRONG><A NAME="item__lt_DirectoryMatch_gt_and_lt_">&lt;DirectoryMatch&gt;, and &lt;Directory&gt; with
  +regular expressions</A></STRONG>
  +<P><LI><STRONG><A NAME="item__lt_Files_gt_and_lt_FilesMatch">&lt;Files&gt; and &lt;FilesMatch&gt; are processed
  +simultaneously</A></STRONG>
  +<P><LI><STRONG><A NAME="item__lt_Location_gt_and_lt_Locatio">&lt;Location&gt; and &lt;LocationMatch&gt; are
  +processed simultaneously</A></STRONG>
   </OL>
   <P>
   Apart from <CODE>&lt;Directory&gt;</CODE>, each group is processed in the order that it appears in the configuration
  -files.  <CODE>&lt;Directory&gt;</CODE> (group 1 above) is processed in the order shortest directory component to
  -longest. If multiple <CODE>&lt;Directory&gt;</CODE> sections apply to the same directory then they are processed in the
  +files.
  +<CODE>&lt;Directory&gt;</CODE> (group 1 above) is processed in the order shortest directory component to
  +longest. If multiple
  +<CODE>&lt;Directory&gt;</CODE> sections apply to the same directory then they are processed in the
   configuration file order.
   
   <P>
  @@ -612,8 +628,8 @@
   which have their own distinct behavior. Alternatively you could use a <CODE>&lt;Files&gt;</CODE> section inside an <EM>.htaccess</EM> file.
   
   <P>
  -Note that you can't put <CODE>&lt;Files&gt;</CODE> or <CODE>&lt;FilesMatch&gt;</CODE> sections inside a <CODE>&lt;Location&gt;</CODE> section, but you can put them inside a <CODE>&lt;Directory&gt;</CODE>
  -section.
  +Note that you can't put <CODE>&lt;Files&gt;</CODE> or <CODE>&lt;FilesMatch&gt;</CODE>
  +sections inside a <CODE>&lt;Location&gt;</CODE> section, but you can put them inside a <CODE>&lt;Directory&gt;</CODE> section.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  @@ -624,8 +640,7 @@
   complete; the options are not merged.
   
   <P>
  -However if all the options on the <CODE>Options</CODE> directive are preceded by a <CODE>+</CODE> or <CODE>-</CODE> symbol, the options are merged. Any options preceded by
  -<CODE>+</CODE> are added to the options currently in force, and any options preceded by <CODE>-</CODE> are removed.
  +However if all the options on the <CODE>Options</CODE> directive are preceded by a <CODE>+</CODE> or <CODE>-</CODE> symbol, the options are merged. Any options preceded by <CODE>+</CODE> are added to the options currently in force, and any options preceded by <CODE>-</CODE> are removed.
   
   <P>
   For example, without any <CODE>+</CODE> and <CODE>-</CODE> symbols:
  @@ -743,15 +758,15 @@
           </td>
   
   	<td>
  -	  <pre>  Alias /foo /home/httpd/perl/foo</pre>
  +	  <pre>  Alias /foo /home/httpd/foo</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -will map all requests starting with <EM>/foo</EM> onto the files starting with <EM>/home/httpd/perl/foo</EM>. So when Apache gets a request <A
  -HREF="http://www.example.com/perl/test.pl">http://www.example.com/perl/test.pl</A>
  -the server will remap this into the file <EM>test.pl</EM> in the directory <EM>/home/httpd/perl/foo</EM>.
  +will map all requests starting with <EM>/foo</EM> onto the files starting with <EM>/home/httpd/foo/</EM>. So when Apache gets a request <A
  +HREF="http://www.example.com/foo/test.pl">http://www.example.com/foo/test.pl</A>
  +the server will remap this into the file <EM>test.pl</EM> in the directory <EM>/home/httpd/foo/</EM>.
   
   <P>
   In addition <CODE>ScriptAlias</CODE> assigns all the requests that match the URI (i.e. <EM>/cgi-bin</EM>) to be executed under mod_cgi.
  @@ -818,14 +833,38 @@
           </td>
   
   	<td>
  +	  <pre>  ScriptAlias /cgi-bin/ /home/httpd/cgi-bin/
  +  Alias       /perl/    /home/httpd/perl/</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +In the examples above all the requests issued for URIs starting with
  +<EM>/cgi-bin</EM> will be served from the directory <EM>/home/httpd/cgi-bin/</EM>, and starting with <EM>/perl</EM> from the directory <EM>/home/httpd/perl/</EM>.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H3><A NAME="Running_CGI_PerlRun_and_Regist">Running CGI, PerlRun, and Registry Scripts located in the same Directory</A></H3></CENTER>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
   	  <pre>  # Typical for plain cgi scripts:
  -  ScriptAlias /cgi-bin/ /home/httpd/perl/
  +  ScriptAlias /cgi-bin/  /home/httpd/perl/
       
     # Typical for Apache::Registry scripts:
  -  Alias /perl/ /home/httpd/perl/
  +  Alias       /perl/     /home/httpd/perl/
       
     # Typical for Apache::PerlRun scripts:
  -  Alias /cgi-perl/ /home/httpd/perl/</pre>
  +  Alias       /cgi-perl/ /home/httpd/perl/</pre>
           </td>
   	    
         </tr>
  @@ -852,8 +891,9 @@
   
   <P>
   You should remember that it is undesirable to run scripts in plain mod_cgi
  -mode from a mod_perl-enabled server -- the resource consumption is too
  -high, it is better to run these on a plain Apache server. See <A HREF="././strategy.html#Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A>.
  +mode from a mod_perl-enabled server--the resource consumption is too high,
  +it is better to run these on a plain Apache server. See
  +<A HREF="././strategy.html#Standalone_mod_perl_Enabled_Apac">Standalone mod_perl Enabled Apache Server</A>.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  @@ -861,8 +901,12 @@
   <CENTER><H2><A NAME="_Location_Configuration">&lt;Location&gt; Configuration</A></H2></CENTER>
   <P>
   The <CODE>&lt;Location&gt;</CODE> section assigns a number of rules which the server should follow when the
  -request's URI matches the <EM>Location</EM>. Just as it is the widely accepted convention to use <EM>/cgi-bin</EM> for your mod_cgi scripts, it is conventional to use <EM>/perl</EM> as the base URI of the perl scripts which you are running under mod_perl.
  -Let's review the following very widely used <CODE>&lt;Location&gt;</CODE> section:
  +request's URI matches the
  +<EM>Location</EM>. Just as it is the widely accepted convention to use
  +<EM>/cgi-bin</EM> for your mod_cgi scripts, it is conventional to use
  +<EM>/perl</EM> as the base URI of the perl scripts which you are running under mod_perl.
  +Let's review the following very widely used
  +<CODE>&lt;Location&gt;</CODE> section:
   
   <P>
   
  @@ -907,8 +951,7 @@
       </table>
       <P>
   Remember the <CODE>Alias</CODE> from the above section? We use the same <CODE>Alias</CODE>
  -here; if you were to use a <CODE>&lt;Location&gt;</CODE> that does not have the same
  -<CODE>Alias</CODE>, the server would fail to locate the script in the file system. You need
  +here; if you were to use a <CODE>&lt;Location&gt;</CODE> that does not have the same <CODE>Alias</CODE>, the server would fail to locate the script in the file system. You need
   the <CODE>Alias</CODE> setting only if the code that should be executed is located in the file. So <CODE>Alias</CODE> just provides the URI to filepath translation rule.
   
   <P>
  @@ -1039,8 +1082,8 @@
   
   <P>
   Note that sometimes you will have to preload the module before using it in
  -the <CODE>&lt;Location&gt;</CODE> section. In the case of <CODE>Apache::Registry</CODE>
  -the configuration will look like this:
  +the <CODE>&lt;Location&gt;</CODE> section. In the case of
  +<CODE>Apache::Registry</CODE> the configuration will look like this:
   
   <P>
   
  @@ -1156,15 +1199,11 @@
   <P>
   As we saw earlier, a module should be loaded before it is used.
   <CODE>PerlModule</CODE> and <CODE>PerlRequire</CODE> are the two mod_perl directives which are used to load modules and code.
  -They are equivalent to Perl's <CODE>use()</CODE> and <CODE>require()</CODE>
  -functions respectively. Since they are equivalent, the same rules apply to
  -their arguments. Thus you would give <CODE>Apache::DBI</CODE> as an argument for a <CODE>PerlModule</CODE> directive, while you would give <EM>Apache/DBI.pm</EM> for <CODE>PerlRequire</CODE>.
  +They are almost equivalent to Perl's <CODE>use()</CODE> and <CODE>require()</CODE> functions respectively and called from the Apache configuration file. You
  +can pass one or more module names as arguments to <CODE>PerlModule</CODE>:
   
   <P>
  -You may load modules from the configuration file at server startup e.g.:
   
  -<P>
  -
       <table>
         <tr>
   
  @@ -1198,9 +1237,12 @@
         </tr>
       </table>
       <P>
  -As with any file with Perl code that gets <CODE>require()'d,</CODE> it must
  -return a <EM>true</EM> value. To ensure that this happens don't forget to add
  -<CODE>1;</CODE> at the end of <EM>startup.pl</EM>.
  +A <CODE>PerlRequire</CODE> file name can be absolute or relative to
  +<CODE>ServerRoot</CODE> or a path in <CODE>@INC</CODE>.
  +
  +<P>
  +As with any file with Perl code that gets <CODE>use()</CODE>'d or
  +<CODE>require()</CODE>'d, it must return a <EM>true</EM> value. To ensure that this happens don't forget to add <CODE>1;</CODE> at the end of <EM>startup.pl</EM>.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  @@ -1226,21 +1268,17 @@
   Ordinarily a C module is written, compiled and configured to hook into a
   specific phase of the request loop. For a Perl handler you compile mod_perl
   itself to hook into the appropriate phases, as if it were to handle the
  -phases itself. Then you put Perl*Handler directives in your configuration
  -file to tell mod_perl that it is to pass the responsibility for handling
  -that part of the request phase to your Perl module.
  +phases itself. Then you put
  +<CODE>Perl*Handler</CODE> directives in your configuration file to tell mod_perl that it is to pass
  +the responsibility for handling that part of the request phase to your Perl
  +module.
   
   <P>
   mod_perl is an Apache module written in C. As most programmers will only
  -need to handle the response phase, in the default compilation most of the
  -Perl*Handlers are disabled. When you configure the
  +need to handle the response phase, in the default compilation most of the <CODE>Perl*Handler</CODE>s are disabled. When you configure the
   <EM>Makefile.PL</EM> file for its compilation, you must specify whether or not you will want to
   handle parts of the request loop other than the usual content generation
  -phase. If so you need to specify which parts. See the INSTALL section for
  -how to do this.
  -
  -<P>
  -META: link above
  +phase. If so you need to specify which parts. See the ``<A HREF="././install.html#Callback_Hooks">Callback Hooks</A>'' section for how to do this.
   
   <P>
   Apache specifies about eleven phases of the request loop, namely (and in
  @@ -1268,7 +1306,8 @@
   mod_perl module!) is not present in your copy of Apache executable.
   
   <P>
  -The full list of Perl*Handlers follows:
  +The full list of <CODE>Perl*Handler</CODE>s follows. They are in the order that they are processed by Apache and
  +mod_perl:
   
   <P>
   
  @@ -1307,21 +1346,20 @@
   memory.
   
   <P>
  -All <CODE>&lt;Location&gt;</CODE>, <CODE>&lt;Directory&gt;</CODE> and <CODE>&lt;Files&gt;</CODE> sections contain a physical path specification. Like <CODE>PerlChildInitHandler</CODE> and
  -<CODE>PerlChildExitHandler</CODE>, the directives <CODE>PerlPostReadRequestHandler</CODE>
  -and <CODE>PerlTransHandler</CODE> cannot be used in these sections, nor in
  -<EM>.htaccess</EM> files, because it is not until the end of the Translation Handler (<CODE>PerlTransHandler</CODE>) phase that the path translation is completed and a physical path is
  +All <CODE>&lt;Location&gt;</CODE>, <CODE>&lt;Directory&gt;</CODE> and
  +<CODE>&lt;Files&gt;</CODE> sections contain a physical path specification. Like <CODE>PerlChildInitHandler</CODE> and <CODE>PerlChildExitHandler</CODE>, the directives <CODE>PerlPostReadRequestHandler</CODE> and <CODE>PerlTransHandler</CODE>
  +cannot be used in these sections, nor in <EM>.htaccess</EM> files, because it is not until the end of the Translation Handler (<CODE>PerlTransHandler</CODE>) phase that the path translation is completed and a physical path is
   known.
   
   <P>
   <CODE>PerlInitHandler</CODE> changes its behaviour depending upon where it is used. In any case it is
  -the first handler to be invoked in serving a request. If found outside any <CODE>&lt;Location&gt;</CODE>, <CODE>&lt;Directory&gt;</CODE> or
  -<CODE>&lt;Files&gt;</CODE> section, it is an alias for <CODE>PerlPostReadRequestHandler</CODE>. When outside any such section it is an alias for
  -<CODE>PerlHeaderParserHandler</CODE>.
  +the first handler to be invoked in serving a request. If found outside any <CODE>&lt;Location&gt;</CODE>,
  +<CODE>&lt;Directory&gt;</CODE> or <CODE>&lt;Files&gt;</CODE> section, it is an alias for <CODE>PerlPostReadRequestHandler</CODE>. When outside any such section it is an alias for <CODE>PerlHeaderParserHandler</CODE>.
   
   <P>
   Starting from <CODE>PerlHeaderParserHandler</CODE> the requested URI has been mapped to a physical server pathname, and thus
  -it can be used to match a <CODE>&lt;Location&gt;</CODE>, <CODE>&lt;Directory&gt;</CODE> or <CODE>&lt;Files&gt;</CODE> configuration section, or to look in a <EM>.htaccess</EM> file if such a file exists in the specified directory in the translated
  +it can be used to match a <CODE>&lt;Location&gt;</CODE>, <CODE>&lt;Directory&gt;</CODE> or <CODE>&lt;Files&gt;</CODE>
  +configuration section, or to look in a <EM>.htaccess</EM> file if such a file exists in the specified directory in the translated
   path.
   
   <P>
  @@ -1331,20 +1369,16 @@
   <P>
   The Apache documentation will tell you all about these stages and what your
   modules can do. By default, most of these hooks are disabled at compile
  -time, see the INSTALL section for information on enabling them.
  +time, see the``<A HREF="././install.html#Callback_Hooks">Callback Hooks</A>'' section for information on enabling them.
   
   <P>
  -META: Link for INSTALL section above?
  -
  -<P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
   <CENTER><H2><A NAME="The_handler_subroutine">The handler subroutine</A></H2></CENTER>
   <P>
   By default the mod_perl API expects a subroutine called <CODE>handler()</CODE>
  -to handle the request in the registered Perl*Handler module. Thus if your
  -module implements this subroutine, you can register the handler with
  -mod_perl like this:
  +to handle the request in the registered <CODE>Perl*Handler</CODE> module. Thus if your module implements this subroutine, you can register
  +the handler with mod_perl like this:
   
   <P>
   
  @@ -1362,7 +1396,7 @@
         </tr>
       </table>
       <P>
  -Replace <EM>Perl*Handler</EM> with the name of a specific handler from the list given above. mod_perl
  +Replace <CODE>Perl*Handler</CODE> with the name of a specific handler from the list given above. mod_perl
   will preload the specified module for you. Please note that this approach
   will not preload the module at startup. To make sure it gets loaded you
   have three options: you can explicitly preload it with the <CODE>PerlModule</CODE> directive:
  @@ -1550,7 +1584,7 @@
   
   <P>
   <CODE>CGI.pm</CODE> maintains a global object for its plain function interface. Since the
  -object is global, it does not go out of scope, DESTROY is never called.  <CODE>CGI-&gt;new</CODE> can call:
  +object is global, it does not go out of scope, <CODE>DESTROY</CODE> is never called.  <CODE>CGI-&gt;new</CODE> can call:
   
   <P>
   
  @@ -1737,7 +1771,7 @@
         </tr>
       </table>
       <P>
  -Now, OutputParser goes first, but it <CODE>untie()'s</CODE> <CODE>*STDOUT</CODE> and re-tie()'s it to its own package like so:
  +Now, <CODE>OutputParser</CODE> goes first, but it <CODE>untie()</CODE>'s <CODE>*STDOUT</CODE> and re-<CODE>tie()</CODE>'s it to its own package like so:
   
   <P>
   
  @@ -2016,11 +2050,11 @@
       </table>
       <P>
   <CODE>PerlPassEnv</CODE> passes, <CODE>PerlSetEnv</CODE> sets and passes <EM>ENVironment</EM>
  -variables to your scripts. You can access them in your scripts through
  -<CODE>%ENV</CODE> (e.g. <CODE>$ENV{&quot;key&quot;}</CODE>).
  +variables to your scripts. You can access them in your scripts through <CODE>%ENV</CODE> (e.g. <CODE>$ENV{&quot;key&quot;}</CODE>).
   
   <P>
  -Regarding the setting of <CODE>PerlPassEnv PERL5LIB</CODE> in <EM>httpd.conf</EM>: if you turn on taint checks (<CODE>PerlTaintMode On</CODE>), <CODE>$ENV{PERL5LIB}</CODE> will be ignored (unset). See the '<A HREF="././porting.html#Command_line_Switches_w_T_e">Switches -w, -T</A>' section.
  +Regarding the setting of <CODE>PerlPassEnv PERL5LIB</CODE> in <EM>httpd.conf</EM>: if you turn on taint checks (<CODE>PerlTaintCheck On</CODE>), <CODE>$ENV{PERL5LIB}</CODE>
  +will be ignored (unset). See the '<A HREF="././porting.html#Command_line_Switches_w_T_e">Switches -w, -T</A>' section.
   
   <P>
   <CODE>PerlSetVar</CODE> is very similar to <CODE>PerlSetEnv</CODE>, but you extract it with another method. 
  @@ -2035,7 +2069,7 @@
           </td>
   
   	<td>
  -	  <pre>  PerlSetVar key val</pre>
  +	  <pre>  PerlSetVar foo bar</pre>
           </td>
   	    
         </tr>
  @@ -2053,7 +2087,7 @@
           </td>
   
   	<td>
  -	  <pre>  push @{ $Location{&quot;/&quot;}-&gt;{PerlSetVar} }, [ key =&gt; 'val' ];</pre>
  +	  <pre>  push @{ $Location{&quot;/&quot;}-&gt;{PerlSetVar} }, [ foo =&gt; 'bar' ];</pre>
           </td>
   	    
         </tr>
  @@ -2072,7 +2106,7 @@
   
   	<td>
   	  <pre>  my $r = Apache-&gt;request;
  -  print $r-&gt;dir_config('key');</pre>
  +  print $r-&gt;dir_config('foo');</pre>
           </td>
   	    
         </tr>
  @@ -2090,7 +2124,7 @@
           </td>
   
   	<td>
  -	  <pre>  val</pre>
  +	  <pre>  value</pre>
           </td>
   	    
         </tr>
  @@ -2108,7 +2142,7 @@
           </td>
   
   	<td>
  -	  <pre>  push @{ $Location{&quot;/&quot;}-&gt;{PerlSetVar} }, [ key =&gt; \%hash ];</pre>
  +	  <pre>  push @{ $Location{&quot;/&quot;}-&gt;{PerlSetVar} }, [ foo =&gt; \%bar ];</pre>
           </td>
   	    
         </tr>
  @@ -2118,8 +2152,69 @@
   to a hash as a value (something which will look like ``<CODE>HASH(0x87a5108)</CODE>''). This cannot be turned back into a reference and therefore the original
   hash upon retrieval.
   
  +<P>
  +However you can use the <CODE>PerlAddVar</CODE> directive to push more values into the variable, emulating arrays. For
  +example: PerlSetVar foo bar PerlAddVar foo bar1 PerlAddVar foo bar2
  +
  +<P>
  +or the equal:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlAddVar foo bar
  +  PerlAddVar foo bar1
  +  PerlAddVar foo bar2</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +To retrieve the values use the <CODE>get()</CODE> method:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my @foo = $r-&gt;dir_config-&gt;get('foo');</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +or
  +
   <P>
  -However you can 
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my %foo = $r-&gt;dir_config-&gt;get('foo');</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Make sure that you use an even number of elements if you store the
  +retrieved values in a hash.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  @@ -2314,9 +2409,9 @@
         </tr>
       </table>
       <P>
  -The only chance to permanently modify the <CODE>@INC</CODE> before the server is started is with this command. Later the running code
  +The only chance to permanently modify <CODE>@INC</CODE> before the server is started is with this command. Later the running code
   can modify
  -<CODE>@INC</CODE> just for the moment it <CODE>requre()'s</CODE> some file, and then
  +<CODE>@INC</CODE> just for the moment it <CODE>require()</CODE>'s some file, and then
   <CODE>@INC</CODE>'s value gets reset to what it was originally.
   
   <P>
  @@ -2361,7 +2456,8 @@
   Unless you need the symbols (variables and subroutines) exported by the
   modules you preload to accomplish something within the startup file, don't
   import them, since it's just a waste of startup time. Instead use the empty
  -list <CODE>()</CODE> to tell the <CODE>import()</CODE> function not to import anything.
  +list <CODE>()</CODE> to tell the <CODE>import()</CODE>
  +function not to import anything.
   
   <P>
   
  @@ -2460,11 +2556,11 @@
   once, it might be a good idea to precompile all or a part of its methods.
   
   <P>
  -<CODE>CGI.pm</CODE>'s <CODE>compile()</CODE> method performs this task. Notice that this is a
  -propietary function of this module, other modules can implement this
  -feature or not and use this or some other name for this functionality. As
  -with all modules we preload in the startup file, we don't import symbols
  -from them as they will be lost when they go out of the file's scope.
  +<CODE>CGI.pm</CODE>'s <CODE>compile()</CODE> method performs this task. Notice that this is a proprietary function of
  +this module, other modules can implement this feature or not and use this
  +or some other name for this functionality. As with all modules we preload
  +in the startup file, we don't import symbols from them as they will be lost
  +when they go out of the file's scope.
   
   <P>
   Note that starting with <CODE>$CGI::VERSION</CODE> 2.46, the recommended method to precompile the code in <CODE>CGI.pm</CODE> is:
  @@ -2522,7 +2618,7 @@
   any symbols that we actually need in each script individually.
   
   <P>
  -Normally when we write <CODE>use MyModule;</CODE>, <CODE>use</CODE> will both load the module and import its symbols; so for the startup file
  +Normally when we write <CODE>use MyModule;</CODE>, <CODE>use()</CODE> will both load the module and import its symbols; so for the startup file
   we write <CODE>use
   MyModule ();</CODE> and the empty parentheses will ensure that the module is loaded but that no
   symbols are imported. Then in the actual mod_perl script we write <CODE>use()</CODE> in the standard way, e.g. <CODE>use MyModule;</CODE>. Since the module has already been preloaded, the only action taken is to
  @@ -2563,7 +2659,7 @@
         </tr>
       </table>
       <P>
  -For example, if you have <CODE>use()'d</CODE>  <CODE>Apache::Constants</CODE> in the startup file, it does not mean you can have the following handler:
  +For example, if you have <CODE>use()</CODE>'d <CODE>Apache::Constants</CODE> in the startup file, it does not mean you can have the following handler:
   
   <P>
   
  @@ -2629,9 +2725,8 @@
   export the method symbols.
   
   <P>
  -Technically, you aren't required to supply the <CODE>use()</CODE> statement
  -in your (handler?) code if it was already loaded during server startup
  -(i.e. by '<CODE>PerlRequire startup.pl</CODE>'). When writing your code, however, you should not assume the module code
  +Technically, you aren't required to supply the <CODE>use()</CODE> statement in your (handler?) code if it was already loaded during server
  +startup (i.e. by '<CODE>PerlRequire startup.pl</CODE>'). When writing your code, however, you should not assume the module code
   has been preloaded. In the future, you or someone else will revist this
   code and will not understand how it is possible to use a module's methods
   without first loading the module itself.
  @@ -2673,7 +2768,7 @@
   special package whose symbol table mod_perl can then walk and grind the
   names and values of Perl variables/structures through the Apache core
   configuration gears. Most of the configuration directives can be
  -represented as scalars (<CODE>$scalar</CODE>) or lists (<CODE>@list</CODE>). A <CODE>@List</CODE> inside these sections is simply converted into a space delimited string for
  +represented as scalars (<CODE>$scalar</CODE>) or lists (<CODE>@list</CODE>). A <CODE>@list</CODE> inside these sections is simply converted into a space delimited string for
   you. Here is an example:
   
   <P>
  @@ -2703,7 +2798,8 @@
         </tr>
       </table>
       <P>
  -Block sections such as <CODE>&lt;Location&gt;</CODE>..<CODE>&lt;/Location&gt;</CODE> are represented in a <CODE>%Location</CODE> hash, e.g.:
  +Block sections such as <CODE>&lt;Location&gt;</CODE>..<CODE>&lt;/Location&gt;</CODE>
  +are represented in a <CODE>%Location</CODE> hash, e.g.:
   
   <P>
   
  @@ -2736,7 +2832,7 @@
       <P>
   If an Apache directive can take two or three arguments you may push strings
   (the lowest number of arguments will be shifted off the
  -<CODE>@List</CODE>) or use an array reference to handle any number greater than the minimum
  +<CODE>@list</CODE>) or use an array reference to handle any number greater than the minimum
   for that directive:
   
   <P>
  @@ -2813,7 +2909,8 @@
   <P>
   <CODE>&lt;Perl&gt;</CODE> sections come to rescue. Now you have a single configuration file and the
   full power of Perl to tweak the local configuration. For example to solve
  -the problem of the <CODE>ServerName</CODE> directive you might have this <CODE>&lt;Perl&gt;</CODE> section:
  +the problem of the <CODE>ServerName</CODE>
  +directive you might have this <CODE>&lt;Perl&gt;</CODE> section:
   
   <P>
   
  @@ -2860,11 +2957,13 @@
       </table>
       <P>
   Behind the scenes, mod_perl defines a package called
  -<CODE>Apache::ReadConfig</CODE>. Here it keeps all the variables that you define inside the <CODE>&lt;Perl&gt;</CODE> sections. Therefore it's not necessarily to configure the server within the <CODE>&lt;Perl&gt;</CODE> sections. Actually what you can do is to write the Perl code to configure
  -the server just like you'd do in the <CODE>&lt;Perl&gt;</CODE> sections, but instead place it into a separate file that should be called
  -during the configuration parsing with either <CODE>PerlModule</CODE> or <CODE>PerlRequire</CODE> directives, or from within the startup file. All you have to do is to
  -declare the package
  -<CODE>Apache::ReadConfig</CODE> within this file. Using the last example:
  +<CODE>Apache::ReadConfig</CODE>. Here it keeps all the variables that you define inside the <CODE>&lt;Perl&gt;</CODE> sections. Therefore it's not necessarily to configure the server within the <CODE>&lt;Perl&gt;</CODE>
  +sections. Actually what you can do is to write the Perl code to configure
  +the server just like you'd do in the <CODE>&lt;Perl&gt;</CODE>
  +sections, but instead place it into a separate file that should be called
  +during the configuration parsing with either <CODE>PerlModule</CODE> or
  +<CODE>PerlRequire</CODE> directives, or from within the startup file. All you have to do is to
  +declare the package <CODE>Apache::ReadConfig</CODE> within this file. Using the last example:
   
   <P>
   
  @@ -2914,15 +3013,16 @@
   <HR>
   <CENTER><H2><A NAME="Enabling">Enabling</A></H2></CENTER>
   <P>
  -To enable <CODE>&lt;Perl&gt;</CODE> sections you should build mod_perl with perl
  -Makefile.PL&nbsp;PERL_SECTIONS=1&nbsp;[&nbsp;...&nbsp;].
  +To enable <CODE>&lt;Perl&gt;</CODE> sections you should build mod_perl with
  +perl&nbsp;Makefile.PL&nbsp;PERL_SECTIONS=1&nbsp;[&nbsp;...&nbsp;].
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
   <CENTER><H2><A NAME="Caveats">Caveats</A></H2></CENTER>
   <P>
  -Be careful when you declare package names inside <CODE>&lt;Perl&gt;</CODE> sections, for example this code has a problem:
  +Be careful when you declare package names inside <CODE>&lt;Perl&gt;</CODE>
  +sections, for example this code has a problem:
   
   <P>
   
  @@ -2948,7 +3048,8 @@
       <P>
   When you put code inside a <CODE>&lt;Perl&gt;</CODE> section, by default it actually goes into the <CODE>Apache::ReadConfig</CODE> package, which is already declared for you. This means that the <CODE>PerlTransHandler</CODE> we have tried to define above is actually undefined. If you define a
   different package name within a <CODE>&lt;Perl&gt;</CODE> section you must make sure to close the scope of that package and return to
  -the <CODE>Apache::ReadConfig</CODE> package when you want to define the configuration directives, like this:
  +the
  +<CODE>Apache::ReadConfig</CODE> package when you want to define the configuration directives, like this:
   
   <P>
   
  @@ -3021,8 +3122,8 @@
         </tr>
       </table>
       <P>
  -In a running httpd you can see how you have configured the <CODE>&lt;Perl&gt;</CODE>
  -sections through the URI
  +In a running httpd you can see how you have configured the
  +<CODE>&lt;Perl&gt;</CODE> sections through the URI
   <A HREF="././debug.html#Apache_Status_Embedded_Inter">/perl-status</A>, by choosing <EM>Perl
   Section Configuration</EM> from the menu. In order to make this item show up in the menu you should
   set <CODE>$Apache::Server::SaveConfig</CODE> to a true value. When you do that the <EM>Apache::ReadConfig</EM> namespace (in which the configuration data is stored) will not be flushed,
  @@ -3110,7 +3211,8 @@
         </tr>
       </table>
       <P>
  -You can then <CODE>require()</CODE> that file in some other <CODE>&lt;Perl&gt;</CODE> section.
  +You can then <CODE>require()</CODE> that file in some other <CODE>&lt;Perl&gt;</CODE>
  +section.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  @@ -3142,16 +3244,15 @@
       </table>
       <P>
   then mod_perl will not tolerate invalid Apache configuration syntax and
  -will croak (die) if this is the case. At the time of writing the default
  -value is <CODE>0</CODE>.
  +will <CODE>croak</CODE> (die) if this is the case. At the time of writing the default value is <CODE>0</CODE>.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
   <CENTER><H2><A NAME="Debugging">Debugging</A></H2></CENTER>
   <P>
  -If you compile modperl with <CODE>PERL_TRACE=1</CODE> and set the environment variable <A HREF="././debug.html#Debug_Tracing">MOD_PERL_TRACE</A> then you should see some useful diagnostics when mod_perl is processing
  -&lt;Perl&gt; sections.
  +If you compile mod_perl with <CODE>PERL_TRACE=1</CODE> and set the environment variable <A HREF="././debug.html#Debug_Tracing">MOD_PERL_TRACE</A> then you should see some useful diagnostics when mod_perl is processing <CODE>&lt;Perl&gt;</CODE>
  +sections.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  @@ -3172,10 +3273,10 @@
   <CODE>apachectl configtest</CODE> tests the configuration file without starting the server. You can safely
   validate the configuration file on your production server, if you run this
   test before you restart the server with <CODE>apachectl restart</CODE>. Of course it is not 100% perfect, but it will reveal any syntax errors
  -you might have made while editing the file. 
  +you might have made while editing the file.
   
   <P>
  -'<CODE>apachectl configtest</CODE>' is the same as '<CODE>httpd -t</CODE>' and it doesn't just parse the code in startup.pl it actually executes it.
  +'<CODE>apachectl configtest</CODE>' is the same as '<CODE>httpd -t</CODE>' and it doesn't just parse the code in <EM>startup.pl</EM>, it actually executes it.
   <CODE>&lt;Perl&gt;</CODE> configuration has always started Perl during the configuration read, and <CODE>Perl{Require,Module}</CODE> do so as well.
   
   <P>
  @@ -3306,6 +3407,10 @@
   running on the blocked port.
   
   <P>
  +[META: this is incomplete. Should add <CODE>ProxyPassReverse</CODE> to the front end (to rewrite the hostname for external redirects), and Port
  +80 to the backend for scripts that use <CODE>SERVER_PORT</CODE> env var]
  +
  +<P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
   <CENTER><H1><A NAME="Configuring_Apache_mod_perl_wi">Configuring Apache + mod_perl with mod_macro</A></H1></CENTER>
  @@ -3504,8 +3609,7 @@
       </table>
       <P>
   Finally, here is a complete example that uses macros to set up simple
  -virtual hosts. It uses the BasicAuth macro defined previously (yes, macros
  -can be nested!).
  +virtual hosts. It uses the <CODE>BasicAuth</CODE> macro defined previously (yes, macros can be nested!).
   
   <P>
   
  @@ -3570,8 +3674,7 @@
   <HR>
   <CENTER><H2><A NAME="My_CGI_Perl_Code_Gets_Returned_a">My CGI/Perl Code Gets Returned as Plain Text Instead of Being Executed by the Webserver</A></H2></CENTER>
   <P>
  -Check your configuration files and make sure that the ``ExecCGI'' is turned
  -on in your configurations.
  +Check your configuration files and make sure that the <CODE>ExecCGI</CODE> is turned on in your configurations.
   
   <P>
   
  @@ -3599,14 +3702,15 @@
   <HR>
   <CENTER><H2><A NAME="My_Script_Works_under_mod_cgi_b">My Script Works under mod_cgi, but when Called via mod_perl I Get a 'Save-As' Prompt</A></H2></CENTER>
   <P>
  -Did you put <STRONG>PerlSendHeader On</STRONG> in the configuration part of the &lt;Location foo&gt;&lt;/Location&gt;?
  +Did you put <STRONG>PerlSendHeader On</STRONG> in the configuration part of the
  +<CODE>&lt;Location foo&gt;&lt;/Location&gt;</CODE>?
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
   <CENTER><H2><A NAME="Is_There_a_Way_to_Provide_a_Diff">Is There a Way to Provide a Different startup.pl File for Each Individual Virtual Host</A></H2></CENTER>
   <P>
  -No. Any virtual host will be able to see the routines from a startup.pl
  +No. Any virtual host will be able to see the routines from a <EM>startup.pl</EM>
   loaded for any other virtual host.  
   
   <P>
  @@ -3629,7 +3733,8 @@
   <P>
   This has been a bug before, last fixed in 1.15_01, i.e. if you are running
   1.15, that could be the problem. You should set this variable in a startup
  -file (which you load with <CODE>PerlRequire</CODE> in <EM>httpd.conf</EM>):
  +file (which you load with <CODE>PerlRequire</CODE> in
  +<EM>httpd.conf</EM>):
   
   <P>
   
  @@ -3649,9 +3754,8 @@
       <P>
   But, as we know sometimes a bug turns out to be a feature. If the same
   script is running for more than one Virtual host on the same machine, this
  -can be a waste, right? Set it to 0 in a startup script if you want to turn
  -it off and have this bug as a feature. (Only makes sense if you are sure
  -that there will be no <EM>other</EM> scripts with the same path/name). It also saves you some memory as well.
  +can be a waste, right? Set it to <CODE>0</CODE> in a startup script if you want to turn it off and have this bug as a
  +feature. (Only makes sense if you are sure that there will be no <EM>other</EM> scripts with the same path/name). It also saves you some memory as well.
   
   <P>
   
  @@ -3674,8 +3778,9 @@
   <CENTER><H2><A NAME="the_Server_no_Longer_Retrieves_t">the Server no Longer Retrieves the DirectoryIndex Files for a Directory</A></H2></CENTER>
   <P>
   The problem was reported by users who declared mod_perl configuration
  -inside a &lt;Directory&gt; section for all files matching *.pl. The problem went away
  -after placing the directives in a <CODE>&lt;Files&gt;</CODE> section.
  +inside a <CODE>&lt;Directory&gt;</CODE> section for all files matching *.pl. The problem went away after placing
  +the directives in a <CODE>&lt;Files&gt;</CODE>
  +section.
   
   <P>
   The mod_alias and mod_rewrite are both Trans handlers in the normal case.
  @@ -3693,10 +3798,10 @@
   <P>
   The solution is not to mix mod_rewrite and mod_alias. mod_rewrite does
   everything mod_alias does--except for <CODE>ScriptAlias</CODE> which is not really relevant to mod_perl anyway. Don't rely on the module
  -ordering, but use explicitely disjoint URL namespaces for Alias and
  -Rewrite. In other words any URL regexp that can potentially match a Rewrite
  -rule should not be used in an Alias, and vice versa. Given that mod_rewrite
  -can easily do what mod_alias does, it's no problem
  +ordering, but use explicitely disjoint URL namespaces for <CODE>Alias</CODE> and
  +<CODE>Rewrite</CODE>. In other words any URL regexp that can potentially match a
  +<CODE>Rewrite</CODE> rule should not be used in an <CODE>Alias</CODE>, and vice versa. Given that mod_rewrite can easily do what mod_alias does,
  +it's no problem.
   
   <P>
   Here is one of the exmaples where <CODE>Alias</CODE> is replaced with
  @@ -3717,8 +3822,6 @@
     RewriteLogLevel   0
     RewriteRule       ^/(perl.*)$    <A HREF="http://127.0.0.1:8045/">http://127.0.0.1:8045/</A>$1  [P,L]
     RewriteRule       ^/(mail.*)$    <A HREF="http://127.0.0.1:8045/">http://127.0.0.1:8045/</A>$1  [P,L]
  -  RewriteRule       ^proxy:.*      -                         [F]
  -  ProxyRequests     on
     NoCache           *
     ProxyPassReverse  / <A HREF="http://www.example.com/">http://www.example.com/</A>
     
  @@ -3735,9 +3838,8 @@
   <P>
   In the above setup we proxy requests starting with <EM>/perl</EM> or
   <EM>/mail</EM> to the mod_perl server, forbid proxy requests to the external sites, and
  -make sure that the proxied requests will use the <A
  -HREF="http://www.example.com/">http://www.example.com/</A> as their URL on
  -the way back to the client.
  +make sure that the proxied requests will use the
  +<EM>http://www.example.com/</EM> as their URL on the way back to the client.
   
   <P>
   The <CODE>RedirectMatch</CODE> settings work exactly like if you'd write:
  @@ -3778,10 +3880,8 @@
     RewriteLogLevel   0
     RewriteMap        lowercase int:tolower
     RewriteRule       ^/(perl.*)$  <A HREF="http://127.0.0.1:8042/">http://127.0.0.1:8042/</A>$1   [P,L]
  -  RewriteRule       ^proxy:.*     -                         [F]
     RewriteRule       ^/$           /pages/welcome.htm        [R=301,L]
     RewriteRule       ^(.*)$        ${lowercase:$1}
  -  ProxyRequests     on
     NoCache           *
     ProxyPassReverse  /  <A HREF="http://www.example.com/">http://www.example.com/</A></pre>
           </td>
  @@ -3794,10 +3894,6 @@
   rewritten as <CODE>^(/.+)$</CODE> and all would be well.
   
   <P>
  -It's very important to stress the line that ends with <CODE>[F]</CODE>, which prevents people from unduly using your proxy server. This is a
  -security issue.
  -
  -<P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
   <CENTER><H1><A NAME="Configuration_Security_Concerns">Configuration Security Concerns</A></H1></CENTER>
  @@ -3899,7 +3995,7 @@
   
   	<td>
   	  <pre>  &lt;Perl&gt;
  -  print STDERR &quot;Server is Startingn\n&quot;  if $Apache::Server::Starting;
  +  print STDERR &quot;Server is Starting\n&quot;   if $Apache::Server::Starting;
     print STDERR &quot;Server is ReStarting\n&quot; if $Apache::Server::ReStarting;
     &lt;/Perl&gt;</pre>
           </td>
  @@ -4106,8 +4202,7 @@
         </tr>
       </table>
       <P>
  -If it didn't work as expected try building mod_perl with PERL_TRACE=1, then
  -do:
  +If it didn't work as expected try building mod_perl with <CODE>PERL_TRACE=1</CODE>, then do:
   
   <P>
   
  @@ -4180,7 +4275,7 @@
   <td align=center valign=center>
   
   <b><font size=-1>Written by <a
  -href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/07/2000
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 08/05/2000
   </font></b>
   <br>
   
  
  
  
  1.27      +509 -36   modperl-site/guide/control.html
  
  Index: control.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/control.html,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- control.html	2000/06/07 22:45:30	1.26
  +++ control.html	2000/08/05 20:48:04	1.27
  @@ -65,6 +65,7 @@
   
   	</UL>
   
  +	<LI><A HREF="#Swapping_Prevention">Swapping Prevention</A>
   	<LI><A HREF="#Preventing_mod_perl_Processes_Fr">Preventing mod_perl Processes From Going Wild</A>
   	<UL>
   
  @@ -274,7 +275,7 @@
   </DL>
   <P>
   By default, if a server is restarted (using <CODE>kill -USR1 `cat
  -logs/httpd.pid`</CODE> or with the <A HREF="#item_HUP">HUP</A> signal), Perl scripts and modules are not reloaded. To reload <CODE>PerlRequire</CODE>'s, <CODE>PerlModule</CODE>'s, other
  +logs/httpd.pid`</CODE> or with the <A HREF="#item_HUP">HUP</A> signal), Perl scripts and modules are not reloaded. To reload <CODE>PerlRequire</CODE>s, <CODE>PerlModule</CODE>s, other
   <CODE>use()</CODE>'d modules and flush the <CODE>Apache::Registry</CODE> cache, use this directive in <EM>httpd.conf</EM>:
   
   <P>
  @@ -302,8 +303,8 @@
   <P>
   We've already mentioned that restart or termination can sometimes take
   quite a long time, (e.g. tens of seconds), for a mod_perl server. The
  -reason for that is a call to the <CODE>perl_destruct()</CODE> Perl API
  -function during the child exit phase. This will cause proper execution of
  +reason for that is a call to the <CODE>perl_destruct()</CODE> Perl API function during the child exit phase. This will cause proper
  +execution of
   <CODE>END</CODE> blocks found during server startup and will invoke the
   <CODE>DESTROY</CODE> method on global objects which are still alive.
   
  @@ -349,7 +350,7 @@
   <CENTER><H1><A NAME="Using_apachectl_to_Control_the_S">Using apachectl to Control the Server</A></H1></CENTER>
   <P>
   The Apache distribution comes with a script to control the server. It's
  -called <EM>apachectl</EM> and it is installed into the same location as the httpd executable. We will
  +called <CODE>apachectl</CODE> and it is installed into the same location as the httpd executable. We will
   assume for the sake of our examples that it's in <CODE>/usr/local/sbin/httpd_perl/apachectl</CODE>:
   
   <P>
  @@ -1096,7 +1097,7 @@
   
   <P>
   By the way, don't let all this setuid stuff to confuse you -- when the
  -parent process is loaded, the childred processes are spawned as non-root
  +parent process is loaded, the children processes are spawned as non-root
   processes. This section has presented a way to allow non-root users to
   start the server as root user, the rest is exactly the same as if you were
   executing the script as root in first place.
  @@ -1226,9 +1227,9 @@
   	  <pre>  /etc/rc.d/init.d/httpd_docs
     /etc/rc.d/init.d/httpd_perl
     /etc/rc.d/rc3.d/S86httpd_docs -&gt; ../init.d/httpd_docs
  -  /etc/rc.d/rc3.d/S87httpd_perl -&gt; ../init.d/httpd_perl
  -  /etc/rc.d/rc6.d/K86httpd_docs -&gt; ../init.d/httpd_docs
  -  /etc/rc.d/rc6.d/K87httpd_perl -&gt; ../init.d/httpd_perl</pre>
  +  /etc/rc.d/rc3.d/S86httpd_perl -&gt; ../init.d/httpd_perl
  +  /etc/rc.d/rc6.d/K16httpd_docs -&gt; ../init.d/httpd_docs
  +  /etc/rc.d/rc6.d/K16httpd_perl -&gt; ../init.d/httpd_perl</pre>
           </td>
   	    
         </tr>
  @@ -1240,11 +1241,28 @@
   numbers are executed earlier.
   
   <P>
  -Under RedHat Linux, when a machine is booted and its runlevel set to 3
  -(multiuser+network), Linux goes into <CODE>/etc/rc.d/rc3.d/</CODE> and executes the scripts the symbolic links point to with the <CODE>start</CODE> argument. When it sees <EM>S87httpd_perl</EM>, it executes:
  +When the system starts (level 3) we want the Apache to be started when
  +almost all of the services are running already, therefore I've used
  +<EM>S86</EM>. For example if the mod_perl enabled Apache issues a
  +<CODE>connect_on_init()</CODE> the SQL server should be started before Apache.
   
   <P>
  +When the system shuts down (level 6), Apache should be stopped as one of
  +the first processes, therefore I've used <CODE>K16</CODE>. Again if the server does some cleanup processing during the shutdown
  +event and requires third party services to be running (e.g. SQL server) it
  +should be stopped before these services.
   
  +<P>
  +Notice that it's normal for more than one symbolic link to have the same
  +sequence number.
  +
  +<P>
  +Under RedHat Linux and similar systems, when a machine is booted and its
  +runlevel set to 3 (multiuser + network), Linux goes into
  +<EM>/etc/rc.d/rc3.d/</EM> and executes the scripts the symbolic links point to with the <CODE>start</CODE> argument. When it sees <EM>S86httpd_perl</EM>, it executes:
  +
  +<P>
  +
       <table>
         <tr>
   
  @@ -1280,11 +1298,275 @@
       <P>
   Most systems have GUI utilites to automate the creation of symbolic links.
   For example RedHat Linux includes the <CODE>control-panel</CODE>
  -utility, which amongst other things includes the <CODE>RunLevel Manager</CODE>. This will help you to create the proper symbolic links. Of course before
  -you use it, you should put <CODE>apachectl</CODE> or similar scripts into the <EM>init.d</EM> or equivalent directory. Or you can have a symbolic link to some other
  +utility, which amongst other things includes the <CODE>RunLevel Manager</CODE>. (which can be invoked directly as either <CODE>ntsysv(8)</CODE> or
  +<CODE>tksysv(8)).</CODE> This will help you to create the proper symbolic
  +links. Of course before you use it, you should put <CODE>apachectl</CODE> or similar scripts into the <EM>init.d</EM> or equivalent directory. Or you can have a symbolic link to some other
   location instead.
   
   <P>
  +The simplest approach is to use the <CODE>chkconfig(8)</CODE> utility which
  +adds and removes the services for you. The following example shows how to
  +add an <EM>httpd_perl</EM> startup script to the system.
  +
  +<P>
  +First move or copy the file into the directory <EM>/etc/rc.d/init.d</EM>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % mv httpd_perl /etc/rc.d/init.d</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Now open the script in your favorite editor and add the following lines
  +after the main header of the script:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # Comments to support chkconfig on RedHat Linux
  +  # chkconfig: 2345 86 16
  +  # description: mod_perl enabled Apache Server</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +So now the beginning of the script looks like:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  #!/bin/sh
  +  #
  +  # Apache control script designed to allow an easy command line
  +  # interface to controlling Apache.  Written by Marc Slemko,
  +  # 1997/08/23
  +  
  +  # Comments to support chkconfig on RedHat Linux
  +  # chkconfig: 2345 86 16
  +  # description: mod_perl enabled Apache Server
  +  
  +  #
  +  # The exit codes returned are:
  +  # ...</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Adjust the line:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # chkconfig: 2345 86 16</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +to your needs. The above setting says to says that the script should be
  +started in levels 2, 3, 4, and 5, that its start priority should be 86, and
  +that its stop priority should be 16.
  +
  +<P>
  +Now all you have to do is to ask <CODE>chkconfig</CODE> to configure the startup scripts. Before we do that let's look at what we
  +have:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % find /etc/rc.d | grep httpd_perl
  +  
  +  /etc/rc.d/init.d/httpd_perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Which means that we only have the startup script itself. Now we execute:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % chkconfig --add httpd_perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +and see what has changed:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % find /etc/rc.d | grep httpd_perl
  +  
  +  /etc/rc.d/init.d/httpd_perl
  +  /etc/rc.d/rc0.d/K16httpd_perl
  +  /etc/rc.d/rc1.d/K16httpd_perl
  +  /etc/rc.d/rc2.d/S86httpd_perl
  +  /etc/rc.d/rc3.d/S86httpd_perl
  +  /etc/rc.d/rc4.d/S86httpd_perl
  +  /etc/rc.d/rc5.d/S86httpd_perl
  +  /etc/rc.d/rc6.d/K16httpd_perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +As you can see <CODE>chkconfig</CODE> created all the symbolic links for us, using the startup and shutdown
  +priorities as specified in the line:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  # chkconfig: 2345 86 16</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +If for some reason you want to remove the service from the startup scripts,
  +all you have to do is to tell <CODE>chkconfig</CODE> to remove the links:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % chkconfig --del httpd_perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Now if we look at the files under the directory <EM>/etc/rc.d/</EM> we see again only the script itself.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % find /etc/rc.d | grep httpd_perl
  +  
  +  /etc/rc.d/init.d/httpd_perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Of course you may keep the startup script in any other directory as long as
  +you can link to it. For example if you want to keep this file with all the
  +Apache binaries in <EM>/usr/local/apache/bin</EM>, all you have to do is to provide a symbolic link to this file:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ln -s /usr/local/apache/bin/apachectl /etc/rc.d/init.d/httpd_perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +and then:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  %  chkconfig --add httpd_perl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Note that in case of using symlinks the link name in
  +<EM>/etc/rc.d/init.d</EM> is what matters and not the name of the script the link points to.
  +
  +<P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
   <CENTER><H1><A NAME="Monitoring_the_Server_A_watchdo">Monitoring the Server.  A watchdog.</A></H1></CENTER>
  @@ -1363,10 +1645,11 @@
       echo &quot;$0 $ARG: httpd not running, trying to start&quot;
       if $HTTPD ; then
         echo &quot;$0 $ARG: httpd started&quot;
  -      mail $EMAIL -s &quot;$0 $ARG: httpd started&quot; &lt;/dev/null &gt;&amp; /dev/null
  +      mail $EMAIL -s &quot;$0 $ARG: httpd started&quot; &gt; /dev/null 2&gt;&amp;1
       else
         echo &quot;$0 $ARG: httpd could not be started&quot;
  -      mail $EMAIL -s &quot;$0 $ARG: httpd could not be started&quot; &lt;/dev/null &gt;&amp; /dev/null
  +      mail $EMAIL -s \
  +      &quot;$0 $ARG: httpd could not be started&quot; &gt; /dev/null 2&gt;&amp;1
       fi
     fi</pre>
           </td>
  @@ -1375,7 +1658,7 @@
       </table>
       <P>
   Another approach, probably even more practical, is to use the cool
  -<CODE>LWP</CODE> perl package to test the server by trying to fetch some document (script)
  +<CODE>LWP</CODE> Perl package to test the server by trying to fetch some document (script)
   served by the server. Why is it more practical? Because while the server
   can be up as a process, it can be stuck and not working. Failing to get the
   document will trigger restart, and ``probably'' the problem will go away. 
  @@ -1386,7 +1669,7 @@
   minute. Why so often? If your server starts to spin and trash your disk
   space with multiple error messages filling the <EM>error_log</EM>, in five minutes you might run out of free disk space which might bring
   your system to its knees. Chances are that no other child will be able to
  -serve requests, since the system will be too busy writing to the <EM>error_log</EM> file. Think big -- if you are running a heavy service (which is very fast
  +serve requests, since the system will be too busy writing to the <EM>error_log</EM> file. Think big--if you are running a heavy service (which is very fast
   since you are running under mod_perl) adding one more request every minute
   will not be felt by the server at all.
   
  @@ -1557,7 +1840,7 @@
   In addition you should know that when running with <CODE>-X</CODE> you will not see the control messages that the parent server normally
   writes to the
   <EM>error_log</EM> (<EM>"server started"</EM>, <EM>"server stopped"</EM> etc). Since
  -httpd&nbsp;-X causes the server to handle all requests itself, without forking any
  +<CODE>httpd -X</CODE> causes the server to handle all requests itself, without forking any
   children, there is no controlling parent to write the status messages.
   
   <P>
  @@ -1570,7 +1853,7 @@
   often you will have a group of developers who need to develop mod_perl
   scripts and modules concurrently. This means that each developer will want
   to have control over the server - to kill it, to run it in single server
  -mode, to restart it etc., as well as having control over the location of
  +mode, to restart it, etc., as well as having control over the location of
   the log files, configuration settings like <CODE>MaxClients</CODE>, and so on.
   
   <P>
  @@ -1666,7 +1949,7 @@
   <P>
   In the above technique, you need to discover the PID of your parent
   <CODE>httpd_perl</CODE> process, which is written in
  -<CODE>/usr/local/var/httpd_perl/run/httpd.pid.stas</CODE> (and the same for the user eric). To make things even easier we change the <EM>apachectl</EM>
  +<CODE>/usr/local/var/httpd_perl/run/httpd.pid.stas</CODE> (and the same for the user <EM>eric</EM>). To make things even easier we change the <EM>apachectl</EM>
   script to do the work for us. We make a copy for each developer called <STRONG>apachectl.username</STRONG> and we change two lines in each script:
   
   <P>
  @@ -1687,7 +1970,7 @@
       </table>
       <P>
   So for the user <EM>stas</EM> we prepare a startup script called
  -<STRONG>apachectl.stas</STRONG> and we change these two lines in the standard apachectl script as it comes
  +<EM>apachectl.stas</EM> and we change these two lines in the standard apachectl script as it comes
   unmodified from Apache distribution.
   
   <P>
  @@ -1815,14 +2098,11 @@
       <P>
   The IP addresses are the addresses of the developer desktop machines (where
   they are running their web browsers). So if an html file includes a a
  -relative URI <EM>/perl/test.pl</EM> or even <A
  -HREF="http://www.example.com/perl/test.pl">http://www.example.com/perl/test.pl</A>,
  -clicking on the link will be internally proxied to <A
  +relative URI <EM>/perl/test.pl</EM> or even
  +<EM>http://www.example.com/perl/test.pl</EM>, clicking on the link will be internally proxied to <A
   HREF="http://www.example.com:8000/perl/test.pl">http://www.example.com:8000/perl/test.pl</A>
  -if the click has been made at the user stas's desktop machine, or to <A
  -HREF="http://www.example.com:8001/perl/test.pl">http://www.example.com:8001/perl/test.pl</A>
  -for a request generated from the user eric's machine, per our above URI
  -rewrite example.
  +if the click has been made at the user <EM>stas</EM>'s desktop machine, or to
  +<EM>http://www.example.com:8001/perl/test.pl</EM> for a request generated from the user <EM>eric</EM>'s machine, per our above URI rewrite example.
   
   <P>
   Another possibility is to use <CODE>REMOTE_USER</CODE> variable if all the developers are forced to authenticate themselves before
  @@ -1833,8 +2113,7 @@
   We wish to stress again, that the above setup will work only with relative
   URIs in the HTML code. If you choose to generate full URIs including non-80
   port the requests originated from this HTML code will bypass the light
  -server listenting to the default port 80, and go directly to the
  -server:port of the full URI.
  +server listenting to the default port 80, and go directly to the <EM>server:port</EM> of the full URI.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  @@ -1874,8 +2153,7 @@
   The best debugging approach is to write a wrapper that emulates the exact
   environment of the server, first deleting environment variables like <CODE>PERL5LIB</CODE> and then calling the same perl binary that it is being used by the server.
   Next, set the environment identical to the server's by copying the Perl run
  -directives from the server startup and configuration files or even
  -<CODE>require()'ing</CODE> the startup file, if it doesn't include <A HREF="#item_Apache_">Apache::</A> modules stuff, unavailable under shell. This will also allow you to remove
  +directives from the server startup and configuration files or even <EM>require()</EM>'ing the startup file, if it doesn't include <A HREF="#item_Apache_">Apache::</A> modules stuff, unavailable under shell. This will also allow you to remove
   completely the first line of the script, since mod_perl doesn't need it
   anyway and the wrapper knows how to call the script.
   
  @@ -2049,7 +2327,8 @@
     my $gzip_exec = &quot;/usr/bin/gzip&quot;;
     
     my ($sec,$min,$hour,$mday,$mon,$year) = localtime(time);
  -  my $time = sprintf &quot;%0.4d.%0.2d.%0.2d-%0.2d.%0.2d.%0.2d&quot;, $year+1900,++$mon,$mday,$hour,$min,$sec;
  +  my $time = sprintf &quot;%0.4d.%0.2d.%0.2d-%0.2d.%0.2d.%0.2d&quot;,
  +       $year+1900,++$mon,$mday,$hour,$min,$sec;
     $^I = &quot;.$time&quot;;
     
     # rename log files
  @@ -2239,7 +2518,7 @@
   the crontab, to handle the situations like this. The cron job should run
   every few minutes or even every minute, since if you experience this
   problem you know that log files fills up very fast. The example script will
  -rotate when the <EM>error_log</EM> will grow over 100K. Note that this script is usefull when you have the
  +rotate when the <EM>error_log</EM> will grow over 100K. Note that this script is useful when you have the
   normal scheduled log rotation facility working, remember that this one is
   an emergency solver and not to be used for routine log rotation.
   
  @@ -2291,6 +2570,200 @@
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +<CENTER><H1><A NAME="Swapping_Prevention">Swapping Prevention</A></H1></CENTER>
  +<P>
  +Before I delve into swapping process details, let's refresh our knowledge
  +of memory components and memory management
  +
  +<P>
  +The computer memory is called RAM, which stands for Random Access Memory.
  +Reading and writing to RAM is, by a few orders, faster than doing the same
  +operations on a hard disk, the former uses non-movable memory cells, while
  +the latter uses rotating magnetic media.
  +
  +<P>
  +On most operating systems swap memory is used as an extension for RAM and
  +not as a duplication of it. So if your OS is one of those, if you have
  +128MB of RAM and 256MB swap partition, you have a total of 384MB of memory
  +available. You should never count the extra memory when you decide on the
  +maximum number of processes to be run, and I will show why in the moment.
  +
  +<P>
  +The swapping memory can be built of a number of hard disk partitions and
  +swap files formatted to be used as swap memory. When you need more swap
  +memory you can always extend it on demand as long as you have some free
  +disk space (for more information see the <EM>mkswap</EM> and
  +<EM>swapon</EM> manpages).
  +
  +<P>
  +System memory is quantified in units called memory pages. Usually the size
  +of a memory page is between 1KB and 8KB. So if you have 256MB of RAM
  +installed on your machine and the page size is 4KB your system has 64,000
  +main memory pages to work with and these pages are fast. If you have 256MB
  +swap partition the system can use yet another 64,000 memory pages, but they
  +are much slower.
  +
  +<P>
  +When the system is started all memory pages are available for use by the
  +programs (processes).
  +
  +<P>
  +Unless the program is really small, the process running this program uses
  +only a few segments of the program, each segment mapped onto its own memory
  +page. Therefore only a few memory pages are required to be loaded into the
  +memory.
  +
  +<P>
  +When the process needs an additional program's segment to be loaded into
  +the memory, it asks the system whether the page containing this segment is
  +already loaded in the memory. If the page is not found--an event know as a <EM>page fault</EM> occurs, which requires the system to allocate a free memory page, go to the
  +disk, read and load the requested program's segment into the allocated
  +memory page.
  +
  +<P>
  +If a process needs to bring a new page into physical memory and there are
  +no free physical pages available, the operating system must make room for
  +this page by discarding another page from physical memory.
  +
  +<P>
  +If the page to be discarded from physical memory came from an image or data
  +file and has not been written to then the page does not need to be saved.
  +Instead it can be discarded and if the process needs that page again it can
  +be brought back into memory from the image or data file.
  +
  +<P>
  +However, if the page has been modified, the operating system must preserve
  +the contents of that page so that it can be accessed at a later time. This
  +type of page is known as a <EM>dirty page</EM> and when it is removed from memory it is saved in a special sort of file
  +called the swap file. This process is referred to as a <EM>swapping out</EM>.
  +
  +<P>
  +Accesses to the swap file are very long relative to the speed of the
  +processor and physical memory and the operating system must juggle the need
  +to write pages to disk with the need to retain them in memory to be used
  +again.
  +
  +<P>
  +In order to improve the swapping out process, to decrease the possibility
  +that the page that has just been swapped out, will be needed at the next
  +moment, the LRU (least recently used) or a similar algorithm is used.
  +
  +<P>
  +To summarize the two swapping scenarios, read-only pages discarding incurs
  +no overhead in contrast with the discarding scenario of the data pages that
  +have been written to, since in the latter case the pages have to be written
  +to a swap partition located on the slow disk. Therefore your machine's
  +overall performance will be much better if there will be less memory pages
  +that can become dirty.
  +
  +<P>
  +But the problem is, Perl is a language with no strong data types, which
  +means that both the program code and the program data are seen as a data
  +pages by OS since both mapped to the same memory pages. Therefore a big
  +chunk of your Perl code becomes dirty when its variables are modified and
  +when the pages need to be discarded they have to be written to the swap
  +partition.
  +
  +<P>
  +This leads us to two important conclusions about swapping and Perl.
  +
  +<UL>
  +<P><LI>
  +<P>
  +Running your system when there is no free main memory available hinders
  +performance, because processes memory pages should be discarded and then
  +reread from disk again and again.
  +
  +<P><LI>
  +<P>
  +Since a majority of the running code is a Perl code, in addition to the
  +overhead of reading the previously discarded pages in, the overhead of
  +saving the dirty pages to the swap partition is occurring.
  +
  +</UL>
  +<P>
  +When the system has to swap memory pages in and out, the system slows down,
  +not serving the processes as fast as before. This leads to an accumulation
  +of processes waiting for their turn to run, which further causes processing
  +demands to go up, which in turn slows down the system even more as more
  +memory is required. This ever worsening spiral will lead the machine to
  +halt, unless the resource demand suddenly drops down and allows the
  +processes to catch up with their tasks and go back to normal memory usage.
  +
  +<P>
  +In addition it's important to know that for a better performance, most
  +programs, particularly programs written in Perl, on most modern OSs don't
  +return memory pages while they are running. If some of the memory gets
  +freed it's reused when needed by the process, without creating the
  +additional overhead of asking the system to allocate new memory pages.
  +That's why you will observe that Perl programs grow in size as they run and
  +almost never shrink.
  +
  +<P>
  +When the process quits it returns its memory pages to the pool of freely
  +available pages for other processes to use.
  +
  +<P>
  +This scenario is certainly educating, and it should be now obvious that
  +your system that runs the web server should never swap. It's absolutely
  +normal for your desktop to start swapping. You will see it immediately
  +since things will slow down and sometimes the system will freeze for a
  +short periods. But as I've just mentioned, you can stop starting new
  +programs and can quit some, thus allowing the system to catch up with the
  +load and come back to use the RAM.
  +
  +<P>
  +In the case of the web server you have much less control since it's users
  +who load your machine by issuing requests to your server. Therefore you
  +should configure the server, so that the maximum number of possible
  +processes will be small enough using the <CODE>MaxClients</CODE>
  +directive (For the technique for choosing the right <CODE>MaxClients</CODE>
  +refer to the section '<A HREF="././performance.html#Choosing_MaxClients">Choosing MaxClients</A>'). This will ensure that at peak hours the system won't swap. Remember
  +that swap space is an emergency pool, not a resource to be used routinely.
  +If you are low on memory and you badly need it, buy it or reduce the number
  +of processes to prevent swapping.
  +
  +<P>
  +However sometimes, due to the faulty code, some process might start
  +spinning in an unconstrained loop, consuming all the available RAM and
  +starting to heavily use swap memory. In such a situation it helps when you
  +have a big emergency pool (i.e. lots of swap memory). But you have to
  +resolve this problem as soon as possible since this pool won't last for a
  +long time. In the meanwhile the <CODE>Apache::Resource</CODE> module can be handy.
  +
  +<P>
  +Sometimes calling an undefined subroutine in a module can cause a tight
  +loop that consumes all the available memory. Here is a way to catch such
  +errors. Define an <CODE>AUTOLOAD</CODE> subroutine:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  sub UNIVERSAL::AUTOLOAD {
  +    my $class = shift;
  +    warn &quot;$class can't \$UNIVERSAL::AUTOLOAD!\n&quot;;
  +  }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +This will produce a nice error in <EM>error_log</EM>, giving the line number of the call and the name of the undefined
  +subroutine.
  +
  +<P>
  +For swapping monitoring techniques see the section '<A HREF="././debug.html#Apache_VMonitor_Visual_Syste">Apache::VMonitor -- Visual System and Apache Server Monitor</A>'.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Preventing_mod_perl_Processes_Fr">Preventing mod_perl Processes From Going Wild</A></H1></CENTER>
   <P>
   Sometimes people report that they had a problem with their code running
  @@ -2326,8 +2799,8 @@
         </tr>
       </table>
       <P>
  -This will produce a nice error in error_log, giving the line number of the
  -call and the name of the undefined subroutine.
  +This will produce a nice error in <EM>error_log</EM>, giving the line number of the call and the name of the undefined
  +subroutine.
   
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  @@ -2382,7 +2855,7 @@
   <td align=center valign=center>
   
   <b><font size=-1>Written by <a
  -href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 08/03/2000
   </font></b>
   <br>
   
  
  
  
  1.10      +21 -54    modperl-site/guide/correct_headers.html
  
  Index: correct_headers.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/correct_headers.html,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- correct_headers.html	2000/06/07 22:45:30	1.9
  +++ correct_headers.html	2000/08/05 20:48:04	1.10
  @@ -1,7 +1,7 @@
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
   <html>
     <head>
  -   <title>mod_perl guide: Correct Headers - A quick guide for mod_perl users</title>
  +   <title>mod_perl guide: Issuing Correct HTTP Headers</title>
      <meta name="Author" content="Stas Bekman">
      <meta name="Description" content="All Apache/Perl related information: Hints, Guidelines, Scenarios and Troubleshottings">
      <meta name="keywords" content="mod_perl modperl perl cgi apache webserver speed fast guide mod_perl apache guide help info faq mod_perl installation cgi troubleshooting help no sex speedup free open source OSS mod_perl apache guide">
  @@ -14,7 +14,7 @@
       <h1 align=center>
         <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=left></a>
         <a href="http://perl.apache.org"><img src="images/mod_perl.gif" alt="Mod Perl Icon" border=0 height=30 width=90 align=right></a>
  -      Correct Headers - A quick guide for mod_perl users
  +      Issuing Correct HTTP Headers
       </h1>
       <hr>
       <p>
  @@ -34,19 +34,18 @@
   
   <UL>
   
  -	<LI><A HREF="#Correct_Headers_A_quick_guide_">Correct Headers - A quick guide for mod_perl users</A>
   	<LI><A HREF="#SYNOPSIS">SYNOPSIS</A>
  -	<LI><A HREF="#The_origin_of_this_chapter">The origin of this chapter</A>
  +	<LI><A HREF="#The_Origin_of_this_Chapter">The Origin of this Chapter</A>
   	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
  -	<LI><A HREF="#1_Why_headers">1) Why headers</A>
  +	<LI><A HREF="#1_Why_Headers">1) Why Headers</A>
   	<LI><A HREF="#2_Which_Headers">2) Which Headers</A>
   	<UL>
   
  -		<LI><A HREF="#2_1_Date_related_headers">2.1) Date related headers</A>
  +		<LI><A HREF="#2_1_Date_Related_Headers">2.1) Date Related Headers</A>
   		<LI><A HREF="#2_1_1_Date">2.1.1) Date</A>
   		<LI><A HREF="#2_1_2_Last_Modified">2.1.2) Last-Modified</A>
   		<LI><A HREF="#2_1_3_Expires_and_Cache_Control">2.1.3) Expires and Cache-Control</A>
  -		<LI><A HREF="#2_2_Content_related_headers">2.2) Content related headers</A>
  +		<LI><A HREF="#2_2_Content_Related_Headers">2.2) Content Related Headers</A>
   		<LI><A HREF="#2_2_1_Content_Type">2.2.1) Content-Type</A>
   		<LI><A HREF="#2_2_2_Content_Length">2.2.2) Content-Length</A>
   		<LI><A HREF="#2_2_3_Entity_Tags">2.2.3) Entity Tags</A>
  @@ -61,10 +60,10 @@
   		<LI><A HREF="#3_2_POST">3.2) POST</A>
   		<LI><A HREF="#3_3_GET">3.3) GET</A>
   		<LI><A HREF="#3_4_Conditional_GET">3.4) Conditional GET</A>
  -		<LI><A HREF="#3_Avoiding_dealing_with_them">3.) Avoiding dealing with them</A>
   	</UL>
   
  -	<LI><A HREF="#References_and_other_literature">References and other literature</A>
  +	<LI><A HREF="#4_Avoiding_Dealing_with_Header">4.) Avoiding Dealing with Headers</A>
  +	<LI><A HREF="#References">References</A>
   	<UL>
   
   		<LI><A HREF="#_1_">[1]</A>
  @@ -74,8 +73,6 @@
   		<LI><A HREF="#_5_">[5]</A>
   	</UL>
   
  -	<LI><A HREF="#VERSION">VERSION</A>
  -	<LI><A HREF="#AUTHOR">AUTHOR</A>
   </UL>
   
       </div>
  @@ -118,10 +115,6 @@
   <HR>
   
   <P>
  -<CENTER><H1><A NAME="Correct_Headers_A_quick_guide_">Correct Headers - A quick guide for mod_perl users</A></H1></CENTER>
  -<P>
  -[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  -<HR>
   <CENTER><H1><A NAME="SYNOPSIS">SYNOPSIS</A></H1></CENTER>
   <P>
   As there is always more than one way to do it, I'm tempted to believe one
  @@ -130,7 +123,7 @@
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  -<CENTER><H1><A NAME="The_origin_of_this_chapter">The origin of this chapter</A></H1></CENTER>
  +<CENTER><H1><A NAME="The_Origin_of_this_Chapter">The Origin of this Chapter</A></H1></CENTER>
   <P>
   This chapter has been contributed to the Guide by Andreas Koenig. You will
   find the references and other related info at the bottom of this page. I'll
  @@ -150,7 +143,7 @@
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  -<CENTER><H1><A NAME="1_Why_headers">1) Why headers</A></H1></CENTER>
  +<CENTER><H1><A NAME="1_Why_Headers">1) Why Headers</A></H1></CENTER>
   <P>
   Dynamic Content is dynamic, after all, so why would anybody care about HTTP
   headers? Header composition is a task often neglected in the CGI world.
  @@ -189,7 +182,7 @@
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  -<CENTER><H2><A NAME="2_1_Date_related_headers">2.1) Date related headers</A></H2></CENTER>
  +<CENTER><H2><A NAME="2_1_Date_Related_Headers">2.1) Date Related Headers</A></H2></CENTER>
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  @@ -298,7 +291,7 @@
     use Date::Parse;
     # Date::Parse parses RCS format, Apache::Util::parsedate doesn't
     $Mtime ||=
  -    Date::Parse::str2time(substr q$Date: 2000/06/07 22:45:30 $, 6);
  +    Date::Parse::str2time(substr q$Date: 2000/08/05 20:48:04 $, 6);
     $r-&gt;set_last_modified($Mtime);</pre>
           </td>
   	    
  @@ -473,7 +466,7 @@
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  -<CENTER><H2><A NAME="2_2_Content_related_headers">2.2) Content related headers</A></H2></CENTER>
  +<CENTER><H2><A NAME="2_2_Content_Related_Headers">2.2) Content Related Headers</A></H2></CENTER>
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  @@ -1003,7 +996,7 @@
           </td>
   
   	<td>
  -	  <pre>  <A HREF="http://foo.com/query?BGCOLOR=blue;FGCOLOR=red">http://foo.com/query?BGCOLOR=blue;FGCOLOR=red</A></pre>
  +	  <pre>  <A HREF="http://example.com/query?BGCOLOR=blue;FGCOLOR=red">http://example.com/query?BGCOLOR=blue;FGCOLOR=red</A></pre>
           </td>
   	    
         </tr>
  @@ -1021,7 +1014,7 @@
           </td>
   
   	<td>
  -	  <pre>  <A HREF="http://foo.com/query;BGCOLOR=blue;FGCOLOR=red">http://foo.com/query;BGCOLOR=blue;FGCOLOR=red</A></pre>
  +	  <pre>  <A HREF="http://example.com/query;BGCOLOR=blue;FGCOLOR=red">http://example.com/query;BGCOLOR=blue;FGCOLOR=red</A></pre>
           </td>
   	    
         </tr>
  @@ -1042,7 +1035,7 @@
           </td>
   
   	<td>
  -	  <pre>  <A HREF="http://foo.com/query;BGCOLOR=blue;FGCOLOR=red;FONT=%2Ffont%2Fbla">http://foo.com/query;BGCOLOR=blue;FGCOLOR=red;FONT=%2Ffont%2Fbla</A></pre>
  +	  <pre>  <A HREF="http://example.com/query;BGCOLOR=blue;FGCOLOR=red;FONT=%2Ffont%2Fbla">http://example.com/query;BGCOLOR=blue;FGCOLOR=red;FONT=%2Ffont%2Fbla</A></pre>
           </td>
   	    
         </tr>
  @@ -1060,7 +1053,7 @@
           </td>
   
   	<td>
  -	  <pre>  <A HREF="http://foo.com/query;BGCOLOR=blue;FGCOLOR=red;FONT=/font/bla">http://foo.com/query;BGCOLOR=blue;FGCOLOR=red;FONT=/font/bla</A></pre>
  +	  <pre>  <A HREF="http://example.com/query;BGCOLOR=blue;FGCOLOR=red;FONT=/font/bla">http://example.com/query;BGCOLOR=blue;FGCOLOR=red;FONT=/font/bla</A></pre>
           </td>
   	    
         </tr>
  @@ -1134,7 +1127,7 @@
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  -<CENTER><H2><A NAME="3_Avoiding_dealing_with_them">3.) Avoiding dealing with them</A></H2></CENTER>
  +<CENTER><H1><A NAME="4_Avoiding_Dealing_with_Header">4.) Avoiding Dealing with Headers</A></H1></CENTER>
   <P>
   There is another approach to dynamic content that is possible with
   mod_perl. This approach is appropriate if the content changes relatively
  @@ -1165,13 +1158,13 @@
       <P>
   even if this seems redundant because the filename is already equal to
   <CODE>$file</CODE>. Setting the filename has the side effect of doing a
  -<A HREF="#item_stat">stat()</A> on the file. This is important because otherwise Apache would use the out
  +<CODE>stat()</CODE> on the file. This is important because otherwise Apache would use the out
   of date <CODE>finfo</CODE> when generating the response header.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  -<CENTER><H1><A NAME="References_and_other_literature">References and other literature</A></H1></CENTER>
  +<CENTER><H1><A NAME="References">References</A></H1></CENTER>
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  @@ -1216,32 +1209,6 @@
   HREF="http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu/">http://www.amazon.com/exec/obidos/ASIN/156592567X/writinapachemodu/</A>
   
   
  -<P>
  -[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  -<HR>
  -<CENTER><H1><A NAME="VERSION">VERSION</A></H1></CENTER>
  -<P>
  -You're reading revision $Revision: 1.9 $ of this document, written on
  -$Date: 2000/06/07 22:45:30 $
  -
  -<P>
  -[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  -<HR>
  -<CENTER><H1><A NAME="AUTHOR">AUTHOR</A></H1></CENTER>
  -<P>
  -Andreas Koenig with helpful corrections, addition, comments from Ask Bjoern
  -Hansen &lt;<A HREF="mailto:ask@netcetera.dk">ask@netcetera.dk</A>&gt;,
  -Frank D. Cringle &lt;<A
  -HREF="mailto:fdc@cliwe.ping.de">fdc@cliwe.ping.de</A>&gt;, Eric Cholet
  -&lt;<A HREF="mailto:cholet@logilune.com">cholet@logilune.com</A>&gt;, Mark
  -Kennedy &lt;<A
  -HREF="mailto:mark.kennedy@gs.com">mark.kennedy@gs.com</A>&gt;, Doug
  -MacEachern &lt;<A HREF="mailto:dougm@pobox.com">dougm@pobox.com</A>&gt;,
  -Tom Hukins &lt;<A HREF="mailto:tom@eborcom.com">tom@eborcom.com</A>&gt;,
  -Wham Bang &lt;<A
  -HREF="mailto:wham_bang@yahoo.com">wham_bang@yahoo.com</A>&gt; and many
  -others.
  -
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
   
  @@ -1295,7 +1262,7 @@
   <td align=center valign=center>
   
   <b><font size=-1>Written by <a
  -href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/28/2000
   </font></b>
   <br>
   
  
  
  
  1.16      +1 -1      modperl-site/guide/databases.html
  
  Index: databases.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/databases.html,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- databases.html	2000/06/07 22:45:30	1.15
  +++ databases.html	2000/08/05 20:48:04	1.16
  @@ -985,7 +985,7 @@
   <td align=center valign=center>
   
   <b><font size=-1>Written by <a
  -href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/04/2000
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
   </font></b>
   <br>
   
  
  
  
  1.25      +269 -765  modperl-site/guide/debug.html
  
  Index: debug.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/debug.html,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- debug.html	2000/06/07 22:45:30	1.24
  +++ debug.html	2000/08/05 20:48:05	1.25
  @@ -71,8 +71,7 @@
   		<UL>
   
   			<LI><A HREF="#Critical_Section">Critical Section</A>
  -			<LI><A HREF="#Safe_Resource_Locking">Safe Resource Locking</A>
  -			<LI><A HREF="#Cleanup_Code">Cleanup Code</A>
  +			<LI><A HREF="#Safe_Resource_Locking_and_Cleanu">Safe Resource Locking and Cleanup Code</A>
   		</UL>
   
   	</UL>
  @@ -125,7 +124,7 @@
   	<LI><A HREF="#Debugging_Signal_Handlers_SIG_">Debugging Signal Handlers ($SIG{FOO})</A>
   	<LI><A HREF="#Code_Profiling">Code Profiling</A>
   	<LI><A HREF="#Devel_Peek">Devel::Peek</A>
  -	<LI><A HREF="#How_can_I_find_out_if_a_mod_perl">How can I find out if a mod_perl script has a memory leak</A>
  +	<LI><A HREF="#How_can_I_find_out_if_a_mod_perl">How can I find out if a mod_perl code has a memory leak</A>
   	<LI><A HREF="#Debugging_your_code_in_Single_Se">Debugging your code in Single Server Mode</A>
   	<LI><A HREF="#Apache_DumpHeaders_Watch_HTTP">Apache::DumpHeaders - Watch HTTP Transaction Via Headers</A>
   	<LI><A HREF="#Apache_DebugInfo_Log_Various_">Apache::DebugInfo - Log Various Bits Of Per-Request Data</A>
  @@ -1834,32 +1833,41 @@
   the <CODE>while(1)</CODE> loop isn't aborted by Apache. The next section covers this.
   
   <P>
  +META: add the note about using the 'curinfo' gdb macro to perform an easy
  +detecting of the hanging location.
  +
  +<P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
   <CENTER><H1><A NAME="Handling_the_User_pressed_Stop_">Handling the 'User pressed Stop button' case</A></H1></CENTER>
  +<P>
  +When a user presses a <STRONG>STOP</STRONG> or <STRONG>RELOAD</STRONG> button, the current socket connection goes broken (aborted). It would be
  +nice if Apache could always immediately detect this event. Unfortunately
  +there is no way to tell whether the connection is still valid unless an
  +attempt to read from or write to connection is made.
  +
   <P>
  -When a user presses a <STRONG>STOP</STRONG> or <STRONG>RELOAD</STRONG> button, Apache could detect this via the <CODE>SIGPIPE</CODE> signal (Broken pipe). It could then halt the script execution and perform
  -all the cleanup stuff it has to do. But the <CODE>SIGPIPE</CODE> will be triggered only when the process attempts to send some data to the
  -client browser via the broken connection. If the script is doing some
  -lengthy operation, without writing anything to the client, it won't be
  -stopped until that operation is completed and an attempt is made to send at
  -least one character the client.
  +If the reading of the request's data is completed and the code does
  +processing without writing anything back to the client the broken
  +connection won't be noticed. When an attempt is made to send at least one
  +character to the client, the broken connection would be noticed and the <CODE>SIGPIPE</CODE> signal (Broken pipe) would be sent to the process. The program could then
  +halt its execution and perform all the cleanup stuff it has to do.
   
   <P>
  -Apache &gt;= 1.3.6 does not catch SIGPIPE anymore, and modperl can do the
  +Apache &gt;= 1.3.6 does not catch SIGPIPE anymore, and mod_perl can do the
   job much better.
   
   <P>
  -Since Apache version 1.3.6:
  +Prior to Apache version 1.3.6, <CODE>SIGPIPE</CODE> was handled by Apache. Currently Apache is not handling SIGPIPE anymore and
  +mod_perl takes care of it. 
   
  -<UL>
  -<P><LI>
   <P>
  -<CODE>$r-&gt;print</CODE> returns <EM>true</EM> on success, <EM>false</EM> on failure (broken connection).
  +Under mod_perl <CODE>$r-&gt;print</CODE> (or just <CODE>print())</CODE> returns a <EM>true</EM>
  +value on success, a <EM>false</EM> value on failure. The latter usually happens when the connection is broken.
   
  -<P><LI>
   <P>
  -If you want a similar to the old <CODE>SIGPIPE</CODE> behaviour, simply configure:
  +If you want a similar to the old <CODE>SIGPIPE</CODE> behaviour (as it was before Apache version 1.3.6), add the following
  +configuration directive:
   
   <P>
   
  @@ -1882,17 +1890,19 @@
   child. When <CODE>Apache::SIG</CODE> is used, it installs a different <CODE>SIGPIPE</CODE> handler which rewinds the context to make sure Perl is back to normal
   state, preventing these bizarre errors.
   
  -</UL>
  +<P>
  +But in general case, you don't need to use the above setting.
  +
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
   <CENTER><H2><A NAME="Detecting_Aborted_Connections">Detecting Aborted Connections</A></H2></CENTER>
   <P>
   Let's use the knowledge we have acquired to trace the execution of the code
  -and see all the events as they happen.
  +and watch all the events as they happen. 
   
   <P>
  -Let's take a little script that obviously ``hangs'' the server:
  +Let's take a little script that obviously <EM>"hangs"</EM> the server process:
   
   <P>
   
  @@ -1904,7 +1914,9 @@
           </td>
   
   	<td>
  -	  <pre>  my $r = shift;
  +	  <pre>  stopping_detector.pl
  +  --------------------
  +  my $r = shift;
     $r-&gt;send_http_header('text/plain');
     
     print &quot;PID = $$\n&quot;;
  @@ -1921,20 +1933,20 @@
       <P>
   The script gets a request object <CODE>$r</CODE> by <CODE>shift()ing</CODE> it from the <CODE>@_</CODE>
   argument list passed by the <CODE>handler()</CODE> subroutine. (This magic
  -is done by <CODE>Apache::Registry</CODE>). Then the script sends a <EM>Content-type</EM>
  -header, telling the client that we are going to send some plain text.
  +is done by <CODE>Apache::Registry</CODE>). Then the script sends a <CODE>Content-type</CODE>
  +header, telling the client that we are going to send a plain text as a
  +response.
   
   <P>
  -We print out a single line telling us the id of the process that handles
  -this request, which we need to know in order to run the tracing utility.
  -Then we flush Apache's buffer. (If we don't flush the buffer we will never
  -see the line printed. That's because our output is shorter than the buffer
  -size and the script intentionally hangs, so the buffer won't be
  -auto-flushed as the script hangs at the end.)
  +Next the script prints out a single line telling us the id of the process
  +that handles this request, which we need to know in order to run the
  +tracing utility. Then we flush Apache's buffer. (If we don't flush the
  +buffer we will never see this short information printed. That's because our
  +output is shorter than the buffer size and the script intentionally hangs,
  +so the buffer won't be auto-flushed as the script hangs at the end.)
   
   <P>
  -Then we enter an infinite loop, which just increments a dummy variable and
  -sleeps for a second.
  +Then we enter an infinite <CODE>while(1)</CODE> loop, which just increments a dummy variable and sleeps for a second.
   
   <P>
   Running <CODE>strace -p PID</CODE>, where <EM>PID</EM> is the process ID as printed to the browser, we see the following output
  @@ -1951,21 +1963,24 @@
   
   	<td>
   	  <pre>  SYS_175(0, 0xbffff41c, 0xbffff39c, 0x8, 0) = 0
  -  SYS_174(0x11, 0, 0xbffff1a0, 0x8, 0x11) = 0
  -  SYS_175(0x2, 0xbffff39c, 0, 0x8, 0x2)   = 0
  -  nanosleep(0xbffff308, 0xbffff308, 0x401a61b4, 0xbffff308, 0xbffff41c) = 0
  -  time([941281947])                       = 941281947
  -  time([941281947])                       = 941281947</pre>
  +  SYS_174(0x11, 0, 0xbffff1a0, 0x8, 0x11)    = 0
  +  SYS_175(0x2, 0xbffff39c, 0, 0x8, 0x2)      = 0
  +  nanosleep(0xbffff308, 0xbffff308, 
  +            0x401a61b4, 0xbffff308, 0xbffff41c) = 0
  +  time([941281947])                     = 941281947
  +  time([941281947])                     = 941281947</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -Let's leave <CODE>strace</CODE> running and press the <STRONG>STOP</STRONG> button. Did anything change? No, the same trace printed every second. Which
  -means that Apache didn't detect the broken pipe.
  +Let's leave <CODE>strace</CODE> running and press the <STRONG>STOP</STRONG> button. Did anything change? No, the same system calls trace is printed
  +every second. Which means that Apache didn't detect the broken connection.
   
   <P>
  -Let's try to write a NULL <CODE>\0</CODE> character to the client so the broken pipe will be detected as soon the <STRONG>Stop</STRONG> button is pressed:
  +Now we are going to write the <CODE>\0</CODE> (NULL) character to the client in attempt to detect the broken connection
  +as close as possible to the time the <STRONG>Stop</STRONG> button is pressed at. Therefore we modify the loop code in the following
  +way:
   
   <P>
   
  @@ -1989,13 +2004,16 @@
       </table>
       <P>
   We add a <CODE>print()</CODE> statement to print a NULL character and then
  -we check whether the connection was aborted. If it was, we break from the
  -loop.
  +we check whether the connection was aborted with help of the
  +<CODE>$r-&gt;connection-&gt;aborted</CODE> method. If the connection is broken, we break out of the loop.
   
   <P>
   We run this script and strace on it as before, but we see that it still
  -doesn't work. The trouble is we aren't flushing the buffer. After printing
  -the NULL, add $r-&gt;rflush():
  +doesn't work. The trouble is we aren't flushing the buffer, which leaves
  +the characters in the buffer and they won't be printed before the buffer
  +will get full and will be autoflushed. Since we want to attempt to write to
  +the connection pipe all the time, after printing the NULL, we add
  +$r-&gt;rflush(). Here is a new version of the code:
   
   <P>
   
  @@ -2007,7 +2025,9 @@
           </td>
   
   	<td>
  -	  <pre>  my $r = shift;
  +	  <pre>  stopping_detector2.pl
  +  ---------------------
  +  my $r = shift;
     $r-&gt;send_http_header('text/plain');
     
     print &quot;PID = $$\n&quot;;
  @@ -2027,8 +2047,7 @@
         </tr>
       </table>
       <P>
  -Watch <CODE>strace</CODE>'s output on the running process and then press the
  -<STRONG>Stop</STRONG> button, you will see:
  +After starting the <CODE>strace</CODE> utility on the running process as we did before and pressing the <STRONG>Stop</STRONG> button, we have seen the following output.
   
   <P>
   
  @@ -2099,7 +2118,7 @@
         </tr>
       </table>
       <P>
  -In the <EM>access_log</EM> file we can see the file descriptor of the logfile in this process (17).
  +where 17 is a file descriptor of the opened <EM>access_log</EM> file
   
   <P>
   Let's see how can we make the code more general-purpose:
  @@ -2184,25 +2203,29 @@
   <HR>
   <CENTER><H2><A NAME="The_Importance_of_Cleanup_Code">The Importance of Cleanup Code</A></H2></CENTER>
   <P>
  -This is a critical issue with aborted scripts.
  +Cleanup code is a critical issue with aborted scripts.
   
   <P>
  -What happens to locked resources? Will they be freed or not? If not,
  -scripts using these resources and the same locking scheme will hang,
  -waiting for this resource to be freed.
  +What happens to locked resources if there are any? Will they be freed or
  +not? If not, scripts using these resources and the same locking scheme will
  +hang, waiting for them to be freed.
   
   <P>
  -Under mod_cgi this was a problem only if you happened to use external lock
  -files for lock indication, instead of using <CODE>flock().</CODE> If the
  -script was aborted between the lock and the unlock code, and you didn't
  -bother to write cleanup code to remove old dead locks then you were in big
  -trouble.
  +First let's go one step back and recall what are the problems and solutions
  +for this issue under mod_cgi.
   
   <P>
  -With mod_cgi you can create an <CODE>END</CODE> block, and put the cleanup code there:
  +Under mod_cgi the resource locking issue is a problem only if you happened
  +to create external lock files and and use them for lock indication, instead
  +of using <CODE>flock().</CODE> If the script running under mod_cgi is
  +aborted between the lock and the unlock code, and you didn't bother to
  +write cleanup code to remove old dead locks then you are in big trouble.
   
   <P>
  +The solution is to use an <CODE>END</CODE> block to place the cleanup code in:
   
  +<P>
  +
       <table>
         <tr>
   
  @@ -2211,7 +2234,7 @@
           </td>
   
   	<td>
  -	  <pre>  END{
  +	  <pre>  END {
       # some code that ensures that locks are removed
     }</pre>
           </td>
  @@ -2222,24 +2245,25 @@
   When the script is aborted, Apache will run the <CODE>END</CODE> blocks.
   
   <P>
  -If you use <CODE>flock()</CODE> things are much simpler, since all opened files will be closed. When the
  -file is closed, the lock is removed as well and all the locked resources
  -will be freed. There are systems where <CODE>flock(2)</CODE> is
  -unavailable, and for those you can use Perl's emulation of this function.
  +If you use <CODE>flock()</CODE> things are much simpler, since all opened files will be closed when the
  +script exits. When the file is closed, the lock is removed as well--all the
  +locked resources get freed. There are systems where <CODE>flock(2)</CODE>
  +is unavailable, and for those you can use Perl's emulation of this
  +function.
   
   <P>
  -With mod_perl things are more complex. Because the processes don't exit
  -after processing a request, files won't be closed unless you explicitly
  -<CODE>close()</CODE> them or reopen with the <CODE>open()</CODE> call,
  -which first closes a file. Let's see what problems we might encounter, and
  -possible solutions for them.
  +With mod_perl things can be more complex when you use global variables as a
  +filehandlers. Because the processes don't exit after processing a request,
  +files won't be closed unless you explicitly <CODE>close()</CODE> them or
  +reopen with the <CODE>open()</CODE> call, which first closes a file. Let's
  +see what problems we might encounter, and possible solutions for them.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
   <CENTER><H3><A NAME="Critical_Section">Critical Section</A></H3></CENTER>
   <P>
  -First I want to make a little detour to discuss the <EM>"critical
  +First we want to make a little detour to discuss the <EM>"critical
   section"</EM> issue.
   
   <P>
  @@ -2267,19 +2291,19 @@
       </table>
       <P>
   If the locking is exclusive, only one process can hold the resource at any
  -given time, which means that all the other processes will have to wait, and
  -this code snippet becomes a so called bottleneck. That's why the section of
  -the code where the resource is locked is called critical and you must make
  -it as short as possible.
  +given time, which means that all the other processes will have to wait,
  +therefore the code between the locking and unlocking functions can become a
  +service bottleneck. That's why this code section is called critical and
  +once started it should be finished as soon as possible.
   
   <P>
  -In a shared locking scheme, where many processes can concurrently access
  -the resource, if there are processes that sometimes want to get an
  -exclusive lock it's also important to keep the critical section as short as
  -possible.
  +Even if you use a shared locking scheme, where many processes are allowed
  +to concurrently access the resource, if there are processes that sometimes
  +want to get an exclusive lock it's also important to keep the critical
  +section as short as possible.
   
   <P>
  -The code below uses a shared lock, but has a poorly-designed critical
  +The next example uses a shared lock, but has a poorly-designed critical
   section:
   
   <P>
  @@ -2292,44 +2316,67 @@
           </td>
   
   	<td>
  -	  <pre>  use Fcntl qw(:flock);
  +	  <pre>  critical_section_sh.pl
  +  -------------------
  +  use Fcntl qw(:flock);
     use Symbol;
     my $fh = gensym;
     
  -  open $fh, &quot;filename&quot; or die &quot;$!&quot;;
  +  open $fh, &quot;/tmp/foo&quot; or die $!;
     flock $fh, LOCK_SH;
  -  
       # start critical section
  +  
     seek $fh, 0, 0;
     my @lines = &lt;$fh&gt;;
     for(@lines){
       print if /foo/;
     }
  -    # end critical section
     
  +    # end critical section
     close $fh; # close unlocks the file</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -The code opens the file for reading, locks and rewinds to the start, reads
  -all the lines from the file and prints out the lines that contain the
  -string <EM>foo</EM>. Note that the file remains open and locked while the loop executes.
  +The code opens the file for reading, locks and rewinds it to the beginning,
  +reads all the lines from the file and prints out the lines that contain the
  +string <EM>'foo'</EM>.
  +
  +<P>
  +The <CODE>gensym()</CODE> function imported by the <CODE>Symbol</CODE> module creates an anonymous glob and returns a reference to it. Such a glob
  +reference can be used as a file or directory handle. and therefore allows
  +using lexically scoped variables as filehandlers. <CODE>Fcntl</CODE> imports into the script's namespace file locking symbols like: <CODE>LOCK_SH</CODE>, <CODE>LOCK_EX</CODE>
  +and more. Refer to the <CODE>Fcntl</CODE> manpage for more information.
  +
  +<P>
  +If the file the script reads is big, it'd take a relatively long time for
  +this code to complete. All this time the file remains open and locked.
  +While it's other processes may access this file for reading (shared lock),
  +the process that wants to modify the file (which requires an acquision of
  +the exclusive lock), will be blocked waiting for this section to complete.
   
   <P>
   We can optimize the critical section this way:
   
   <P>
   Once the file has been read, we have all the information we need from it.
  -The loop might take some time to complete. We don't need the file to be
  -open while the loop executes, because we don't access it inside the loop.
  -If we close the file before we start the loop, we will allow other
  -processes to have access to the file if they need it, instead of blocking
  -them for no reason.
  +In order to make the example simpler we've chosen to just print out the
  +matching lines. In reality the code might be much longer.
  +
  +<P>
  +We don't need the file to be open while the loop executes, because we don't
  +access it inside the loop. If we close the file before we start the loop,
  +we will allow other processes to have an exclusive access to the file if
  +they need it, instead of blocking them for no reason.
   
   <P>
  +In the following corrected version of the previous example, we only read
  +the content of the file during the critical section and process it
  +afterwards, without creating a possible bottleneck.
   
  +<P>
  +
       <table>
         <tr>
   
  @@ -2338,18 +2385,20 @@
           </td>
   
   	<td>
  -	  <pre>  use Fcntl qw(:flock);
  +	  <pre>  critical_section_sh2.pl
  +  --------------------
  +  use Fcntl qw(:flock);
     use Symbol;
     my $fh = gensym;
     
  -  open $fh, &quot;filename&quot; or die &quot;$!&quot;;
  +  open $fh, &quot;/tmp/foo&quot; or die $!;
     flock $fh, LOCK_SH;
  -  
       # start critical section
  +  
     seek $fh, 0, 0;
     my @lines = &lt;$fh&gt;;
  -    # end critical section
     
  +    # end critical section
     close $fh; # close unlocks the file
     
     for(@lines){
  @@ -2360,9 +2409,9 @@
         </tr>
       </table>
       <P>
  -This is another very similar script, but now using an exclusive lock. It
  -reads in a file and writes it back, prepending a number of new text lines
  -to the head of the file.
  +Here is another similar example, but now it uses an exclusive lock. The
  +script reads in a file and writes it back, prepending a number of new text
  +lines to the head of the file.
   
   <P>
   
  @@ -2374,11 +2423,13 @@
           </td>
   
   	<td>
  -	  <pre>  use Fcntl qw(:flock);
  +	  <pre>  critical_section_ex.pl
  +  --------------------
  +  use Fcntl qw(:flock);
     use Symbol;
     my $fh = gensym;
     
  -  open $fh, &quot;+&gt;&gt;filename&quot; or die &quot;$!&quot;;
  +  open $fh, &quot;+&gt;&gt;/tmp/foo&quot; or die $!;
     flock $fh, LOCK_EX;
     
       # start critical section
  @@ -2403,34 +2454,29 @@
         </tr>
       </table>
       <P>
  -First let's see how the code works. I will discuss why I use the
  -<CODE>Symbol</CODE> module to generate the file handles in the next section.
  -
  -<P>
   Since we want to read the file, modify and write it back, without anyone
   else changing it on the way, we open it for read and write with the help of <EM>+&gt;&gt;</EM> and lock it with an exclusive lock. You cannot safely accomplish this task
   by opening the file first for read and then reopening for write, since
  -another process might change the file between the two. (You could get away
  -with <EM>+&lt;</EM>, see
  -<EM>perldoc -f open</EM> or the <EM>perlfunc</EM> manpage for more information about the <CODE>open()</CODE> function.)
  +another process might change the file between the two events. (You could
  +get away with <EM>+&lt;</EM> as well, please refer to the <EM>perlfunc</EM> manpage for more information about the <CODE>open()</CODE> function.)
   
   <P>
  -Next the code prepares the lines of text it wants to prepend to the head of
  -the file, and assigns them and the content of the file to the
  +Next, the code prepares the lines of text it wants to prepend to the head
  +of the file, and assigns them and the content of the file to the
   <CODE>@lines</CODE> array. Now we have our data ready to be written back to the file, so we
   <CODE>seek()</CODE> to the start of the file and <CODE>truncate()</CODE> it
   to zero size. In our example the file always grows, so in this case there
   is no need to truncate it, but if there was a chance that the file might
   shrink then truncating would be necessary. However it's good practice to
  -use <CODE>truncate(),</CODE> as you never know what changes your code might
  -undergo in the future. The <CODE>truncate()</CODE> operation does not carry
  -any significant performance penalty. Finally we write the data back to the
  -file and close it, which unlocks it as well.
  +always use <CODE>truncate(),</CODE> as you never know what changes your
  +code might undergo in the future. The <CODE>truncate()</CODE> operation
  +does not carry any significant performance penalty. Finally we write the
  +data back to the file and close it, which unlocks it as well.
   
   <P>
   Did you notice that we created the text lines to be prepended as close to
  -the place of usage as possible? This is good ``locality of code'' style,
  -but it makes the critical section longer. In such cases you should
  +the place of usage as possible? This complies with good
  +<EM>"locality of code"</EM> style, but it makes the critical section longer. In such cases you should
   sacrifice style, in order to make the critical section as short as
   possible. An improved version of this script with a shorter critical
   section looks like this:
  @@ -2445,7 +2491,9 @@
           </td>
   
   	<td>
  -	  <pre>  use Fcntl qw(:flock);
  +	  <pre>  critical_section_ex2.pl
  +  --------------------
  +  use Fcntl qw(:flock);
     use Symbol;
     
     my @lines =
  @@ -2457,59 +2505,59 @@
       );
     
     my $fh = gensym;
  -  open $fh, &quot;+&gt;&gt;filename&quot; or die &quot;$!&quot;;
  +  open $fh, &quot;+&gt;&gt;/tmp/foo&quot; or die $!;
     flock $fh, LOCK_EX;
  -  
       # start critical section
  +  
     seek $fh, 0, 0;
     push @lines, &lt;$fh&gt;;
     
     seek $fh, 0, 0;
     truncate $fh, 0;
     print $fh @lines;
  -    # end critical section
     
  +    # end critical section
     close $fh; # close unlocks the file</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -There are two important differences. Firstly, we prepare the text lines to
  -be prepended <EM>before</EM> the file is locked. Secondly, instead of creating a new array and copying
  +There are two important differences. First, we prepare the text lines to be
  +prepended <EM>before</EM> the file is locked. Second, instead of creating a new array and copying
   lines from one array to another, we append the file directly to the <CODE>@lines</CODE> array.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  -<CENTER><H3><A NAME="Safe_Resource_Locking">Safe Resource Locking</A></H3></CENTER>
  +<CENTER><H3><A NAME="Safe_Resource_Locking_and_Cleanu">Safe Resource Locking and Cleanup Code</A></H3></CENTER>
   <P>
   Let's get back to the main issue of this section, which is safe resource
   locking.
   
   <P>
   Unless you use the <CODE>Apache::PerlRun</CODE> handler that does the cleanup for you, if you don't make a habit of closing
  -all the files that you open you will encounter lots of problems. If you
  -open a file but don't close it, you will have file descriptor leakage.
  -Since the number of file descriptors available to you is finite, at some
  -point you will run out of them and your service will fail.
  -
  -<P>
  -This is bad, but you can live with it until you run out of file descriptors
  -(which will happen much faster on a heavily used server). But this is
  -nothing compared to the trouble you will give yourself if you lock, but
  -forget to unlock or close your locked files. Since <CODE>close()</CODE>
  -always unlocks the file, you don't have to unlock files explicitly.
  -
  -<P>
  -But a locked file will stay locked after your code has terminated!
  +all the files that you open--in some cases you will encounter lots of
  +problems. If you open a file but don't close it, you may have file
  +descriptor leakage. Since the number of file descriptors available to you
  +is finite, at some point you may run out of them and your service will
  +fail. This is bad, but you can live with it until you run out of file
  +descriptors (which will happen much faster on a heavily used server).
  +
  +<P>
  +You can use system utilities to observe the opened and locked files, as
  +well as the processes that has opened (and locked) the files. On FreeBSD
  +you would use the <CODE>fstat(1)</CODE> utility. On many other UN*X flavors
  +the <CODE>lsof(1)</CODE> utility is available.
  +
  +<P>
  +But this is nothing compared to the trouble you will give yourself if the
  +code terminates and the file stays locked. Any other process requesting a
  +lock on the same file (or resource) will wait indefinitely for it to become
  +unlocked. Since this will not happen until the server reboots, all these
  +processes trying to use this resource will hang.
   
   <P>
  -Any other process requesting a lock on the same file (or resource) will
  -wait indefinitely for it to become unlocked. Since this will not happen
  -until the server reboots, all these processes will hang.
  -
  -<P>
   Here is an example of such a terrible mistake:
   
   <P>
  @@ -2522,22 +2570,23 @@
           </td>
   
   	<td>
  -	  <pre>  open IN, &quot;+&gt;&gt;filename&quot; or die &quot;$!&quot;;
  +	  <pre>  flock.pl
  +  --------
  +  use Fcntl qw(:flock);
  +  open IN, &quot;+&gt;&gt;filename&quot; or die &quot;$!&quot;;
     flock IN, LOCK_EX;
  -  # do something
  -  # quit without closing and unlocking the file</pre>
  +    # do something
  +    # quit without closing and unlocking the file</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -Is this safe code? No - we forgot to close the file.
  +Is this safe code? No - we forgot to close the file. So let's add the
  +<CODE>close():</CODE>
   
   <P>
  -So let's add the <CODE>close():</CODE>
   
  -<P>
  -
       <table>
         <tr>
   
  @@ -2546,12 +2595,12 @@
           </td>
   
   	<td>
  -	  <pre>  open IN, &quot;+&gt;&gt;filename&quot; or die &quot;$!&quot;;
  +	  <pre>  flock2.pl
  +  ---------
  +  use Fcntl qw(:flock);
  +  open IN, &quot;+&gt;&gt;filename&quot; or die &quot;$!&quot;;
     flock IN, LOCK_EX;
  -    # start critical section
  -  # do something
  -    # end critical section
  -  # close and unlock the file
  +    # do something
     close IN;</pre>
           </td>
   	    
  @@ -2565,53 +2614,16 @@
   if we forgot to close it.
   
   <P>
  -There are a few approaches we can take to solving this problem. If you are
  -running under <CODE>Apache::Registry</CODE> and friends, the <CODE>END</CODE>
  -block will perform the cleanup work for you. You might use <CODE>END</CODE> in the same way for scripts running under mod_cgi, or in plain Perl
  -scripts. Just add the cleanup code to this block and you are safe. Since
  -under mod_perl the <CODE>END</CODE> blocks will not be executed after the completion of a request, but only
  -when an Apache child process exits, then if you are writing your own
  -handlers you will need to use the <CODE>register_cleanup()</CODE> function
  -to supply cleanup code similar to that used in <CODE>END</CODE> blocks instead of using <CODE>END</CODE> blocks. We will see a few examples later.
  +In fact if the same process will run the same code again, an
  +<CODE>open()</CODE> call will close the file first, which will unlock the
  +resource. This is because <CODE>IN</CODE> is a global variable. But it's quite possible that the process that created
  +the lock, will not serve the same request for a while, since it would be
  +busy serving other requests. So relying on it to reopen the file is a bad
  +idea.
   
   <P>
  -Of course, if the same child executes the same section of code of the same
  -script, the <CODE>open()</CODE> call on the same file handle will first
  -<CODE>close()</CODE> the file. But this will happen only if it's the same
  -filehandle, which is correct if you use the scalar variable like
  -<CODE>IN</CODE>, <CODE>OUT</CODE>. As you will see in a moment if you use <CODE>Symbol</CODE> or &lt;IO::*&gt; modules, a unique filehandle will be generated every time
  --- you get a file desriptor leakage and the file will be not unlocked in
  -case it was locked.
  -
  -<P>
  -On Linux OS you can use the <CODE>lsof(1)</CODE> utility to list open files
  -and the processes who have opened them. On FreeBSD you would use the
  -<CODE>fstat(1)</CODE> utility.
  -
  -<P>
  -Now I want to show you a much easier safe locking solution.
  -
  -<P>
  -Although it might not be obvious, the problem we have encountered is
  -actually the fact that file handles like <CODE>IN</CODE> are global variables. If we could make them lexically scoped, all our
  -worries would go away. You know that lexically scoped (with the
  -<CODE>my()</CODE> operand) variables are automatically destroyed when they
  -go out of scope. When the program quits, all the lexical variables will be
  -destroyed since they only have file scope. When a variable holding an
  -opened file descriptor is destroyed, the file will automatically be closed
  -and unlocked.
  -
  -<P>
  -So if you use this technique to work with files, you even don't have to
  -explicitly close the files! (Of course if you recall the critical section
  -discussion above, you will still want to make sure that you close them as
  -soon as possible.) In addition to the benefits of safe file handling,
  -having the file handlers lexically scoped will protect you from names
  -collisions. If you use global file handles, e.g when you have to open more
  -than one file, you always have to make sure you don't use the same
  -filehandle name somewhere else in the code in case it might still be
  -associated with an open file. To emphasize the risk of collisions think of
  -subroutine that opens a file for you:
  +This problem happens <STRONG>only</STRONG> if you use global variables as file handles. The following example has the
  +same problem.
   
   <P>
   
  @@ -2622,50 +2634,32 @@
   	  &nbsp;
           </td>
   
  -	<td>
  -	  <pre>  sub open_file{
  -    my $filename  = shift;
  -    open FILE, &quot;&gt;$filename&quot; or die &quot;$!&quot;;
  -    return \*FILE;
  -  }</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
   	<td>
  -	  <pre>  my $fh1 = open_file(&quot;/tmp/x&quot;);
  -  my $fh2 = open_file(&quot;/tmp/y&quot;);
  -  print $fh1 &quot;X&quot;;
  -  print $fh2 &quot;Y&quot;;</pre>
  +	  <pre>  flock3.pl
  +  ---------
  +  use Fcntl qw(:flock);
  +  use Symbol ();
  +  use vars qw($fh);
  +  $fh = Symbol::gensym();
  +  open $fh, &quot;+&gt;&gt;filename&quot; or die &quot;$!&quot;;
  +  flock $fh, LOCK_EX;
  +    # do something
  +  close $fh;</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -This code doesn't do what you think it should do. Instead of writing the
  -character <CODE>X</CODE> to <EM>/tmp/x</EM> file and <CODE>Y</CODE> to <EM>/tmp/y</EM>, what you see after running this script is that <EM>/tmp/x</EM> is empty and <EM>/tmp/y</EM>
  -contains a <CODE>XY</CODE> string. Why is that? Because you have used the same global variable <CODE>FILE</CODE> twice, and when you called <CODE>open_file()</CODE> for a second time it
  -opened a different file using the same variable. Since
  -<CODE>open_file()</CODE> always returns a reference to the same global file
  -handle variable, both <CODE>$fh1</CODE> and <CODE>$fh2</CODE> point to it.
  -
  -<P>
  -There is another way. As you saw earlier we can generate unique, lexically
  -scoped file handles with the <CODE>Symbol</CODE> module.
  +<CODE>$fh</CODE> is still a global variable and therefore the code using it suffers from the
  +same problem.
   
   <P>
  -<CODE>Symbol::gensym()</CODE> creates an anonymous glob and returns a reference to it. Such a glob
  -reference can be used as a file or directory handle. Here is how you can
  -use it:
  +The simplest solution to this problem is to always use lexically scoped
  +variables (created with <CODE>my()).</CODE> Whether script gets aborted
  +before <CODE>close()</CODE> is called or you forgot the use
  +<CODE>close()</CODE> the lexically scoped variable will always go out of
  +scope and therefore if the file was locked it will be unlocked. Here is a
  +good version of the code:
   
   <P>
   
  @@ -2677,20 +2671,26 @@
           </td>
   
   	<td>
  -	  <pre>  use Symbol;
  -  my $fh = gensym;
  +	  <pre>  flock4.pl
  +  ---------
  +  use Fcntl qw(:flock);
  +  use Symbol ();
  +  my $fh = Symbol::gensym();
     open $fh, &quot;+&gt;&gt;filename&quot; or die &quot;$!&quot;;
     flock $fh, LOCK_EX;
  -  # do something</pre>
  +    # do something
  +  close $fh;</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -Now the file will be always unlocked after processing the request.
  +Please don't conclude from this example that you don't have to close files
  +anymore, since they will be automatically closed for you. It's a bad style
  +and should be avoided.
   
   <P>
  -Instead of using <CODE>close(),</CODE> you might use a block:
  +Under Perl version 5.6 <CODE>Symbol.pm</CODE>-like functionality is a built-in feature, so you can do:
   
   <P>
   
  @@ -2702,28 +2702,20 @@
           </td>
   
   	<td>
  -	  <pre>  use Symbol;
  -  {
  -    my $fh = gensym;
  -    open $fh, &quot;+&gt;&gt;filename&quot; or die &quot;$!&quot;;
  -    flock $fh, LOCK_EX;
  -    # do something
  -  }
  -  # the file will be automatically closed and unlocked at this point</pre>
  +	  <pre>  open my $fh, &quot;&gt;/tmp/foo&quot; or die $!;</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -But this is perhaps not so obvious to the reader of the code, so you might
  -want to avoid this last technique and put in an explicit
  -<CODE>close().</CODE>
  +and <CODE>$fh</CODE> will be automatically vivified as a valid filehandle, so you don't need to
  +use the <CODE>Symbol</CODE> module anymore, if backward compatibility is not a requirement.
   
   <P>
   You can also use the <CODE>IO::*</CODE> modules, such as <CODE>IO::File</CODE> or
   <CODE>IO::Dir</CODE>. These are much bigger than the &lt;Symbol&gt; module, and worth using for files or directories only if you are
   already using them for the other features which they provide. As a matter
  -of fact, these modules use the <CODE>Symbol</CODE> module themselves. Here are some examples of their use:
  +of fact, these modules use the <CODE>Symbol</CODE> module themselves. Here is an example of their usage:
   
   <P>
   
  @@ -2736,516 +2728,26 @@
   
   	<td>
   	  <pre>  use IO::File;
  +  use IO::Dir;
     my $fh = IO::File-&gt;new(&quot;&gt;filename&quot;);
  -  # the rest is as before</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -and:
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  use IO::Dir;
     my $dh = IO::Dir-&gt;new(&quot;dirname&quot;);</pre>
           </td>
   	    
         </tr>
       </table>
  -    <P>
  -Under perl 5.6 <CODE>Symbol.pm</CODE>-like functionality is a built-in feature, so you can do:
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  open my $fh, &quot;&gt; filename&quot;;</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -and <CODE>$fh</CODE> will be automatically vivified as a valid filehandle, so you don't need to
  -use the <CODE>Symbol</CODE> module anymore.
  -
  -<P>
  -[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  -<HR>
  -<CENTER><H3><A NAME="Cleanup_Code">Cleanup Code</A></H3></CENTER>
  -<P>
  -Finally, let's look at the case where we need special clean up code. As you
  -have seen, we solved the problem of accidentally leaving file handles lying
  -around by lexically scoping them. There are however, situations where you
  -absolutely must write cleanup code. A tied dbm file is a good example.
  -
  -<P>
  -A reminder: a dbm file is a simple database, which allows you to store
  -pairs of keys and values in it. As of this writing, Berkeley DB is the most
  -advanced dbm implementation, it allows you to store key/value pairs using
  -the HASH, BTREE and RECNO algorithms. The <CODE>BerkeleyDB</CODE>
  -module provides a Perl interface to Berkeley DB versions 2 and 3, while the <CODE>DB_File</CODE> module handles the older Berkeley DB, version 1. Refer to the <CODE>DB_File</CODE> man page for more information.
  -
  -<P>
  -With the help of the TIE interface, working with dbm files is very simple
  -because they are represented in Perl as simple hash variables. They behave
  -almost exactly like hashes.
  -
  -<P>
  -In order to access a dbm file you have to tie it first:
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  use Fcntl qw(O_RDWR O_CREAT);
  -  use DB_File;
  -  my $filename = &quot;/tmp/mydb&quot;;
  -  my %hash;
  -  tie %hash, 'DB_File', $filename, O_RDWR|O_CREAT, 0660, $DB_HASH
  -     or die &quot;Can't tie %hash : $!&quot;;</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
       <P>
  -The first argument to <CODE>tie()</CODE> is the hash variable to which we
  -want the dbm file to be tied. The remaining arguments are: the name of the
  -module that provides the interface (<CODE>DB_File</CODE> in this case); the name of our dbm file; Fcntl flags; file permissions; and
  -finally the interface method to be used (DB_HASH, DB_BTREE or DB_RECNO).
  -
  -<P>
  -From now on we use <CODE>%hash</CODE> to read from and write to the dbm file, like this:
  +If you still have to use global filehandles, there are a few approaches we
  +can take to solving the locking problem.
   
   <P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  $hash{foo} = &quot;Larry Wall&quot;;
  -  my $name = $hash{foo};</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -The only wrinkle is that when we modify the hash (by assigning some values
  -to it) the changes are not written immediately to the file. They are cached
  -to improve performance. The cache buffers are flushed in the following
  -circumstances: when they become full; when the <CODE>sync()</CODE> method
  -is called on the database handle; and when the hash is untied (closed). So
  -be aware that if the program quits abnormally, the dbm file might be
  -corrupted.
  -
  -<P>
  -To untie the dbm file, simply call:
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  untie %hash;</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -To gain the access to the <CODE>sync()</CODE> method, you should retrieve
  -the database handle which is returned by the <CODE>tie()</CODE> method:
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  my $dbh = tie %hash, 'DB_File', $filename, O_RDWR|O_CREAT, 0660, $DB_HASH
  -     or die &quot;Can't tie %hash : $!&quot;;</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -Now you can flush the cache with:
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  $hash{foo} = &quot;Larry Wall&quot;;
  -  $dbh-&gt;sync;</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -Important: If you have saved a copy of the object returned from
  -<CODE>tie(),</CODE> the underlying database file will not be closed until
  -both the tied variable is untied and all copies of the saved object are
  -destroyed.
  -
  -<P>
  -We do this as follows:
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  undef $dbh;
  -  untie %hash;</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -Of course, you have to lock the dbm file exactly like any other resource if
  -some script modifies its contents. Refer to <A HREF="././dbm.html#Locking_dbm_handlers">Locking dbm handlers</A> for more information.
  -
  -<P>
  -Okay, enough introduction, let's get to the point. Since both <CODE>%hash</CODE>
  -and <CODE>$dbh</CODE> are lexically scoped variables, they will always be destroyed, even if you
  -forgot to <CODE>untie()</CODE> them or if the request was aborted before
  -the <CODE>untie()</CODE> function was called.
  -
  -<P>
  -Suppose that you want to have the benefit of mod_perl's persistent global
  -variables in each process and to use this feature to create persistent dbm
  -hashes. You <CODE>tie()</CODE> them only once per Apache child process,
  -thus saving the time which it would take to <CODE>tie()</CODE> and
  -<CODE>untie()</CODE> them for each client request. Assuming that you
  -remember that you must flush the cache buffers (with the
  -<CODE>sync()</CODE> method) when you modify the hash that represents the
  -dbm file, the idea is a good one. Let's code it...
  -
  -<P>
  -We declare <CODE>$dbh</CODE> and <CODE>%hash</CODE> as global variables, then pull in the
  -<CODE>Fcntl</CODE> module and import the symbols we are going to use. Actually we need only <CODE>LOCK_EX</CODE> from the tags provided by <CODE>:flock</CODE>. We pull in the <CODE>DB_File</CODE> and <CODE>Symbol</CODE> modules:
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  use strict;
  -  use vars qw($dbh %hash);
  -  use Fcntl qw(:flock O_RDWR O_CREAT);
  -  use DB_File;
  -  use Symbol;
  -  
  -  # Send the I&lt;Content-type&gt; header of plain text type and tell the
  -  # user the PID of the process that's serving the request:
  -  
  -  my $r = shift;
  -  $r-&gt;send_http_header('text/plain');
  -  $r-&gt;print(&quot;PID $$\n&quot;);
  -  
  -  # The location of the dbm file and its lock file:
  -  
  -  my $filename = &quot;/tmp/mydb&quot;;
  -  my $lockfile = &quot;$filename.lock&quot;;
  -  
  -  # Generate a unique anonymous glob, store it in a lexically scoped
  -  # variable C&lt;$fh&gt;, and lock the file.  This in turn advisory locks
  -  # the dbm file (which will be safely tied):
  -  
  -  my $fh = gensym;
  -  open $fh, &quot;&gt;$lockfile&quot; or die &quot;Cannot open $lockfile: $!&quot;;
  -  flock $fh, LOCK_EX;</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  # Other copies of this script which wish to access the following
  -  # code have to acquire the lock file first.  Since it's an exclusive
  -  # lock, only one copy of the script will be able to tie the dbm
  -  # file.</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  $dbh ||= tie %hash, 'DB_File', $filename, O_RDWR|O_CREAT, 0660, $DB_HASH
  -     or die &quot;Can't tie %hash : $!&quot;;</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -This code snippet demands some explanation.
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  $a ||= $b;</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -is the same as:
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  $a = $a || $b;</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -The boolean test <CODE>||</CODE> (logical OR) doesn't care about undefined values, since <CODE>undef</CODE> is <CODE>false</CODE> in Perl. So what it does is this:
  -
  -<P>
  -If <CODE>$a</CODE> is <EM>true</EM>, leave it unmodified. Otherwise test <CODE>$b</CODE>.
  -
  -<P>
  -If <CODE>$b</CODE>  <EM>true</EM>, assign the value of <CODE>$b</CODE> to <CODE>$a</CODE>.
  -
  -<P>
  -If <CODE>$b</CODE> is <EM>false</EM>, <CODE>$a</CODE> stays undefined.
  -
  -<P>
  -Note that 0 and <CODE>&quot;&quot;</CODE> (the empty string) are both <EM>defined</EM>, but they are <EM>false</EM> values! Refer to the <CODE>perlop(1)</CODE> manpage for more information
  -about the <CODE>||</CODE> operator.
  -
  -<P>
  -Back to our <CODE>tie()</CODE> snippet. For each mod_perl process, when
  -this code is executed for the first time, the <CODE>$dbh</CODE> variable is undefined. Therefore the right-hand part of the statement will
  -be executed, <CODE>tie()ing</CODE> the dbm file. On every subsequent
  -invocation of the code by that same process, <CODE>$dbh</CODE> will contain a database handle. This is considered by Perl to be a <EM>true</EM> value, so the <CODE>tie()</CODE> call will not be executed, eliminating the
  -overhead of the call to <CODE>tie().</CODE>
  -
  -<P>
  -Now we fill the dbm file with random key/value pairs. Each invocation of
  -the code will either generate a new key/value pair or, if an existing key
  -is returned by <CODE>rand(),</CODE> override an old one.
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  $hash{int rand 10} = (qw(a b c d))[int rand 4];
  -  $dbh-&gt;sync();</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -The most important part of the code is to flush the modifications to the
  -dbm.
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>    # unlock the db
  -  close $fh;</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -Now it's safe to unlock the dbm file. Please refer to <A HREF="././dbm.html#Locking_dbm_handlers">Locking dbm handlers</A> to learn why you should use a dbm's file descriptor to lock itself. To cut
  -a long story short, if you don't you may corrupt your dbm file.
  -
  -<P>
  -After we leave the critical section, we can take our time and print out the
  -current contents of the dbm file.
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  # print the contents of the the dbm file
  -  print map {&quot;$_ =&gt; $hash{$_}\n&quot;} sort keys %hash;</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -Here is the same code with fewer comments:
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  use strict;
  -  use vars qw($dbh %hash);
  -  use Fcntl qw(:flock O_RDWR O_CREAT);
  -  use DB_File;
  -  use Symbol;
  -  
  -  my $r = shift;
  -  $r-&gt;send_http_header('text/plain');
  -  $r-&gt;print(&quot;PID $$\n&quot;);
  -  
  -  my $filename = &quot;/tmp/mydb&quot;;
  -  my $lockfile = &quot;$filename.lock&quot;;
  -  
  -  my $fh = gensym;
  -  open $fh, &quot;&gt;$lockfile&quot; or die &quot;Cannot open $lockfile: $!&quot;;
  -  
  -    # must lock the db file before opening it
  -  flock $fh, LOCK_EX;
  -  
  -  $dbh ||= tie %hash, 'DB_File', $filename, O_RDWR|O_CREAT, 0660, $DB_HASH
  -     or die &quot;Can't tie %hash : $!&quot;;
  -  
  -    # fill the dbmfile with random key/value pairs
  -  $hash{int rand 10} = (qw(a b c d))[int rand 4];
  -  
  -    # sync the DB
  -  $dbh-&gt;sync();
  -  
  -    # unlock the db
  -  close $fh;
  -  
  -    # print the contents of the the dbm file
  -  print map {&quot;$_ =&gt; $hash{$_}\n&quot;} sort keys %hash;</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -Well, if you run this code, you pretty soon figure out that this code
  -doesn't do what we thought it would. What happens is that each process
  -keeps its own copy of the <CODE>%hash</CODE> and modifies it. When the process calls the <CODE>sync()</CODE> method, the
  -dbm file is updated with the contents of the private <CODE>%hash</CODE> of this process. If a request happens to be served by a process that hasn't
  -yet <CODE>tie()d</CODE> the <CODE>%hash</CODE>, the dbm file will be initialized to the value of the <CODE>%hash</CODE> used by the process that last called <CODE>sync()</CODE> on the dbm file.
  -But if it is handled by a process that has already tied the <CODE>%hash</CODE>, it won't read the contents of the dbm file but will use its private value
  -of the
  -<CODE>%hash</CODE> instead.
  -
  -<P>
  -In reality things are even more complicated. The above scenario is true
  -only when the hash file is smaller than the buffer size of the dbm file.
  -When it becomes bigger than the buffer, its contents are flushed. When you
  -do <CODE>keys %hash</CODE>, all the keys will be brought from the dbm file which causes the process
  -to read the values saved by the previous <CODE>sync()</CODE> calls and
  -automatic flushes caused by buffer overflow.
  -
  -<P>
  -Which creates a whole big mess with the data and makes the whole idea is
  -useless.
  -
  -<P>
  -But if you have followed me this far, let's see what else is wrong with
  -this code. It's the <CODE>sync()</CODE> call. If the script somehow stops
  -before <CODE>sync()</CODE> is called, the dbm will be unlocked because <CODE>$fh</CODE>
  -is lexically scoped. But it won't be properly <CODE>sync()ed,</CODE> which
  -at some point will corrupt the dbm file.
  +If you are running under <CODE>Apache::Registry</CODE> and friends, the <CODE>END</CODE>
  +block will perform the cleanup work for you. You might use <CODE>END</CODE> in the same way for scripts running under mod_cgi, or in plain Perl
  +scripts. Just add the cleanup code to this block and you are safe.
   
   <P>
  -The solution is simple. Write an <CODE>END</CODE> block to sync the file:
  +For example if you work with dbm files just like with locking it's
  +important to flush the dbm buffers, by calling a <CODE>sync()</CODE>
  +method:
   
   <P>
   
  @@ -3266,6 +2768,12 @@
         </tr>
       </table>
       <P>
  +Normally the <CODE>END</CODE> blocks will not be executed after the completion of a request, but only
  +when an Apache child process exits, then if you are writing your own
  +handlers you will need to use the <CODE>register_cleanup()</CODE> function
  +to supply cleanup code similar to that used in <CODE>END</CODE> blocks instead of using <CODE>END</CODE> blocks.  
  +
  +<P>
   Under mod_perl, the above will work only for <CODE>Apache::Registry</CODE>
   scripts. Otherwise execution of the <CODE>END</CODE> block will be postponed until the process terminates. If you write a
   handler in the Perl API use the <CODE>register_cleanup()</CODE> method instead. It accepts a reference to a subroutine as an argument:
  @@ -6368,8 +5876,7 @@
         </tr>
       </table>
       <P>
  -At this point the server should die because of the call to
  -<CODE>dump().</CODE> When that happens we use <CODE>bt</CODE> or <CODE>where</CODE> to ask for a stack back trace.
  +At this point the server should die because of the call to <CODE>dump()</CODE>. When that happens we use <CODE>bt</CODE> or <CODE>where</CODE> to ask for a stack back trace.
   
   <P>
   
  @@ -6491,7 +5998,7 @@
         </tr>
       </table>
       <P>
  -<CODE>dump()</CODE> calls <CODE>__kill():</CODE>
  +<CODE>dump()</CODE> calls <CODE>__kill()</CODE>:
   
   <P>
   
  @@ -6686,9 +6193,8 @@
         </tr>
       </table>
       <P>
  -META: should I move the Apache::StatINC here? (I think not, since it
  -relates to other topics like reloading config files, but you should mention
  -it here with a pointer to it)
  +META: should I move the <CODE>Apache::StatINC</CODE> here? (I think not, since it relates to other topics like reloading config
  +files, but you should mention it here with a pointer to it)
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  @@ -7181,9 +6687,9 @@
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  -<CENTER><H1><A NAME="How_can_I_find_out_if_a_mod_perl">How can I find out if a mod_perl script has a memory leak</A></H1></CENTER>
  +<CENTER><H1><A NAME="How_can_I_find_out_if_a_mod_perl">How can I find out if a mod_perl code has a memory leak</A></H1></CENTER>
   <P>
  -<CODE>Apache::Leak</CODE> (derived from <CODE>Devel::Leak</CODE>) should help you with this task. Example:
  +The <CODE>Apache::Leak</CODE> module (derived from <CODE>Devel::Leak</CODE>) should help you detecting the leakages in your code. For example:
   
   <P>
   
  @@ -7195,7 +6701,9 @@
           </td>
   
   	<td>
  -	  <pre>  use Apache::Leak;
  +	  <pre>  leaktest.pl
  +  -----------
  +  use Apache::Leak;
     
     my $global = &quot;FooAAA&quot;;
     
  @@ -7240,8 +6748,9 @@
   <CODE>SUPPORT</CODE> doc for building <CODE>libperld.a</CODE>. When that is built, copy the <CODE>perl</CODE> from that directory to your Perl bin directory, but name it <CODE>dperl</CODE>.
   
   <P>
  -Leak explanation: <CODE>$$global = 1;</CODE> : new global variable created
  -<CODE>FooAAA</CODE> with value of <CODE>1</CODE>, this will not be destroyed until this module is destroyed.
  +Our example's leak explanation: <CODE>$$global = 1;</CODE> : new global variable
  +<CODE>FooAAA</CODE> created with value of <CODE>1</CODE>, this will not be destroyed until this module is destroyed. Under mod_perl
  +the module doesn't get destroyed until the process quits.
   
   <P>
   <CODE>Apache::Leak</CODE> is not very user-friendly, have a look at
  @@ -7288,13 +6797,8 @@
   <CODE>%hash</CODE> keys, and scratch areas of the pad-list for OPs such as
   <CODE>join()</CODE>, `<CODE>.</CODE>', etc.
   
  -<P>
  -<CODE>Apache::Status</CODE> now includes a new <CODE>StatusLexInfo</CODE> option.
  -
   <P>
  -<CODE>Apache::Leak</CODE> works better if you've built a <EM>libperld.a</EM> (see
  -<EM>SUPPORT</EM> document) and given <CODE>PERL_DEBUG=1</CODE> to mod_perl's
  -<CODE>Makefile.PL</CODE>.
  +<CODE>Apache::Status</CODE> includes a <CODE>StatusLexInfo</CODE> option which can show you the internals of your code.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  @@ -7502,7 +7006,7 @@
   <td align=center valign=center>
   
   <b><font size=-1>Written by <a
  -href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/30/2000
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 08/03/2000
   </font></b>
   <br>
   
  
  
  
  1.13      +16 -2     modperl-site/guide/download.html
  
  Index: download.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/download.html,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- download.html	2000/06/07 22:45:31	1.12
  +++ download.html	2000/08/05 20:48:05	1.13
  @@ -60,6 +60,7 @@
   
   	<LI><A HREF="#Apache_Request">Apache::Request</A>
   	<LI><A HREF="#DataBases">DataBases</A>
  +	<LI><A HREF="#libgtop">libgtop</A>
   </UL>
   
       </div>
  @@ -128,7 +129,7 @@
   <P>
   You can download most of the Perl modules from CPAN. There are many mirrors
   of this site. The main site's URL is <A
  -HREF="http://cpan.org/.">http://cpan.org/.</A>  
  +HREF="http://cpan.org/.">http://cpan.org/.</A>
   
   <P>
   You may want to search the Perl modules database by using <A
  @@ -363,6 +364,19 @@
   HREF="http://stason.org/TULARC/webmaster/db.html">http://stason.org/TULARC/webmaster/db.html</A>
   
   
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H1><A NAME="libgtop">libgtop</A></H1></CENTER>
  +<P>
  +LibGTop is a library that fetches system related information such as CPU
  +Load, Memory Usage and information about running processes. The module <CODE>GTop</CODE> provides a Perl interface to this library.
  +
  +<P>
  +<A
  +HREF="http://home-of-linux.org/gnome/libgtop/">http://home-of-linux.org/gnome/libgtop/</A>
  +
  +
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
   
  @@ -416,7 +430,7 @@
   <td align=center valign=center>
   
   <b><font size=-1>Written by <a
  -href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/26/2000
   </font></b>
   <br>
   
  
  
  
  1.29      +7 -5      modperl-site/guide/index.html
  
  Index: index.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/index.html,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- index.html	2000/06/07 22:45:31	1.28
  +++ index.html	2000/08/05 20:48:05	1.29
  @@ -22,7 +22,7 @@
         </p>
       </center>
   
  -    <center><p><b>Version 1.24 Jun 7, 2000</b></p></center>
  +    <center><p><b>Version 1.25 Aug 5, 2000</b></p></center>
    
   
       <table align=center width="70%">
  @@ -99,7 +99,7 @@
   <LI><A HREF="troubleshooting.html">Warnings and Errors Troubleshooting Index</A></LI>
   
   
  -<LI><A HREF="correct_headers.html">Correct Headers - A quick guide for mod_perl users</A></LI>
  +<LI><A HREF="correct_headers.html">Issuing Correct HTTP Headers</A></LI>
   
   
   <LI><A HREF="security.html">Protecting Your Site</A></LI>
  @@ -214,7 +214,9 @@
   	      Here is the <a href="http://perl.apache.org/guide/mod_perl_guide.pdf.gz"> Book-like
   		version </a> (PDF format). To read PDF files you can
   		use: <code>ghostview</code> (<code>gv</code>),
  -	      <code>xpdf</code> or <code>acroread</code>.  You can use the
  +	      <code>xpdf</code> or <code>acroread</code> (with
  +	      <code>acroread</code> you can search the text and us the
  +	      hyperlinks).  You can use the
   	      <code>pdf2ps</code> utility to convert PDF to
   	      PostSscript format.
   	    </li>
  @@ -304,7 +306,7 @@
   	    Full Version Master Copy URL: <a
   	    href="http://perl.apache.org/guide/"><b>http://perl.apache.org/guide</b></a><br>
   	    Copyright &copy; 1998-2000 Stas Bekman. All rights
  -	    reserved.
  +	    reserved. (Distributed under GPL license)
   	  </div>
   	</td>
         </tr>
  @@ -323,7 +325,7 @@
   	    <b><font size=-1>
   		Written by <a
   		  href="help.html#Contacting_me">Stas
  -		  Bekman</a>.<br> Last Modified at 06/07/2000
  +		  Bekman</a>.<br> Last Modified at 08/05/2000
   	      </font></b>
   	    <br>
   	    
  
  
  
  1.3       +33 -36    modperl-site/guide/index_long.html
  
  Index: index_long.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/index_long.html,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- index_long.html	2000/06/07 22:45:31	1.2
  +++ index_long.html	2000/08/05 20:48:05	1.3
  @@ -22,7 +22,7 @@
         </p>
       </center>
   
  -    <center><p><b>Version 1.24 Jun 7, 2000</b></p></center>
  +    <center><p><b>Version 1.25 Aug 5, 2000</b></p></center>
    
   
       <table align=center width="70%">
  @@ -137,6 +137,7 @@
   		<LI><A HREF="perl.html#Making_Variables_Global_With_str">Making Variables Global With strict Pragma On</A>
   		<LI><A HREF="perl.html#Using_Exporter_pm_to_Share_Globa">Using Exporter.pm to Share Global Variables</A>
   		<LI><A HREF="perl.html#Using_the_Perl_Aliasing_Feature_">Using the Perl Aliasing Feature to Share Global Variables</A>
  +		<LI><A HREF="perl.html#Using_Non_Hardcoded_Configuratio">Using Non-Hardcoded Configuration Module Names</A>
   	</UL>
   
   	<LI><A HREF="perl.html#The_Scope_of_the_Special_Perl_Va">The Scope of the Special Perl Variables</A>
  @@ -357,6 +358,11 @@
   	<UL>
   
   		<LI><A HREF="config.html#Alias_Configurations">Alias Configurations</A>
  +		<UL>
  +
  +			<LI><A HREF="config.html#Running_CGI_PerlRun_and_Regist">Running CGI, PerlRun, and Registry Scripts located in the same Directory</A>
  +		</UL>
  +
   		<LI><A HREF="config.html#_Location_Configuration">&lt;Location&gt; Configuration</A>
   		<LI><A HREF="config.html#Overriding_Location_Setting_in">Overriding &lt;Location&gt; Setting in &quot;Sub-Location&quot;</A>
   		<LI><A HREF="config.html#PerlModule_and_PerlRequire_Direc">PerlModule and PerlRequire Directives</A>
  @@ -447,6 +453,7 @@
   
   	</UL>
   
  +	<LI><A HREF="control.html#Swapping_Prevention">Swapping Prevention</A>
   	<LI><A HREF="control.html#Preventing_mod_perl_Processes_Fr">Preventing mod_perl Processes From Going Wild</A>
   	<UL>
   
  @@ -709,7 +716,6 @@
   
   		</UL>
   
  -		<LI><A HREF="performance.html#Memory_Swapping_is_Considered_Ba">Memory Swapping is Considered Bad</A>
   		<LI><A HREF="performance.html#Increasing_Shared_Memory_With_me">Increasing Shared Memory With mergemem</A>
   		<LI><A HREF="performance.html#Forking_and_Executing_Subprocess">Forking and Executing Subprocesses from mod_perl</A>
   		<UL>
  @@ -738,25 +744,16 @@
   		<LI><A HREF="performance.html#Reducing_the_Number_of_stat_Ca">Reducing the Number of stat() Calls Made by Apache</A>
   	</UL>
   
  -	<LI><A HREF="performance.html#TMTOWTDI_Convenience_and_Habit_">TMTOWTDI: Convenience and Habit versus Performance</A>
  +	<LI><A HREF="performance.html#TMTOWTDI_Convenience_and_Habit_">TMTOWTDI: Convenience and Habit vs. Performance</A>
   	<UL>
  -
  -		<LI><A HREF="performance.html#Apache_Registry_versus_pure_Per">Apache::Registry versus pure PerlHandler</A>
  -		<UL>
  -
  -			<LI><A HREF="performance.html#The_Light_Empty_Code">The Light (Empty) Code</A>
  -			<LI><A HREF="performance.html#The_Heavy_Code">The Heavy Code</A>
  -			<LI><A HREF="performance.html#Processing_and_Results">Processing and Results</A>
  -			<LI><A HREF="performance.html#Conclusions">Conclusions</A>
  -		</UL>
   
  -		<LI><A HREF="performance.html#CGI_pm_versus_Apache_Request">CGI.pm versus Apache::Request</A>
  +		<LI><A HREF="performance.html#Apache_Registry_PerlHandler_vs_">Apache::Registry PerlHandler vs. Custom PerlHandler</A>
   		<LI><A HREF="performance.html#_Bloatware_modules">&quot;Bloatware&quot; modules</A>
  -		<LI><A HREF="performance.html#Apache_args_versus_Apache_Requ">Apache::args versus Apache::Request::params</A>
  +		<LI><A HREF="performance.html#Apache_args_vs_Apache_Request">Apache::args vs. Apache::Request::param vs. CGI::param</A>
   		<LI><A HREF="performance.html#Using_1_Under_mod_perl_and_Be">Using $|=1 Under mod_perl and Better print() Techniques.</A>
  -		<LI><A HREF="performance.html#Global_vs_Fully_Qualified_Variab">Global vs Fully Qualified Variables </A>
  +		<LI><A HREF="performance.html#Global_vs_Fully_Qualified_Varia">Global vs. Fully Qualified Variables </A>
   		<LI><A HREF="performance.html#Avoid_Importing_Functions">Avoid Importing Functions</A>
  -		<LI><A HREF="performance.html#Object_Methods_Calls_Versus_Func">Object Methods Calls Versus Function Calls</A>
  +		<LI><A HREF="performance.html#Object_Methods_Calls_vs_Functio">Object Methods Calls vs. Function Calls</A>
   		<UL>
   
   			<LI><A HREF="performance.html#The_Overhead_with_Light_Subrouti">The Overhead with Light Subroutines</A>
  @@ -772,7 +769,7 @@
   	<LI><A HREF="performance.html#Apache_Registry_and_Derivatives">Apache::Registry and Derivatives Specific Notes</A>
   	<UL>
   
  -		<LI><A HREF="performance.html#Be_carefull_with_symbolic_links">Be carefull with symbolic links</A>
  +		<LI><A HREF="performance.html#Be_Careful_with_Symbolic_Links">Be Careful with Symbolic Links</A>
   	</UL>
   
   	<LI><A HREF="performance.html#Improving_Performance_by_Prevent">Improving Performance by Prevention</A>
  @@ -786,13 +783,12 @@
   			<LI><A HREF="performance.html#Work_With_Databases">Work With Databases</A>
   		</UL>
   
  -		<LI><A HREF="performance.html#Limiting_the_Size_of_the_Process">Limiting the Size of the Processes</A>
   		<LI><A HREF="performance.html#Keeping_the_Shared_Memory_Limit">Keeping the Shared Memory Limit</A>
  -		<LI><A HREF="performance.html#Limiting_the_Resources_Used_by_h">Limiting the Resources Used by httpd Children</A>
  +		<LI><A HREF="performance.html#Limiting_the_Size_of_the_Process">Limiting the Size of the Processes</A>
  +		<LI><A HREF="performance.html#Limiting_Other_Resources_Used_by">Limiting Other Resources Used by Apache Child Processes</A>
   		<UL>
   
   			<LI><A HREF="performance.html#OS_Specific_notes">OS Specific notes</A>
  -			<LI><A HREF="performance.html#Debug">Debug</A>
   		</UL>
   
   		<LI><A HREF="performance.html#Limiting_the_Number_of_Processes">Limiting the Number of Processes Serving the Same Resource</A>
  @@ -923,22 +919,21 @@
   
   </UL>
   <P>
  -<LI><A HREF="correct_headers.html"><B><FONT SIZE=+1>Correct Headers - A quick guide for mod_perl users</FONT></B></A></LI><P>
  +<LI><A HREF="correct_headers.html"><B><FONT SIZE=+1>Issuing Correct HTTP Headers</FONT></B></A></LI><P>
   <UL>
   
  -	<LI><A HREF="correct_headers.html#Correct_Headers_A_quick_guide_">Correct Headers - A quick guide for mod_perl users</A>
   	<LI><A HREF="correct_headers.html#SYNOPSIS">SYNOPSIS</A>
  -	<LI><A HREF="correct_headers.html#The_origin_of_this_chapter">The origin of this chapter</A>
  +	<LI><A HREF="correct_headers.html#The_Origin_of_this_Chapter">The Origin of this Chapter</A>
   	<LI><A HREF="correct_headers.html#DESCRIPTION">DESCRIPTION</A>
  -	<LI><A HREF="correct_headers.html#1_Why_headers">1) Why headers</A>
  +	<LI><A HREF="correct_headers.html#1_Why_Headers">1) Why Headers</A>
   	<LI><A HREF="correct_headers.html#2_Which_Headers">2) Which Headers</A>
   	<UL>
   
  -		<LI><A HREF="correct_headers.html#2_1_Date_related_headers">2.1) Date related headers</A>
  +		<LI><A HREF="correct_headers.html#2_1_Date_Related_Headers">2.1) Date Related Headers</A>
   		<LI><A HREF="correct_headers.html#2_1_1_Date">2.1.1) Date</A>
   		<LI><A HREF="correct_headers.html#2_1_2_Last_Modified">2.1.2) Last-Modified</A>
   		<LI><A HREF="correct_headers.html#2_1_3_Expires_and_Cache_Control">2.1.3) Expires and Cache-Control</A>
  -		<LI><A HREF="correct_headers.html#2_2_Content_related_headers">2.2) Content related headers</A>
  +		<LI><A HREF="correct_headers.html#2_2_Content_Related_Headers">2.2) Content Related Headers</A>
   		<LI><A HREF="correct_headers.html#2_2_1_Content_Type">2.2.1) Content-Type</A>
   		<LI><A HREF="correct_headers.html#2_2_2_Content_Length">2.2.2) Content-Length</A>
   		<LI><A HREF="correct_headers.html#2_2_3_Entity_Tags">2.2.3) Entity Tags</A>
  @@ -953,10 +948,10 @@
   		<LI><A HREF="correct_headers.html#3_2_POST">3.2) POST</A>
   		<LI><A HREF="correct_headers.html#3_3_GET">3.3) GET</A>
   		<LI><A HREF="correct_headers.html#3_4_Conditional_GET">3.4) Conditional GET</A>
  -		<LI><A HREF="correct_headers.html#3_Avoiding_dealing_with_them">3.) Avoiding dealing with them</A>
   	</UL>
   
  -	<LI><A HREF="correct_headers.html#References_and_other_literature">References and other literature</A>
  +	<LI><A HREF="correct_headers.html#4_Avoiding_Dealing_with_Header">4.) Avoiding Dealing with Headers</A>
  +	<LI><A HREF="correct_headers.html#References">References</A>
   	<UL>
   
   		<LI><A HREF="correct_headers.html#_1_">[1]</A>
  @@ -966,8 +961,6 @@
   		<LI><A HREF="correct_headers.html#_5_">[5]</A>
   	</UL>
   
  -	<LI><A HREF="correct_headers.html#VERSION">VERSION</A>
  -	<LI><A HREF="correct_headers.html#AUTHOR">AUTHOR</A>
   </UL>
   <P>
   <LI><A HREF="security.html"><B><FONT SIZE=+1>Protecting Your Site</FONT></B></A></LI><P>
  @@ -987,6 +980,7 @@
   		<LI><A HREF="security.html#OK_AUTH_REQUIRED_and_FORBIDDEN_">OK, AUTH_REQUIRED and FORBIDDEN in Authentication handlers</A>
   	</UL>
   
  +	<LI><A HREF="security.html#Apache_Auth_modules">Apache:Auth* modules</A>
   </UL>
   <P>
   <LI><A HREF="databases.html"><B><FONT SIZE=+1>mod_perl and Relational Databases</FONT></B></A></LI><P>
  @@ -1085,8 +1079,7 @@
   		<UL>
   
   			<LI><A HREF="debug.html#Critical_Section">Critical Section</A>
  -			<LI><A HREF="debug.html#Safe_Resource_Locking">Safe Resource Locking</A>
  -			<LI><A HREF="debug.html#Cleanup_Code">Cleanup Code</A>
  +			<LI><A HREF="debug.html#Safe_Resource_Locking_and_Cleanu">Safe Resource Locking and Cleanup Code</A>
   		</UL>
   
   	</UL>
  @@ -1139,7 +1132,7 @@
   	<LI><A HREF="debug.html#Debugging_Signal_Handlers_SIG_">Debugging Signal Handlers ($SIG{FOO})</A>
   	<LI><A HREF="debug.html#Code_Profiling">Code Profiling</A>
   	<LI><A HREF="debug.html#Devel_Peek">Devel::Peek</A>
  -	<LI><A HREF="debug.html#How_can_I_find_out_if_a_mod_perl">How can I find out if a mod_perl script has a memory leak</A>
  +	<LI><A HREF="debug.html#How_can_I_find_out_if_a_mod_perl">How can I find out if a mod_perl code has a memory leak</A>
   	<LI><A HREF="debug.html#Debugging_your_code_in_Single_Se">Debugging your code in Single Server Mode</A>
   	<LI><A HREF="debug.html#Apache_DumpHeaders_Watch_HTTP">Apache::DumpHeaders - Watch HTTP Transaction Via Headers</A>
   	<LI><A HREF="debug.html#Apache_DebugInfo_Log_Various_">Apache::DebugInfo - Log Various Bits Of Per-Request Data</A>
  @@ -1206,6 +1199,7 @@
   	<LI><A HREF="snippets.html#SSI_and_Embperl_Doing_Both">SSI and Embperl -- Doing Both</A>
   	<LI><A HREF="snippets.html#Getting_the_Front_end_Server_s_N">Getting the Front-end Server's Name in the Back-end Server</A>
   	<LI><A HREF="snippets.html#Authentication_Snippets">Authentication Snippets</A>
  +	<LI><A HREF="snippets.html#An_example_of_using_Apache_Sess">An example of using Apache::Session::DBI with cookies</A>
   	<LI><A HREF="snippets.html#Using_DESTROY_to_Finalize_Output">Using DESTROY to Finalize Output</A>
   	<LI><A HREF="snippets.html#Setting_Environment_Variables_Fo">Setting Environment Variables For Scripts Called From CGI.</A>
   	<LI><A HREF="snippets.html#Mysql_Backup_and_Restore_Scripts">Mysql Backup and Restore Scripts</A>
  @@ -1302,6 +1296,7 @@
   
   	<LI><A HREF="download.html#Apache_Request">Apache::Request</A>
   	<LI><A HREF="download.html#DataBases">DataBases</A>
  +	<LI><A HREF="download.html#libgtop">libgtop</A>
   </UL>
   <P>
   	  </div>
  @@ -1380,7 +1375,9 @@
   	      Here is the <a href="http://perl.apache.org/guide/mod_perl_guide.pdf.gz"> Book-like
   		version </a> (PDF format). To read PDF files you can
   		use: <code>ghostview</code> (<code>gv</code>),
  -	      <code>xpdf</code> or <code>acroread</code>.  You can use the
  +	      <code>xpdf</code> or <code>acroread</code> (with
  +	      <code>acroread</code> you can search the text and us the
  +	      hyperlinks).  You can use the
   	      <code>pdf2ps</code> utility to convert PDF to
   	      PostSscript format.
   	    </li>
  @@ -1470,7 +1467,7 @@
   	    Full Version Master Copy URL: <a
   	    href="http://perl.apache.org/guide/"><b>http://perl.apache.org/guide</b></a><br>
   	    Copyright &copy; 1998-2000 Stas Bekman. All rights
  -	    reserved.
  +	    reserved. (Distributed under GPL license)
   	  </div>
   	</td>
         </tr>
  @@ -1489,7 +1486,7 @@
   	    <b><font size=-1>
   		Written by <a
   		  href="help.html#Contacting_me">Stas
  -		  Bekman</a>.<br> Last Modified at 06/07/2000
  +		  Bekman</a>.<br> Last Modified at 08/05/2000
   	      </font></b>
   	    <br>
   	    
  
  
  
  1.16      +23 -21    modperl-site/guide/install.html
  
  Index: install.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/install.html,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- install.html	2000/06/07 22:45:32	1.15
  +++ install.html	2000/08/05 20:48:05	1.16
  @@ -334,13 +334,13 @@
   <P>
   Since mod_perl can be configured in many different ways (features can be
   enabled or disabled, directories can be modified, etc.) it's preferable to
  -use a manual installation, as a prepackaged version might not suite your
  +use a manual installation, as a prepackaged version might not suit your
   needs. Manual installation will allow you to make the fine tuning for the
   best performance as well.
   
   <P>
  -We will talk in extension about the prepackaged versions and scenarios to
  -prepare your own packages for reuse on many machines in this chapter.
  +In this chapter we will talk extensively about the prepackaged versions,
  +and ways to prepare your own packages for reuse on many machines.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  @@ -4512,7 +4512,7 @@
   <CENTER><H1><A NAME="Installation_Without_Superuser_P">Installation Without Superuser Privileges</A></H1></CENTER>
   <P>
   As you have already learned, mod_perl enabled Apache consists of two main
  -components: perl modules and Apache itself. Let's tackle the tasks one at a
  +components: Perl modules and Apache itself. Let's tackle the tasks one at a
   time.
   
   <P>
  @@ -4802,7 +4802,7 @@
   different names.
   
   <P>
  -I also have a perl-5.00561 installed under <CODE>/usr/local/lib/</CODE>
  +I also have a perl-5.6.0 installed under <CODE>/usr/local/lib/</CODE>
   so when I do:
   
   <P>
  @@ -4815,7 +4815,7 @@
           </td>
   
   	<td>
  -	  <pre>  % /usr/local/bin/perl5.00561 -V</pre>
  +	  <pre>  % /usr/local/bin/perl5.6.0 -V</pre>
           </td>
   	    
         </tr>
  @@ -4834,9 +4834,9 @@
   
   	<td>
   	  <pre>  @INC:
  -    /usr/local/lib/perl5/5.00561/i586-linux
  -    /usr/local/lib/perl5/5.00561
  -    /usr/local/lib/site_perl/5.00561/i586-linux
  +    /usr/local/lib/perl5/5.6.0/i586-linux
  +    /usr/local/lib/perl5/5.6.0
  +    /usr/local/lib/site_perl/5.6.0/i586-linux
       /usr/local/lib/site_perl</pre>
           </td>
   	    
  @@ -5034,7 +5034,8 @@
     Built under linux
     Compiled at Apr  6 1999 23:34:07
     %ENV:
  -    PERL5LIB=&quot;/home/stas/lib/perl5/5.00503:/home/stas/lib/perl5/site_perl/5.005&quot;
  +    PERL5LIB=&quot;/home/stas/lib/perl5/5.00503:
  +    /home/stas/lib/perl5/site_perl/5.005&quot;
     @INC:
       /home/stas/lib/perl5/5.00503/i386-linux
       /home/stas/lib/perl5/5.00503
  @@ -5130,7 +5131,8 @@
           </td>
   
   	<td>
  -	  <pre>  % cp /usr/lib/perl5/5.00503/CPAN/Config.pm /home/stas/.cpan/CPAN/MyConfig.pm</pre>
  +	  <pre>  % cp /usr/lib/perl5/5.00503/CPAN/Config.pm \
  +    /home/stas/.cpan/CPAN/MyConfig.pm</pre>
           </td>
   	    
         </tr>
  @@ -5149,7 +5151,8 @@
           </td>
   
   	<td>
  -	  <pre>  % perl -pi -e 's|/usr/src|/home/stas|' /home/stas/.cpan/CPAN/MyConfig.pm</pre>
  +	  <pre>  % perl -pi -e 's|/usr/src|/home/stas|' \
  +  /home/stas/.cpan/CPAN/MyConfig.pm</pre>
           </td>
   	    
         </tr>
  @@ -5486,15 +5489,14 @@
         </tr>
       </table>
       <P>
  -Note that the above multiline splitting will work only with <CODE>bash</CODE>,
  -<CODE>tcsh</CODE> users will have to list all the parameters on a single line.
  +Note that the above multiline splitting will work only with
  +<CODE>(ba)?sh</CODE>, <CODE>t?csh</CODE> users will have to list all the parameters on a single line.
   
   <P>
   Basically the installation is complete. The only remaining problem is the <CODE>@INC</CODE> variable. This won't be correctly set if you rely on the
   <CODE>PERL5LIB</CODE> environment variable unless you set it explicitly in a startup file which
   is <CODE>require</CODE>'d before loading any other module that resides in your local repository. A
  -much nicer approach is to use the
  -<CODE>lib</CODE> pragma as we saw before, but in a slightly different way - we use it in the
  +much nicer approach is to use the <CODE>lib</CODE> pragma as we saw before, but in a slightly different way--we use it in the
   startup file and it affects all the code that will be executed under
   mod_perl handlers. For example:
   
  @@ -5551,13 +5553,14 @@
           </td>
   
   	<td>
  -	  <pre>  PerlSetEnv Perl5LIB /home/stas/lib/perl5/5.00503/:/home/stas/lib/perl5/site_perl/5.005</pre>
  +	  <pre>  PerlSetEnv Perl5LIB \
  +  /home/stas/lib/perl5/5.00503/:/home/stas/lib/perl5/site_perl/5.005</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -in <EM>httpd.conf</EM>.
  +in <EM>httpd.conf</EM>, but the latter setting will be ignored if you use the <CODE>PerlTaintcheck</CODE> setting, and I hope you do use it.
   
   <P>
   The rest of the mod_perl configuration and use is just the same as if you
  @@ -5816,8 +5819,7 @@
       </table>
       <P>
   Not so neat, but a working solution. You could have written the value on a
  -piece of paper instead of saving it to makepl_arg.save, but you are more
  -likely to make a mistake that way.
  +piece of paper instead of saving it to <CODE>makepl_arg.save</CODE>, but you are more likely to make a mistake that way.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  @@ -6481,7 +6483,7 @@
   <td align=center valign=center>
   
   <b><font size=-1>Written by <a
  -href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/31/2000
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 08/03/2000
   </font></b>
   <br>
   
  
  
  
  1.23      +2 -4      modperl-site/guide/intro.html
  
  Index: intro.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/intro.html,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- intro.html	2000/06/07 22:45:32	1.22
  +++ intro.html	2000/08/05 20:48:05	1.23
  @@ -793,9 +793,7 @@
   <P><LI><STRONG><A NAME="item_Philip">Philip Jacob</A></STRONG>
   <P><LI><STRONG><A NAME="item_Philip">Philip Newton</A></STRONG>
   <P><LI><STRONG><A NAME="item_Radu">Radu Greab</A></STRONG>
  -<P><LI><STRONG>Radu Greab</STRONG>
   <P><LI><STRONG><A NAME="item_Ralf">Ralf Engelschall</A></STRONG>
  -<P><LI><STRONG><A NAME="item_Ralf">Ralf S. Engelschall</A></STRONG>
   <P><LI><STRONG><A NAME="item_Randal">Randal L. Schwartz</A></STRONG>
   <P><LI><STRONG><A NAME="item_Randy">Randy Harmon</A></STRONG>
   <P><LI><STRONG><A NAME="item_Randy">Randy Kobes</A></STRONG>
  @@ -808,7 +806,7 @@
   <P><LI><STRONG><A NAME="item_Robin">Robin Berjon</A></STRONG>
   <P><LI><STRONG><A NAME="item_Scott">Scott Fagg</A></STRONG>
   <P><LI><STRONG><A NAME="item_Sean">Sean Dague</A></STRONG>
  -<P><LI><STRONG><A NAME="item_Shane">Shane shane@isupportlive.com</A></STRONG>
  +<P><LI><STRONG><A NAME="item_Shane">Shane</A></STRONG>
   <P><LI><STRONG><A NAME="item_Stephane">Stephane Benoit</A></STRONG>
   <P><LI><STRONG><A NAME="item_Stephen">Stephen Judd</A></STRONG>
   <P><LI><STRONG><A NAME="item_Steve">Steve Reppucci</A></STRONG>
  @@ -887,7 +885,7 @@
   <td align=center valign=center>
   
   <b><font size=-1>Written by <a
  -href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/07/2000
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/26/2000
   </font></b>
   <br>
   
  
  
  
  1.6       +4743 -4977modperl-site/guide/mod_perl_guide.pdf.gz
  
  	<<Binary file>>
  
  
  1.17      +35 -159   modperl-site/guide/modules.html
  
  Index: modules.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/modules.html,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- modules.html	2000/06/07 22:45:35	1.16
  +++ modules.html	2000/08/05 20:48:07	1.17
  @@ -96,9 +96,10 @@
   <P>
   <CENTER><H1><A NAME="Apache_Session_Maintain_sessi">Apache::Session - Maintain session state across HTTP requests</A></H1></CENTER>
   <P>
  -This module provides the Apache/mod_perl user a mechanism for storing
  -persistent user data in a global hash, which is independent of its real
  -storage mechanism. Currently you can choose from these storage mechanisms <CODE>Apache::Session::DBI</CODE>, <CODE>Apache::Session::Win32</CODE>,
  +This module provides the Apache/mod_perl user with a mechanism for storing
  +persistent user data in a global hash, which is independent of the
  +underlying storage mechanism. Currently you can choose from these storage
  +mechanisms <CODE>Apache::Session::DBI</CODE>, <CODE>Apache::Session::Win32</CODE>,
   <CODE>Apache::Session::File</CODE>, <CODE>Apache::Session::IPC</CODE>. Read the man page of the mechanism you want to use for a complete
   reference.
   
  @@ -205,18 +206,18 @@
       </table>
       <P>
   After setting this up, you can stick anything you want into
  -<CODE>%session</CODE> (except file handles), and it will still be there
  -when the user invokes the next page.
  +<CODE>%session</CODE> (except file handles and code references), and it
  +will still be there when the user invokes the next page.
   
   <P>
  -It is possible to write an Apache authen handler using
  +It is possible to write an Apache authentication handler using
   <CODE>Apache::Session</CODE>. You can put your authentication token into the session. When a user
   invokes a page, you open their session, check to see if they have a valid
  -token, and approve or deny their authorization based on that.
  +token, and authenticate or forbid based on that.
   
   <P>
  -As for IIS, let's compare. IIS's sessions are only valid on the same web
  -server as the one that issued the session.
  +By way of comparison note that IIS's sessions are only valid on the same
  +web server as the one that issued the session.
   <CODE>Apache::Session</CODE>'s session objects can be shared amongst a farm of many machines running
   different operating systems, including even Win32. IIS stores session
   information in RAM.  <CODE>Apache::Session</CODE>
  @@ -250,7 +251,7 @@
   <EM>run away</EM>.
   
   <P>
  -When the process is considered as <EM>hanging</EM> it will be killed and the event logged into a log file.
  +When the process is considered to be <EM>hanging</EM> it will be killed and the event logged in a log file.
   
   <P>
   Generally you should use the <CODE>amprapmon</CODE> program that is bundled with this module's distribution package, but you
  @@ -346,7 +347,7 @@
         </tr>
       </table>
       <P>
  -More information available in the module's extensive manpage.
  +More information is available in the module's extensive manpage.
   
   <P>
   It requires <CODE>Apache::Scoreboard</CODE> and <CODE>GTop</CODE> to work.  <CODE>GTop</CODE> in turn requires the <CODE>libgtop</CODE> library but is not available for all platforms. Visit <A
  @@ -363,142 +364,21 @@
   process size limiter to check the process size on every request:
   
   <P>
  +The module is thoroughly explained in the sections: ``<A HREF="././performance.html#Keeping_the_Shared_Memory_Limit">Keeping the Shared Memory Limit</A>'' and ``<A HREF="././performance.html#Limiting_the_Size_of_the_Process">Limiting the Size of the Processes</A>''
   
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>    # in your startup.pl:
  -    use Apache::GTopLimit;
  -  
  -    # Control the life based on memory size
  -    # in KB, so this is 10MB
  -    $Apache::GTopLimit::MAX_PROCESS_SIZE = 10000;
  -  
  -    # Control the life based on Shared memory size
  -    # in KB, so this is 4MB
  -    $Apache::GTopLimit::MIN_PROCESS_SHARED_SIZE = 4000;
  -  
  -    # watch what happens  
  -    $Apache::GTopLimit::DEBUG = 1;
  -  
  -    # in your httpd.conf:   
  -    PerlFixupHandler Apache::GTopLimit
  -    # you can set this up as any Perl*Handler that handles
  -    # part of the request, even the LogHandler will do.</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -Or you can just check those requests that are likely to get big or
  -unshared. This way of checking is also easier for those who are mostly just
  -running Apache::Registry scripts:
  -
   <P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>    # in your CGI:
  -    use Apache::GTopLimit;  
  -      # Max Process Size in KB
  -    Apache::GTopLimit-&gt;set_max_size(10000);</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -and/or:
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>    use Apache::GTopLimit;
  -       # Min Shared process Size in KB
  -    Apache::GTopLimit-&gt;set_min_shared_size(4000);</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -Since accessing the process info might add a little overhead, you may want
  -to only check the process size every N times. To do so, put this in your <EM>startup.pl</EM> or your code:
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>    $Apache::GTopLimit::CHECK_EVERY_N_REQUESTS = 2;</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -This will only check the process size every other time the process size
  -checker is called.
  -
  -<P>
  -This module was written in response to questions on the mod_perl mailing
  -list on how to tell the httpd process to exit if:
  -
  -<UL>
  -<P><LI>
  -<P>
  -its memory size goes beyond a specified limit
  -
  -<P><LI>
  -<P>
  -its shared memory size goes below a specified limit
  -
  -</UL>
  -<P>
  -Note: This module will run on platforms supported by <STRONG>GTop.pm</STRONG> a Perl interface to libgtop (which of course needs <STRONG>libgtop</STRONG> : See <A
  -HREF="http://home-of-linux.org/gnome/libgtop/">http://home-of-linux.org/gnome/libgtop/</A>
  -).
  -
  -<P>
  -Referer to the <CODE>Apache::GTopLimit</CODE> manpage for more information.
  -
  -<P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
   <CENTER><H1><A NAME="Apache_Request_libapreq_Gen">Apache::Request (libapreq) - Generic Apache Request Library</A></H1></CENTER>
   <P>
   This package contains modules for manipulating client request data via the
   Apache API with Perl and C. Functionality includes:
  -
  -<P>
  -- parsing of application/x-www-form-urlencoded data
  -
  -<P>
  -- parsing of multipart/form-data
  -
  -<P>
  -- parsing of HTTP Cookies
   
  +<DL>
  +<P><DT><STRONG><A NAME="item_parsing">parsing of application/x-www-form-urlencoded data</A></STRONG><DD>
  +<P><DT><STRONG>parsing of multipart/form-data</STRONG><DD>
  +<P><DT><STRONG>parsing of HTTP Cookies</STRONG><DD>
  +</DL>
   <P>
   The Perl modules are simply a thin xs layer on top of libapreq, making them
   a lighter and faster alternative to CGI.pm and CGI::Cookie. See the <CODE>Apache::Request</CODE> and <CODE>Apache::Cookie</CODE> documentation for more details and eg/perl/ for examples.
  @@ -518,8 +398,7 @@
   <CODE>Apache::RequestNotes</CODE> provides a simple interface allowing all phases of the request cycle access
   to cookie or form input parameters in a consistent manner. Behind the
   scenes, it uses libapreq
  -<A HREF="././modules.html#Apache_Request_libapreq_Gen">Apache::Request</A>&gt;) functions to parse request data and puts references to the data in
  -pnotes.
  +<A HREF="././modules.html#Apache_Request_libapreq_Gen">Apache::Request</A>&gt;) functions to parse request data and puts references to the data in <CODE>pnotes()</CODE>.
   
   <P>
   Once the request is past the PerlInit phase, all other phases can have
  @@ -542,7 +421,7 @@
   <HR>
   <CENTER><H1><A NAME="Apache_RegistryNG_Apache_Re">Apache::RegistryNG -- Apache::Registry New Generation</A></H1></CENTER>
   <P>
  -<CODE>Apache::RegistryNG</CODE> is the same as <CODE>Apache::Registry</CODE>, aside from using filename instead of URI for the namespace. It also uses
  +<CODE>Apache::RegistryNG</CODE> is the same as <CODE>Apache::Registry</CODE>, aside from using filenames instead of URIs for namespaces. It also uses
   an Object Oriented interface.
   
   <P>
  @@ -609,7 +488,7 @@
   <P>
   It works just like <CODE>Apache::Registry</CODE>, but does not test the x bit (-x) only compiles the file once (no
   <CODE>stat()</CODE> call is made per requsest), skips the OPT_EXECCGI
  -checks and does not <A HREF="#item_chdir">chdir()</A> into the script parent directory. It uses the Object Oriented interface.
  +checks and does not <CODE>chdir()</CODE> into the script parent directory. It uses the Object Oriented interface.
   
   <P>
   Configuration:
  @@ -719,9 +598,9 @@
   Have you ever served a huge HTML file (e.g. a file bloated with JavaScript
   code) and wondered how could you send it compressed, thus dramatically
   cutting down the download times? After all java applets can be compressed
  -into a jar and benefit from a faster download times. Why can't we do the
  -same with a plain ASCII (HTML, JS etc.)? ASCII text can often be compressed
  -by a factor of 10. 
  +into a jar and benefit from faster download times. Why can't we do the same
  +with plain ASCII (HTML, JS etc.)? ASCII text can often be compressed by a
  +factor of 10.
   
   <P>
   <CODE>Apache::GzipChain</CODE> comes to help you with this task. If a client (browser) understands <CODE>gzip</CODE> encoding, this module compresses the output and sends it downstream. The
  @@ -751,7 +630,7 @@
       </table>
       <P>
   Remember that it will work only if the browser claims to accept compressed
  -input, by setting the <CODE>Accept-Encoding</CODE> header.  
  +input, by setting the <CODE>Accept-Encoding</CODE> header.
   <CODE>Apache::GzipChain</CODE> keeps a list of user-agents, thus it also looks at the <CODE>User-Agent</CODE> header to check for browsers known to accept compressed output.
   
   <P>
  @@ -857,7 +736,7 @@
   Will compess the output of the <CODE>Apache::Registry</CODE> scripts. Yes, you should write <CODE>Apache::RegistryFilter</CODE> and not <CODE>Apache::Registry</CODE>.
   
   <P>
  -You can put as many filters as you want:
  +You can use as many filters as you want:
   
   <P>
   
  @@ -880,7 +759,8 @@
         </tr>
       </table>
       <P>
  -You can test that it works by either looking at the size of the respond at <EM>access.log</EM> or by telnet:
  +You can test that it works by either looking at the size of the response in
  +the <EM>access.log</EM> or by telnet:
   
   <P>
   
  @@ -907,9 +787,6 @@
   And you will get the data compressed if configured correctly.
   
   <P>
  -META: what the full mime type for gzip?
  -
  -<P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
   <CENTER><H1><A NAME="Apache_PerlVINC_set_a_differe">Apache::PerlVINC - set a different @INC perl-location</A></H1></CENTER>
  @@ -948,8 +825,8 @@
       SetHandler perl-script
       PerlHandler Apache::Status
     
  -    PerlINC /home/dougm/dev/modperl/lib
       PerlVersionINC On
  +    PerlINC /home/dougm/dev/modperl/lib
       PerlFixupHandler Apache::PerlVINC
       PerlRequire Apache/Status.pm
     &lt;/Location&gt;</pre>
  @@ -971,8 +848,8 @@
       SetHandler perl-script
       PerlHandler Apache::Status
     
  -    PerlINC /home/other/current/modperl/lib
       PerlVersionINC On
  +    PerlINC /home/other/current/modperl/lib
       PerlFixupHandler Apache::PerlVINC
       PerlRequire Apache/Status.pm
     &lt;/Location&gt;</pre>
  @@ -981,6 +858,10 @@
         </tr>
       </table>
       <P>
  +<CODE>PerlVersionINC On</CODE> must come before the <CODE>PerlINC</CODE>
  +statement. <CODE>PerlINC</CODE> wont store that path unless <CODE>PerlVersionINC</CODE> is On.
  +
  +<P>
   It's important to be aware that a changed <CODE>@INC</CODE> is effective only inside the <CODE>&lt;Location&gt;</CODE> or a similar configuration directive.
   <CODE>Apache::PerlVINC</CODE> subclasses the <CODE>PerlRequire</CODE> directive, marking the file to be reloaded by the fixup handler, using the
   value of
  @@ -992,11 +873,6 @@
   namespace. This is not a good idea in a high load environment, of course.
   
   <P>
  -If you can't find it on CPAN, get it at: <A
  -HREF="http://perl.apache.org/~dougm/Apache-PerlVINC-0.01.tar.gz">http://perl.apache.org/~dougm/Apache-PerlVINC-0.01.tar.gz</A>
  -
  -
  -<P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
   <CENTER><H1><A NAME="Apache_LogSTDERR">Apache::LogSTDERR</A></H1></CENTER>
  @@ -1239,7 +1115,7 @@
   <td align=center valign=center>
   
   <b><font size=-1>Written by <a
  -href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/01/2000
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 08/05/2000
   </font></b>
   <br>
   
  
  
  
  1.28      +818 -798  modperl-site/guide/performance.html
  
  Index: performance.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/performance.html,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- performance.html	2000/06/07 22:45:35	1.27
  +++ performance.html	2000/08/05 20:48:07	1.28
  @@ -78,7 +78,6 @@
   
   		</UL>
   
  -		<LI><A HREF="#Memory_Swapping_is_Considered_Ba">Memory Swapping is Considered Bad</A>
   		<LI><A HREF="#Increasing_Shared_Memory_With_me">Increasing Shared Memory With mergemem</A>
   		<LI><A HREF="#Forking_and_Executing_Subprocess">Forking and Executing Subprocesses from mod_perl</A>
   		<UL>
  @@ -107,25 +106,16 @@
   		<LI><A HREF="#Reducing_the_Number_of_stat_Ca">Reducing the Number of stat() Calls Made by Apache</A>
   	</UL>
   
  -	<LI><A HREF="#TMTOWTDI_Convenience_and_Habit_">TMTOWTDI: Convenience and Habit versus Performance</A>
  +	<LI><A HREF="#TMTOWTDI_Convenience_and_Habit_">TMTOWTDI: Convenience and Habit vs. Performance</A>
   	<UL>
   
  -		<LI><A HREF="#Apache_Registry_versus_pure_Per">Apache::Registry versus pure PerlHandler</A>
  -		<UL>
  -
  -			<LI><A HREF="#The_Light_Empty_Code">The Light (Empty) Code</A>
  -			<LI><A HREF="#The_Heavy_Code">The Heavy Code</A>
  -			<LI><A HREF="#Processing_and_Results">Processing and Results</A>
  -			<LI><A HREF="#Conclusions">Conclusions</A>
  -		</UL>
  -
  -		<LI><A HREF="#CGI_pm_versus_Apache_Request">CGI.pm versus Apache::Request</A>
  +		<LI><A HREF="#Apache_Registry_PerlHandler_vs_">Apache::Registry PerlHandler vs. Custom PerlHandler</A>
   		<LI><A HREF="#_Bloatware_modules">&quot;Bloatware&quot; modules</A>
  -		<LI><A HREF="#Apache_args_versus_Apache_Requ">Apache::args versus Apache::Request::params</A>
  +		<LI><A HREF="#Apache_args_vs_Apache_Request">Apache::args vs. Apache::Request::param vs. CGI::param</A>
   		<LI><A HREF="#Using_1_Under_mod_perl_and_Be">Using $|=1 Under mod_perl and Better print() Techniques.</A>
  -		<LI><A HREF="#Global_vs_Fully_Qualified_Variab">Global vs Fully Qualified Variables </A>
  +		<LI><A HREF="#Global_vs_Fully_Qualified_Varia">Global vs. Fully Qualified Variables </A>
   		<LI><A HREF="#Avoid_Importing_Functions">Avoid Importing Functions</A>
  -		<LI><A HREF="#Object_Methods_Calls_Versus_Func">Object Methods Calls Versus Function Calls</A>
  +		<LI><A HREF="#Object_Methods_Calls_vs_Functio">Object Methods Calls vs. Function Calls</A>
   		<UL>
   
   			<LI><A HREF="#The_Overhead_with_Light_Subrouti">The Overhead with Light Subroutines</A>
  @@ -141,7 +131,7 @@
   	<LI><A HREF="#Apache_Registry_and_Derivatives">Apache::Registry and Derivatives Specific Notes</A>
   	<UL>
   
  -		<LI><A HREF="#Be_carefull_with_symbolic_links">Be carefull with symbolic links</A>
  +		<LI><A HREF="#Be_Careful_with_Symbolic_Links">Be Careful with Symbolic Links</A>
   	</UL>
   
   	<LI><A HREF="#Improving_Performance_by_Prevent">Improving Performance by Prevention</A>
  @@ -155,13 +145,12 @@
   			<LI><A HREF="#Work_With_Databases">Work With Databases</A>
   		</UL>
   
  -		<LI><A HREF="#Limiting_the_Size_of_the_Process">Limiting the Size of the Processes</A>
   		<LI><A HREF="#Keeping_the_Shared_Memory_Limit">Keeping the Shared Memory Limit</A>
  -		<LI><A HREF="#Limiting_the_Resources_Used_by_h">Limiting the Resources Used by httpd Children</A>
  +		<LI><A HREF="#Limiting_the_Size_of_the_Process">Limiting the Size of the Processes</A>
  +		<LI><A HREF="#Limiting_Other_Resources_Used_by">Limiting Other Resources Used by Apache Child Processes</A>
   		<UL>
   
   			<LI><A HREF="#OS_Specific_notes">OS Specific notes</A>
  -			<LI><A HREF="#Debug">Debug</A>
   		</UL>
   
   		<LI><A HREF="#Limiting_the_Number_of_Processes">Limiting the Number of Processes Serving the Same Resource</A>
  @@ -411,6 +400,17 @@
   categories are benchmarking and code profiling.
   
   <P>
  +It's important to understand that in a major number of the benchmarking
  +tests that we will execute we will not look at the absolute result numbers
  +but the relation between the two and more result sets, since in most cases
  +we would try to show which coding approach is preferable and the you
  +shouldn't try to compare the absolute results collected while running the
  +same benchmarks on your machine, since you won't have the exact hardware
  +and software setup anyway. So this kind of comparisment would be
  +misleading. Compare the relative results from the tests running on your
  +machine, don't compare your absolute results with those in this Guide.
  +
  +<P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
   <CENTER><H2><A NAME="Benchmarking_Applications">Benchmarking Applications</A></H2></CENTER>
  @@ -1113,7 +1113,7 @@
   implementations is of the least size.
   
   <P>
  -For example let's compare <CODE>CGI.pm</CODE>'s OO vs procedural interfaces:
  +For example let's compare <CODE>CGI.pm</CODE>'s OO vs. procedural interfaces:
   
   <P>
   As you will see below the first OO script uses about 2k bytes while the
  @@ -1313,7 +1313,7 @@
   
   <P>
   BTW, you can check the number of opcodes in the code by a simple command
  -line run. For example comparing 'my&nbsp;%hash' vs 'my&nbsp;%hash&nbsp;=
  +line run. For example comparing 'my&nbsp;%hash' vs. 'my&nbsp;%hash&nbsp;=
   ()'.
   
   <P>
  @@ -2834,7 +2834,7 @@
   Notice that the the smaller the diff is, the bigger the number of processes
   you can have using the same amount of RAM. Therefore every 100K difference
   counts, when you multiply it by the number of processes. If we take the
  -number from the version version (1) vs (4) and assume that we have 256M of
  +number from the version version (1) vs. (4) and assume that we have 256M of
   memory dedicated to mod_perl processes we will get the following numbers
   using the formula derived from the above formula:
   
  @@ -3211,48 +3211,6 @@
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  -<CENTER><H2><A NAME="Memory_Swapping_is_Considered_Ba">Memory Swapping is Considered Bad</A></H2></CENTER>
  -<P>
  -Swap memory is slow since it resides on the hard disc, which is
  -<EM>much</EM> slower than the RAM.
  -
  -<P>
  -Why and when the swapping happens? Your machine starts to swap when there
  -is no more available RAM to use for the process currently using the CPU. To
  -gain the required number of memory pages requested by the process the
  -kernel has to page out (i.e. move to a hard disk's swap partition) exactly
  -the same number of pages. The kernel pages out memory pages using the LRU
  -(least recently used) or a similar algorithm to decide which pages to take
  -out, in attempt to prevent the situation where the next process in queue
  -for CPU will need exactly the pages that were paged out, and prevent the
  -page fault (when the page is not found in RAM) occur, which in turn will
  -require more pages to be swapped out in order to free the memory for the
  -pages that get swapped in.
  -
  -<P>
  -When the CPU has to page memory pages in and out things slow down, causing
  -processing demands to go up, which in turn slows down the system even more
  -as more memory is required. This ever worstening spiral will lead the
  -machine to halt, unless the resource demand suddenly drops down and allows
  -the processes to catch up with their tasks and go back to normal memory
  -usage.
  -
  -<P>
  -When tuning the performance of your box, you must configure all the
  -runnning software components in such a way that no memory swapping will
  -occur: even during peak hours. Swap space is an emergency pool, not a
  -resource to be used routinely. If you are low on memory and you badly need
  -it, buy it. Memory is cheap.
  -
  -<P>
  -For swapping monitoring techniques see the section '<A HREF="././debug.html#Apache_VMonitor_Visual_Syste">Apache::VMonitor -- Visual System and Apache Server Monitor</A>'.
  -
  -<P>
  -For the mod_perl specific swapping prevention guideliness see the section '<A HREF="././performance.html#Choosing_MaxClients">Choosing MaxClients</A>'.
  -
  -<P>
  -[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  -<HR>
   <CENTER><H2><A NAME="Increasing_Shared_Memory_With_me">Increasing Shared Memory With mergemem</A></H2></CENTER>
   <P>
   <CODE>mergemem</CODE> is an experimental utility for linux, which looks <EM>very</EM>
  @@ -3877,7 +3835,7 @@
           </td>
   
   	<td>
  -	  <pre>  % ./ab -n 100 -c 10 www.example.com:81/test/test.pl</pre>
  +	  <pre>  % ./ab -n 100 -c 10 <A HREF="http://www.example.com:81/test/test.pl">http://www.example.com:81/test/test.pl</A></pre>
           </td>
   	    
         </tr>
  @@ -3895,21 +3853,23 @@
           </td>
   
   	<td>
  -	  <pre>  Concurrency Level:      10
  -  Time taken for tests:   0.715 seconds
  +	  <pre>  Document Path:          /perl/test.pl
  +  Document Length:        16 bytes
  +  
  +  Concurrency Level:      10
  +  Time taken for tests:   1.683 seconds
     Complete requests:      100
     Failed requests:        0
  -  Non-2xx responses:      100
  -  Total transferred:      60700 bytes
  -  HTML transferred:       31900 bytes
  -  Requests per second:    139.86
  -  Transfer rate:          84.90 kb/s received
  +  Total transferred:      16100 bytes
  +  HTML transferred:       1600 bytes
  +  Requests per second:    59.42
  +  Transfer rate:          9.57 kb/s received
     
  -  Connection Times (ms)
  +  Connnection Times (ms)
                   min   avg   max
  -  Connect:        0     0     3
  -  Processing:    13    67    71
  -  Total:         13    67    74</pre>
  +  Connect:        0    29   101
  +  Processing:    77   124  1259
  +  Total:         77   153  1360</pre>
           </td>
   	    
         </tr>
  @@ -3929,7 +3889,7 @@
   	<td>
   	  <pre>  Complete requests:      100
     Failed requests:        0
  -  Requests per second:    139.86</pre>
  +  Requests per second:    59.42</pre>
           </td>
   	    
         </tr>
  @@ -3948,7 +3908,7 @@
           </td>
   
   	<td>
  -	  <pre>  % ./ab -n 1000 -c 10 www.example.com:81/perl/access/access.cgi
  +	  <pre>  % ./ab -n 1000 -c 10  <A HREF="http://www.example.com:81/perl/access/access.cgi">http://www.example.com:81/perl/access/access.cgi</A>
     Concurrency Level:      10
     Complete requests:      1000
     Failed requests:        0
  @@ -3971,7 +3931,7 @@
           </td>
   
   	<td>
  -	  <pre>  % ./ab -n 1000 -c 50 www.example.com:81/perl/access/access.cgi
  +	  <pre>  % ./ab -n 1000 -c 50  <A HREF="http://www.example.com:81/perl/access/access.cgi">http://www.example.com:81/perl/access/access.cgi</A>
     Complete requests:      1000
     Failed requests:        0
     Requests per second:    133.01</pre>
  @@ -3980,10 +3940,10 @@
         </tr>
       </table>
       <P>
  -We see that the server is capable of serving 50 concurrent users at an
  -amazing 133 requests per second! Let's find the upper limit. Using
  -<CODE>-n 10000 -c 1000</CODE> failed to get results (Broken Pipe?). Using <CODE>-n
  -10000 -c 500</CODE> resulted in 94.82 requests per second. The server's performance went down
  +We see that the server is capable of serving 50 concurrent users at 133
  +requests per second! Let's find the upper limit. Using <CODE>-n
  +10000 -c 1000</CODE> failed to get results (Broken Pipe?). Using <CODE>-n 10000
  +-c 500</CODE> resulted in 94.82 requests per second. The server's performance went down
   with the high load.
   
   <P>
  @@ -4044,7 +4004,7 @@
           </td>
   
   	<td>
  -	  <pre>  % ./ab -n 1000 -c 50 www.example.com:81/perl/access/access.cgi</pre>
  +	  <pre>  % ./ab -n 1000 -c 50  <A HREF="http://www.example.com:81/perl/access/access.cgi">http://www.example.com:81/perl/access/access.cgi</A></pre>
           </td>
   	    
         </tr>
  @@ -5709,7 +5669,7 @@
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  -<CENTER><H1><A NAME="TMTOWTDI_Convenience_and_Habit_">TMTOWTDI: Convenience and Habit versus Performance</A></H1></CENTER>
  +<CENTER><H1><A NAME="TMTOWTDI_Convenience_and_Habit_">TMTOWTDI: Convenience and Habit vs. Performance</A></H1></CENTER>
   <P>
   TMTOWTDI (sometimes pronounced <EM>"tim toady"</EM>), or <EM>"There's More
   Than One Way To Do It"</EM> is the main motto of Perl. In other words, you can gain the same goal by
  @@ -5729,43 +5689,9 @@
   support the theory, since however good the theory its the numbers we get in
   practice that matter.
   
  -<P>
  -The following SW/HW is used for the benchmarking purposes:
  -
   <P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  HW: Dual Pentium II (Deschutes) 400Mhz 512 KB cache 256MB 
  -      RAM (DIMM PC100)</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  SW: Linux (RH 6.1) Perl 5.005_03
  -      Apache/1.3.12 mod_perl/1.22 mod_ssl/2.6.2 OpenSSL/0.9.5</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -The relevant Apache configuration:
  +In the following benchmarks, unless told different the following Apache
  +configuration has been used:
   
   <P>
   
  @@ -5789,7 +5715,7 @@
       <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  -<CENTER><H2><A NAME="Apache_Registry_versus_pure_Per">Apache::Registry versus pure PerlHandler</A></H2></CENTER>
  +<CENTER><H2><A NAME="Apache_Registry_PerlHandler_vs_">Apache::Registry PerlHandler vs. Custom PerlHandler</A></H2></CENTER>
   <P>
   At some point you have to decide whether to use <CODE>Apache::Registry</CODE>
   and similar handlers and stick to writing scripts for the content
  @@ -5798,44 +5724,65 @@
   <P>
   <CODE>Apache::Registry</CODE> maps a request to a file and generates a subroutine to run the code
   contained in that file. If you use a
  -PerlHandler&nbsp;My::handler instead of <CODE>Apache::Registry</CODE>, you have a direct mapping from request to subroutine, without the steps
  +PerlHandler&nbsp;My::Handler instead of <CODE>Apache::Registry</CODE>, you have a direct mapping from request to subroutine, without the steps
   in between. These steps include:
   
  -<DL>
  -<P><DT><STRONG><A NAME="item_stat">stat the $r-&gt;filename</A></STRONG><DD>
  -<P><DT><STRONG><A NAME="item_check">check that it exists and is executable</A></STRONG><DD>
  -<P><DT><STRONG><A NAME="item_generate">generate a Perl package name based on $r-&gt;uri</A></STRONG><DD>
  -<P><DT><STRONG><A NAME="item_chdir">chdir basename $r-&gt;filename</A></STRONG><DD>
  -<P><DT><STRONG><A NAME="item_compare">compare last modified time</A></STRONG><DD>
  -<P><DT><STRONG><A NAME="item_if">if modified or not compiled, compile the subroutine</A></STRONG><DD>
  -<P><DT><STRONG>chdir $old_cwd</STRONG><DD>
  -</DL>
  +<OL>
  +<P><LI>
   <P>
  -If you cut out those steps, you cut out some overhead, plain and simple. Do
  -you <EM>need</EM> to cut out that overhead? We don't know, your requirements determine that.
  +run the <CODE>stat()</CODE> on the script's filename ($r-&gt;filename)
   
  +<P><LI>
   <P>
  -You should take a look at the sister <CODE>Apache::Registry</CODE> modules that don't perform all all these steps, so you can still choose to
  -stick to using scripts to generate the content.
  +check that the file exists and is executable
   
  +<P><LI>
   <P>
  -On the other hand, if you go the pure Perl handler way you will have to add
  -a special configuration directives for each handler, something that you
  -don't do when you go the ``scripts'' way.
  +generate a Perl package name based on the request's URI ($r-&gt;uri)
   
  +<P><LI>
   <P>
  -Now let's run benchmarks and compare.
  +go to the directory the script resides in (chdir basename $r-&gt;filename)
  +
  +<P><LI>
  +<P>
  +compare the file's and stored in memory compiled subroutine's last modified
  +time (if it was compiled already)
   
  +<P><LI>
   <P>
  -[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  -<HR>
  -<CENTER><H3><A NAME="The_Light_Empty_Code">The Light (Empty) Code</A></H3></CENTER>
  +if modified or not compiled, compile the subroutine
  +
  +<P><LI>
  +<P>
  +go back to the previous directory (chdir $old_cwd)
  +
  +</OL>
  +<P>
  +If you cut out those steps, you cut out some overhead, plain and simple. Do
  +you <EM>need</EM> to cut out that overhead? May be yes, may be not. Your requirements
  +determine that.
  +
  +<P>
  +You should take a look at the sister <CODE>Apache::Registry</CODE> modules (e.g.
  +<CODE>Apache::RegistryNG</CODE> and <CODE>Apache::RegistryBB</CODE>) that don't perform all these steps, so you can still choose to stick to
  +using scripts to generate the content. The greatest added value of scripts
  +is that you don't have to modify the configuration file to add the handler
  +configuration and restarting the server for each newly written content
  +handler.
  +
  +<P>
  +Now let's run benchmarks and compare.
  +
   <P>
  -First lets see the overhead that <CODE>Apache::Registry</CODE> adds. In order to do that we will use an almost empty script, that only
  -sends a basic header and one word as content.
  +We want to see the overhead that <CODE>Apache::Registry</CODE> adds compared to the custom handler and whether it becomes insignificant
  +when used for the heavy and time consuming code. In order to do that we
  +will run two benchmarks sets: the first so called a <EM>light</EM> set will use an almost empty script, that only sends a basic header and one
  +word as content; the second will be a <EM>heavy</EM> set which will add some time consuming operation to the script's and the
  +handler's code.
   
   <P>
  -The <EM>registry.pl</EM> script running under <CODE>Apache::Registry</CODE>:
  +For the <EM>light</EM> set we are going to use the <EM>registry.pl</EM> script running under <CODE>Apache::Registry</CODE>:
   
   <P>
   
  @@ -5857,7 +5804,7 @@
         </tr>
       </table>
       <P>
  -The Perl Content handler:
  +And the following content generation handler:
   
   <P>
   
  @@ -5886,7 +5833,7 @@
         </tr>
       </table>
       <P>
  -with settings:
  +We will add this settings to <EM>httpd.conf</EM>:
   
   <P>
   
  @@ -5908,11 +5855,11 @@
         </tr>
       </table>
       <P>
  -so we get <CODE>Benchmark::Handler</CODE> preloaded.
  +The first directive worries to preload and compile the
  +<CODE>Benchmark::Handler</CODE> module. The rest of the lines tell Apache to execute the subroutine <CODE>Benchmark::Handler::handler</CODE> when a request with relative URI <EM>/benchmark_handler</EM> is made.
   
   <P>
  -We will use the <CODE>Apache::RegistryLoader</CODE> to preload the script as well, so the benchmark will be fair and only the
  -processing time will be measured. In the <EM>startup.pl</EM> we add:
  +We will use the usual configuration for <CODE>Apache::Registry</CODE> scripts, where all the URIs starting with <EM>/perl</EM> are remapped to the files residing under <EM>/home/httpd/perl/</EM> directory.
   
   <P>
   
  @@ -5924,18 +5871,22 @@
           </td>
   
   	<td>
  -	  <pre>  use Apache::RegistryLoader ();
  -  Apache::RegistryLoader-&gt;new-&gt;handler(
  -              &quot;/perl/benchmarks/registry.pl&quot;,
  -   &quot;/home/httpd/perl/benchmarks/registry.pl&quot;);</pre>
  +	  <pre>  Alias /perl/ /home/httpd/perl/
  +  &lt;Location /perl&gt;
  +    SetHandler perl-script
  +    PerlHandler +Apache::Registry
  +    Options ExecCGI
  +    PerlSendHeader On
  +  &lt;/Location&gt;</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -And we if we check the <EM>Compiled Registry Scripts"</EM> section with the help of <A HREF="././debug.html#Apache_Status_Embedded_Inter">Apache::Status</A> ( <A
  -HREF="http://localhost/perl-status?rgysubs">http://localhost/perl-status?rgysubs</A>
  -), where we see the listing of the already compiled scripts:
  +We will use the <CODE>Apache::RegistryLoader</CODE> to preload and compile the script at the server startup as well, so the
  +benchmark will be fair through the benchmark and only the processing time
  +will be measured. To accomplish the preloading we add the following code to
  +the <EM>startup.pl</EM> file:
   
   <P>
   
  @@ -5947,20 +5898,18 @@
           </td>
   
   	<td>
  -	  <pre>  Apache::ROOT::perl::benchmarks::registry_2epl</pre>
  +	  <pre>  use Apache::RegistryLoader ();
  +  Apache::RegistryLoader-&gt;new-&gt;handler(
  +              &quot;/perl/benchmarks/registry.pl&quot;,
  +   &quot;/home/httpd/perl/benchmarks/registry.pl&quot;);</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  -<HR>
  -<CENTER><H3><A NAME="The_Heavy_Code">The Heavy Code</A></H3></CENTER>
  -<P>
  -We we will see that the overhead is insignificant when the code itself is
  -significantly heavier and slower. Let's leave the above code examples
  -umodified but add some CPU intensive processing operation (it can be also
  -an IO operation or a database query.)
  +To create the <EM>heavy</EM> benchmark set let's leave the above code examples unmodified but add some
  +CPU intensive processing operation (it can be also an IO operation or a
  +database query.)
   
   <P>
   
  @@ -5979,12 +5928,16 @@
         </tr>
       </table>
       <P>
  -[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  -<HR>
  -<CENTER><H3><A NAME="Processing_and_Results">Processing and Results</A></H3></CENTER>
  +This code does lots of mathematical processing and therefore very CPU
  +intensive.
  +
  +<P>
  +Now we are ready to proceed with the benchmark. We will generate 5000
  +requests with 15 as a concurrency level using the <CODE>Apache::Benchmark</CODE>
  +module.
  +
   <P>
  -So now we can proceed with the benchmark. We will generate 5000 request
  -with 10 as a concurrency level (i.e. emulating 10 concurrent users):
  +Here are the reported results:
   
   <P>
   
  @@ -5996,14 +5949,24 @@
           </td>
   
   	<td>
  -	  <pre>  % ab -n 5000 -c 10 <A HREF="http://localhost/perl/benchmarks/registry.pl">http://localhost/perl/benchmarks/registry.pl</A>
  -  % ab -n 5000 -c 10 <A HREF="http://localhost/benchmark_handler">http://localhost/benchmark_handler</A></pre>
  +	  <pre>  ------------------------------
  +      name        | avtime   rps
  +  ------------------------------
  +  light handler   |     15   911
  +  light registry  |     21   680
  +  ------------------------------
  +  heavy handler   |    183    81
  +  heavy registry  |    191    77
  +  ------------------------------</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -And the results:
  +Let's look at the results and answer the previously asked questions.
  +
  +<P>
  +First let's compare the results from the <EM>light</EM> set. We can see that the average overhead added by <CODE>Apache::Registry</CODE> (compared to the custom handler) is about:
   
   <P>
   
  @@ -6015,13 +5978,43 @@
           </td>
   
   	<td>
  -	  <pre>  Light code:</pre>
  +	  <pre>  21 - 15 = 6 milliseconds</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  +per request.
  +
  +<P>
  +Thus the difference in speed is about 40% (15 vs. 21). Note that this
  +doesn't mean that the difference in the real world applications is such
  +big. And the results of the <EM>heavy</EM> set confirm that.
  +
  +<P>
  +In the <EM>heavy</EM> set the average processing time is almost the same for the <CODE>Apache::Registry</CODE> and the custom handler. You can clearly see that the difference between the
  +two is almost the same one that we have seen in the <EM>light</EM> set's results. It has grown from 6 milliseconds to 8 milliseconds
  +(191-183). Which means that the identical heavy code that has been added
  +was running for about 168 milliseconds (183-15). It doesn't mean that the
  +added code itself has been running for 168 milliseconds. It means that it
  +took 168 milliseconds for this code to be completed in a multi-process
  +environment where each process gets a time slice to use the CPU. The more
  +processes are running the more time the process will have to wait to get
  +the next time slice when it can use the CPU.
  +
  +<P>
  +We have the second question answered as well. You can see that when the
  +code is not just the <EM>hello</EM> script, the overhead of the extra operations done but the <CODE>Apache::Registry</CODE> module, is almost insignificant. It's a non zero though, so it depends on
  +your requirements, and if another 5-10 millisecons overhead are quite
  +tolerable, you may choose to use <CODE>Apache::Registry</CODE>.
   
  +<P>
  +The interesting thing is that when the server under test runs on a very
  +slow machine the results are completely different. I'll present them here
  +for comparison:
  +
  +<P>
  +
       <table>
         <tr>
   
  @@ -6030,15 +6023,58 @@
           </td>
   
   	<td>
  -	  <pre>    Type        RPS     Av.CTime
  -  -------       ---     -------
  -  Registry      561          16
  -  Handler       707          13</pre>
  +	  <pre>  ------------------------------
  +      name        | avtime   rps
  +  ------------------------------
  +  light handler   |     50   196
  +  light registry  |    160    61
  +  ------------------------------
  +  heavy handler   |    149    67
  +  heavy registry  |    822    12
  +  ------------------------------</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  +First of all the difference of 6 milliseconds in the average processing
  +time we have seen on the fast machine when running the
  +<EM>light</EM> set, now has grown to 110 milliseconds. Which means that a few extra
  +operations, that <CODE>Apache::Registry</CODE> does, turn to be very expensive on the slow machine.
  +
  +<P>
  +Second, you can see that when the <EM>heavy</EM> set is used, there is no preservation of the 110 milliseconds as we have
  +seen on the fast machine, which we obviously would expect to see, since the
  +code that was added should take the same time to execute in the handler and
  +the script. But instead we see a difference of 673 milliseconds (822-149).
  +
  +<P>
  +The explanation lies in fact that the difference between the machines isn't
  +merely in the CPU speed. It's possible that there are many other things
  +that are different. For example the size of the processor cache. If one
  +machine has a processor cache large enough to hold the whole handler and
  +the other doesn't this can be very significant, given that in our <EM>heavy</EM> benchmark set, 99.9% of the CPU activity was dedicated to running the
  +calculation code.
  +
  +<P>
  +But this also shows you again, that none of the results and conclusion made
  +here should be taken for granted. Certainly, most chances are that you will
  +see a similar behavior on your machine, but only after you have run the
  +benchmarks and analyzed the received results, you can be sure what is the
  +best for you using the setup under test. If you later you happen to use a
  +different machine, make sure to run the tests again, as they can lead to
  +complete different decision as we have just seen when we have tried the
  +same benchmark on a different machine.
  +
  +<P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H2><A NAME="_Bloatware_modules">&quot;Bloatware&quot; modules</A></H2></CENTER>
  +<P>
  +Perl modules like IO:: are very convenient, but let's see what it costs us
  +to use them. (perl5.6.0 over OpenBSD)
  +
  +<P>
   
       <table>
         <tr>
  @@ -6048,12 +6084,45 @@
           </td>
   
   	<td>
  -	  <pre>  Heavy code:</pre>
  +	  <pre>  % wc `perl -MIO -e 'print join(&quot;\n&quot;, sort values %INC, &quot;&quot;)'`
  +   124     696    4166 /usr/local/lib/perl5/5.6.0/Carp.pm
  +   580    2465   17661 /usr/local/lib/perl5/5.6.0/Class/Struct.pm
  +   400    1495   10455 /usr/local/lib/perl5/5.6.0/Cwd.pm
  +   313    1589   10377 /usr/local/lib/perl5/5.6.0/Exporter.pm
  +   225     784    5651 /usr/local/lib/perl5/5.6.0/Exporter/Heavy.pm
  +    92     339    2813 /usr/local/lib/perl5/5.6.0/File/Spec.pm
  +   442    1574   10276 /usr/local/lib/perl5/5.6.0/File/Spec/Unix.pm
  +   115     398    2806 /usr/local/lib/perl5/5.6.0/File/stat.pm
  +   406    1350   10265 /usr/local/lib/perl5/5.6.0/IO/Socket/INET.pm
  +   143     429    3075 /usr/local/lib/perl5/5.6.0/IO/Socket/UNIX.pm
  +  7168   24137  178650 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/Config.pm
  +   230    1052    5995 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/Errno.pm
  +   222     725    5216 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/Fcntl.pm
  +    47     101     669 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO.pm
  +   239     769    5005 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO/Dir.pm
  +   169     549    3956 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO/File.pm
  +   594    2180   14772 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO/Handle.pm
  +   252     755    5375 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO/Pipe.pm
  +    77     235    1709 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO/Seekable.pm
  +   428    1419   10219 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO/Socket.pm
  +   452    1401   10554 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/Socket.pm
  +   127     473    3554 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/XSLoader.pm
  +    52     161    1050 /usr/local/lib/perl5/5.6.0/SelectSaver.pm
  +   139     541    3754 /usr/local/lib/perl5/5.6.0/Symbol.pm
  +   161     609    4081 /usr/local/lib/perl5/5.6.0/Tie/Hash.pm
  +   109     390    2479 /usr/local/lib/perl5/5.6.0/strict.pm
  +    79     370    2589 /usr/local/lib/perl5/5.6.0/vars.pm
  +   318    1124   11975 /usr/local/lib/perl5/5.6.0/warnings.pm
  +    30      85     722 /usr/local/lib/perl5/5.6.0/warnings/register.pm
  + 13733   48195  349869 total</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  +Incredible. But it's half the size on linux:
  +
  +<P>
   
       <table>
         <tr>
  @@ -6063,16 +6132,29 @@
           </td>
   
   	<td>
  -	  <pre>    Type        RPS     Av.CTime
  -  -------       ---     -------
  -  Registry       68         146
  -  Handler        70         141</pre>
  +	  <pre>  % wc `perl -MIO -e 'print join(&quot;\n&quot;, sort values %INC, &quot;&quot;)'`
  +  [similar lines snipped]
  +  6618   25068  176740 total</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  +Moreover, that requires 116 happy trips through the kernel's
  +<CODE>namei().</CODE> It syscalls <CODE>open()</CODE> a remarkable 57
  +times, 17 of which failed but leaving 38 that were successful. It also
  +syscalled <CODE>read()</CODE> a curiously identical 57 times, ingesting a
  +total of 180,265 plump bytes. To top it off, this <STRONG><EM>increases your resident set size by two megabytes!</EM></STRONG>
  +(1.5Mb on linux).
   
  +<P>
  +Happy mallocking...
  +
  +<P>
  +It seems that <CODE>CGI.pm</CODE> suffers from the same disease:
  +
  +<P>
  +
       <table>
         <tr>
   
  @@ -6081,22 +6163,22 @@
           </td>
   
   	<td>
  -	  <pre>  Reports: 
  -  -----------------------------------------------
  -  RPS       : Requests Per Second
  -  Av. CTime : Average request processing time (msec) as seen by client</pre>
  +	  <pre>  % wc `perl -MCGI -le 'print for values %INC'`
  +  1368    6920   43710 /usr/local/lib/perl5/5.6.0/overload.pm
  +  6481   26122  200840 /usr/local/lib/perl5/5.6.0/CGI.pm
  +  7849   33042  244550 total</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  -<HR>
  -<CENTER><H3><A NAME="Conclusions">Conclusions</A></H3></CENTER>
  -<UL>
  -<P><LI><STRONG><A NAME="item_The">The Light Code</A></STRONG>
  +You have 16 trips through namei, 7 successful opens, 2 unsuccessful ones,
  +and 213k of data read in.
  +
   <P>
  -We can see that the average overhead added by <CODE>Apache::Registry</CODE> is about:
  +The following numbers show memory sizes (virtual and resident) for v5.6.0
  +of Perl on four different operating systems, The three calls each are
  +without any modules, with just -MCGI, and with -MIO (never with both):
   
   <P>
   
  @@ -6108,29 +6190,29 @@
           </td>
   
   	<td>
  -	  <pre>  16 - 13 = 3 milli-seconds</pre>
  +	  <pre>              OpenBSD       FreeBSD      Redhat       Solaris
  +              vsz   rss     vsz  rss     vsz  rss    vsz    rss
  +  Raw Perl    736   772     832 1208    2412  980    2928  2272
  +  w/ CGI     1220  1464    1308 1828    2972 1768    3616  3232
  +  w/ IO      2292  2580    2456 3016    4080 2868    5384  4976</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -per request.
  -
  -<P>
  -Thus the difference in speed is about 19%.
  +Anybody who's thinking of choosing one of these might do well to stare at
  +those numbers for a while.
   
  -<P><LI><STRONG><A NAME="item_The">The Heavy Code</A></STRONG>
   <P>
  -If we are looking at the average processing time, we see that the time
  -delta between the two handlers is almost the same and has grown from 3 msec
  -to 5 msec. Which means that the identical heavy code that has been added
  -was running for 130 msec (146-16). It doesn't mean that the added code
  -itself has been running for 130 msec. It means that it took 130 msec for
  -this code to be completed in a multi-process environment where each process
  -gets a time slice to use the CPU.
  -
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H2><A NAME="Apache_args_vs_Apache_Request">Apache::args vs. Apache::Request::param vs. CGI::param</A></H2></CENTER>
   <P>
  -If we run this extra code under plain Benchmark:
  +Let's write three <CODE>Apache::Registry</CODE> scripts that use
  +<CODE>Apache::args</CODE>, <CODE>Apache::Request::param</CODE> and <CODE>CGI::param</CODE> to process the form's input and print it out. Notice that <CODE>Apache::args</CODE>
  +is considered identical to <CODE>Apache::Request::param</CODE> only when you have a single valued keys, in case of multivalued keys (e.g.
  +when using checkbox groups) you will have to write some more code, since if
  +you do a simple:
   
   <P>
   
  @@ -6142,20 +6224,16 @@
           </td>
   
   	<td>
  -	  <pre>  benchmark.pl
  -  ------------
  -  use Benchmark;
  -  
  -  timethis (1_000,
  -   sub {
  -    my $x = 100;
  -    my $y = log ($x ** 100)  for (0..10000);
  -  });</pre>
  +	  <pre>  my %params = $r-&gt;args;</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  +only the last value will be stored and the rest will collapse, something
  +that you will solve with <CODE>Apache::Request::params</CODE> as:
  +
  +<P>
   
       <table>
         <tr>
  @@ -6165,19 +6243,25 @@
           </td>
   
   	<td>
  -	  <pre>  % perl benchmark.pl
  -  timethis 1000: 25 wallclock secs (24.93 usr +  0.00 sys = 24.93 CPU)</pre>
  +	  <pre>  my @values = $q-&gt;params('key');</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -We see that it takes about 25 CPU seconds to complete.
  +In addition <CODE>Apache::Request</CODE> and <CODE>CGI.pm</CODE> has many more functions that ease input processing, like handling file
  +uploads. But
  +<CODE>Apache::Request</CODE> is much faster since its guts are implemented in C, glued with Perl using
  +the XS code.
  +
  +<P>
  +Therefore assuming that the only functionality that you need is the parsing
  +of the key-value pairs, and assuming that every key has a single value, we
  +will compare the following almost indentical scripts, by trying to pass
  +various query strings.
   
   <P>
  -The interesting thing is that when the server under test runs on a slow
  -machine the results are completely different. I'll present them here for
  -comparison:
  +The code that we have used:
   
   <P>
   
  @@ -6189,7 +6273,13 @@
           </td>
   
   	<td>
  -	  <pre>  Light code:</pre>
  +	  <pre>  processing_with_apache_args.pl
  +  ------------------------------
  +  use strict;
  +  my $r = shift;
  +  $r-&gt;send_http_header('text/plain');
  +  my %args = $r-&gt;args;
  +  print join &quot;\n&quot;, map {&quot;$_ =&gt; &quot;.$args{$_} } keys %args;</pre>
           </td>
   	    
         </tr>
  @@ -6204,10 +6294,15 @@
           </td>
   
   	<td>
  -	  <pre>    Type        RPS     Av.CTime
  -  -------       ---     -------
  -  Registry       61         160
  -  Handler       196          50</pre>
  +	  <pre>  processing_with_apache_request.pl
  +  ---------------------------------
  +  use strict;
  +  use Apache::Request ();
  +  my $r = shift;
  +  my $q = Apache::Request-&gt;new($r);
  +  $r-&gt;send_http_header('text/plain');
  +  my %args = map {$_ =&gt; $q-&gt;param($_) } $q-&gt;param;
  +  print join &quot;\n&quot;, map {&quot;$_ =&gt; &quot;.$args{$_} } keys %args;</pre>
           </td>
   	    
         </tr>
  @@ -6222,13 +6317,24 @@
           </td>
   
   	<td>
  -	  <pre>  Heavy code:</pre>
  +	  <pre>  processing_with_cgi_pm.pl
  +  ---------------------------------
  +  use strict;
  +  use CGI;
  +  my $r = shift;
  +  $r-&gt;send_http_header('text/plain');
  +  my $q = new CGI;
  +  my %args = map {$_ =&gt; $q-&gt;param($_) } $q-&gt;param;
  +  print join &quot;\n&quot;, map {&quot;$_ =&gt; &quot;.$args{$_} } keys %args;</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  +All three scripts were preloaded at the server startup:
   
  +<P>
  +
       <table>
         <tr>
   
  @@ -6237,105 +6343,59 @@
           </td>
   
   	<td>
  -	  <pre>    Type        RPS     Av.CTime
  -  -------       ---     -------
  -  Registry       12         822
  -  Handler        67         149</pre>
  +	  <pre>  &lt;Perl&gt;
  +  use Apache::RegistryLoader ();
  +  Apache::RegistryLoader-&gt;new-&gt;handler(
  +                            &quot;/perl/processing_with_cgi_pm.pl&quot;,
  +            &quot;[ROOT_DIR]/httpd/perl/processing_with_cgi_pm.pl&quot;
  +                                    );
  +  Apache::RegistryLoader-&gt;new-&gt;handler(
  +                            &quot;/perl/processing_with_apache_request.pl&quot;,
  +            &quot;[ROOT_DIR]/httpd/perl/processing_with_apache_request.pl&quot;
  +                                    );
  +  Apache::RegistryLoader-&gt;new-&gt;handler(
  +                            &quot;/perl/processing_with_apache_args.pl&quot;,
  +            &quot;[ROOT_DIR]/httpd/perl/processing_with_apache_args.pl&quot;
  +                                    );
  +  &lt;/Perl&gt;</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -You can see that adding the same CPU intensive code to the two handlers
  -under test on the slow machine, enlarges the delta of the average
  -processing time between the two handlers. We'd expect to see the same delta
  -(of 110 msec) in this case, but that's not what's happenning.
  -
  -<P>
  -The explanation lies in fact that the difference between the machines isn't
  -merely the processor speed. It's possible that there are many other things
  -that different. For example the size of the processor cache. If one machine
  -has a processor cache large enough to hold the whole handler and the other
  -doesn't this can be very significant, given that in our benchmark, 99.9% of
  -the CPU activity was dedicated to running the handler's code.
  +And the results:
   
  -</UL>
  -<P>
  -[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  -<HR>
  -<CENTER><H2><A NAME="CGI_pm_versus_Apache_Request">CGI.pm versus Apache::Request</A></H2></CENTER>
   <P>
  -<CODE>CGI.pm</CODE> is a pure Perl implementation of the most used functions used in CGI
  -coding. Mainly it has two parts -- input processing and HTML generation.
   
  -<P>
  -<CODE>Apache::Request</CODE>'s core is written in C, giving it a significant memory and performance
  -benefit. It has all the functionality of
  -<CODE>CGI.pm</CODE> except HTML generation functions.
  +    <table>
  +      <tr>
   
  -<P>
  -<CODE>use CGI qw(-compile =</CODE> ':all')&gt; adds about 1Mb size to the server.
  -<CODE>CGI.pm</CODE> pulls lots of stunts under the covers to provide both a method and function
  -interface, etc.  <CODE>Apache::Request</CODE> is a very thin XS layer on top of a C library and only adds a few kbytes
  -size to the server. this C code is much faster and lighter than the Perl
  -equivalent used in <CODE>CGI.pm</CODE> or similar (e.g. CGI_Lite).
  -
  -<P>
  -This difference might not matter much to you, depending on your
  -requirements.
  -
  -<P>
  -Let's write two registry scripts that use <CODE>CGI.pm</CODE> and
  -<CODE>Apache::Request</CODE> to process a form's input and print it out. We will use the scripts to
  -benchmark the modules.
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
   	<td bgcolor="blue" width="1">
   	  &nbsp;
           </td>
   
   	<td>
  -	  <pre>  benchmarks/cgi_pm.pl
  -  --------------------
  -  use strict;
  -  use CGI;
  -  my $q = new CGI;
  -  print $q-&gt;header('text/plain');
  -  print join &quot;\n&quot;, map {&quot;$_ =&gt; &quot;.$q-&gt;param($_) } $q-&gt;param;</pre>
  +	  <pre>  -------------------------------------------------------------
  +  name           query_length  | avtime completed failed    rps
  +  -------------------------------------------------------------
  +  apache_args              25  |     69      5000      0    698
  +  apache_request           25  |     76      5000      0    632
  +  apache_args             337  |     97      5000      0    500
  +  cgi_pm                   25  |    115      5000      0    422
  +  apache_request          337  |    159      5000      0    308
  +  cgi_pm                  337  |    301      5000      0    163
  +  --------------------------------------------------------------
  +  Non-varying sub-test parameters:
  +  --------------------------------------------------------------
  +  concurrency : 50
  +  connections : 5000</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  +We have used two different query strings, generated by:
   
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  benchmarks/apache_request.pl
  -  ----------------------------
  -  use strict;
  -  use Apache::Request ();
  -  my $r = Apache-&gt;request;
  -  my $q = Apache::Request-&gt;new($r);
  -  $r-&gt;send_http_header('text/plain');
  -  print join &quot;\n&quot;, map {&quot;$_ =&gt; &quot;.$q-&gt;param($_) } $q-&gt;param;</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -We preload both the modules that we are going to benchmark in the
  -<EM>startup.pl</EM>:
  -
   <P>
   
       <table>
  @@ -6346,14 +6406,16 @@
           </td>
   
   	<td>
  -	  <pre>  use Apache::Request ();
  -  use CGI  qw(-compile :all);</pre>
  +	  <pre>  my $query = [
  +             join(&quot;&amp;&quot;, map {&quot;$_=&quot;.'e' x 10}  ('a'..'b')),
  +             join(&quot;&amp;&quot;, map {&quot;$_=&quot;.'e' x 10}  ('a'..'z')),
  +            ];</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -We will preload the both scripts as well:
  +The first one renders into:
   
   <P>
   
  @@ -6365,394 +6427,23 @@
           </td>
   
   	<td>
  -	  <pre>  use Apache::RegistryLoader ();
  -  Apache::RegistryLoader-&gt;new-&gt;handler(
  -              &quot;/perl/benchmarks/cgi_pm.pl&quot;,
  -   &quot;/home/httpd/perl/benchmarks/cgi_pm.pl&quot;);
  -  Apache::RegistryLoader-&gt;new-&gt;handler(
  -              &quot;/perl/benchmarks/apache_request.pl&quot;,
  -   &quot;/home/httpd/perl/benchmarks/apache_request.pl&quot;);</pre>
  +	  <pre>  a=eeeeeeeeee&amp;b=eeeeeeeeee</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -Now let's benchmark the two:
  +which is 25 characters in length. The other is similar but of 337
  +characters in length. Now you can tell what are the numbers in the
  +<CODE>query_length</CODE> column of the report.
   
   <P>
  +You can see that <CODE>Apache::args</CODE> is much faster than the other two modules, whereas <CODE>Apache::Request::param</CODE> is much faster than
  +<CODE>CGI::param</CODE>.
   
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  % ab -n 1000 -c 10 \
  -   '<A HREF="http://localhost/perl/benchmarks/cgi_pm.pl?a=b&amp;c=+k+d+d+f&amp;d=asf&amp;as=+1+2+3+4">http://localhost/perl/benchmarks/cgi_pm.pl?a=b&amp;c=+k+d+d+f&amp;d=asf&amp;as=+1+2+3+4</A>'
  -  
  -  Time taken for tests:   23.950 seconds
  -  Requests per second:    41.75
  -  Connnection Times (ms)
  -                min   avg   max
  -  Connect:        0     0    45
  -  Processing:   204   238   274
  -  Total:        204   238   319</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  % ab -n 1000 -c 10 \
  -   '<A HREF="http://localhost/perl/benchmarks/apache_request.pl?a=b&amp;c=+k+d+d+f&amp;d=asf&amp;as=+1+2+3+4">http://localhost/perl/benchmarks/apache_request.pl?a=b&amp;c=+k+d+d+f&amp;d=asf&amp;as=+1+2+3+4</A>'
  -  
  -  Time taken for tests:   18.406 seconds
  -  Requests per second:    54.33
  -  Connnection Times (ms)
  -                min   avg   max
  -  Connect:        0     0    32
  -  Processing:   156   183   202
  -  Total:        156   183   234</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -Apparently the latter script using <CODE>Apache::Request</CODE> is about 23% faster. If the input is going to be larger the percentage
  -speed up grows as well.
  -
  -<P>
  -In the above example we have benchmarked the CGI input processing. When the
  -code is much heavier the overhead of using
  -<CODE>CGI.pm</CODE> for input parsing becomes insignificant.
  -
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  -<CENTER><H2><A NAME="_Bloatware_modules">&quot;Bloatware&quot; modules</A></H2></CENTER>
  -<P>
  -Perl modules like IO:: are very convenient, but let's see what it costs us
  -to use them. (perl5.6.0 over OpenBSD)
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  % wc `perl -MIO -e 'print join(&quot;\n&quot;, sort values %INC, &quot;&quot;)'`
  -   124     696    4166 /usr/local/lib/perl5/5.6.0/Carp.pm
  -   580    2465   17661 /usr/local/lib/perl5/5.6.0/Class/Struct.pm
  -   400    1495   10455 /usr/local/lib/perl5/5.6.0/Cwd.pm
  -   313    1589   10377 /usr/local/lib/perl5/5.6.0/Exporter.pm
  -   225     784    5651 /usr/local/lib/perl5/5.6.0/Exporter/Heavy.pm
  -    92     339    2813 /usr/local/lib/perl5/5.6.0/File/Spec.pm
  -   442    1574   10276 /usr/local/lib/perl5/5.6.0/File/Spec/Unix.pm
  -   115     398    2806 /usr/local/lib/perl5/5.6.0/File/stat.pm
  -   406    1350   10265 /usr/local/lib/perl5/5.6.0/IO/Socket/INET.pm
  -   143     429    3075 /usr/local/lib/perl5/5.6.0/IO/Socket/UNIX.pm
  -  7168   24137  178650 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/Config.pm
  -   230    1052    5995 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/Errno.pm
  -   222     725    5216 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/Fcntl.pm
  -    47     101     669 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO.pm
  -   239     769    5005 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO/Dir.pm
  -   169     549    3956 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO/File.pm
  -   594    2180   14772 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO/Handle.pm
  -   252     755    5375 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO/Pipe.pm
  -    77     235    1709 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO/Seekable.pm
  -   428    1419   10219 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO/Socket.pm
  -   452    1401   10554 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/Socket.pm
  -   127     473    3554 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/XSLoader.pm
  -    52     161    1050 /usr/local/lib/perl5/5.6.0/SelectSaver.pm
  -   139     541    3754 /usr/local/lib/perl5/5.6.0/Symbol.pm
  -   161     609    4081 /usr/local/lib/perl5/5.6.0/Tie/Hash.pm
  -   109     390    2479 /usr/local/lib/perl5/5.6.0/strict.pm
  -    79     370    2589 /usr/local/lib/perl5/5.6.0/vars.pm
  -   318    1124   11975 /usr/local/lib/perl5/5.6.0/warnings.pm
  -    30      85     722 /usr/local/lib/perl5/5.6.0/warnings/register.pm
  - 13733   48195  349869 total</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -Incredible. But it's half the size on linux:
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  % wc `perl -MIO -e 'print join(&quot;\n&quot;, sort values %INC, &quot;&quot;)'`
  -  [similar lines snipped]
  -  6618   25068  176740 total</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -Moreover, that requires 116 happy trips through the kernel's
  -<CODE>namei().</CODE> It syscalls <CODE>open()</CODE> a remarkable 57
  -times, 17 of which failed but leaving 38 that were successful. It also
  -syscalled <CODE>read()</CODE> a curiously identical 57 times, ingesting a
  -total of 180,265 plump bytes. To top it off, this <STRONG><EM>increases your resident set size by two megabytes!</EM></STRONG>
  -(1.5Mb on linux).
  -
  -<P>
  -Happy mallocking...
  -
  -<P>
  -It seems that <CODE>CGI.pm</CODE> suffers from the same disease:
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  % wc `perl -MCGI -le 'print for values %INC'`
  -  1368    6920   43710 /usr/local/lib/perl5/5.6.0/overload.pm
  -  6481   26122  200840 /usr/local/lib/perl5/5.6.0/CGI.pm
  -  7849   33042  244550 total</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -You have 16 trips through namei, 7 successful opens, 2 unsuccessful ones,
  -and 213k of data read in.
  -
  -<P>
  -The following numbers show memory sizes (virtual and resident) for v5.6.0
  -of Perl on four different operating systems, The three calls each are
  -without any modules, with just -MCGI, and with -MIO (never with both):
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>              OpenBSD       FreeBSD      Redhat       Solaris
  -              vsz   rss     vsz  rss     vsz  rss    vsz    rss
  -  Raw Perl    736   772     832 1208    2412  980    2928  2272
  -  w/ CGI     1220  1464    1308 1828    2972 1768    3616  3232
  -  w/ IO      2292  2580    2456 3016    4080 2868    5384  4976</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -Anybody who's thinking of choosing one of these might do well to stare at
  -those numbers for a while.
  -
  -<P>
  -[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  -<HR>
  -<CENTER><H2><A NAME="Apache_args_versus_Apache_Requ">Apache::args versus Apache::Request::params</A></H2></CENTER>
  -<P>
  -Let's write two registry scripts that use <CODE>Apache::args</CODE> and
  -<CODE>Apache::Request::params</CODE> to process the form's input and print it out. Notice that <CODE>Apache::args</CODE> is considered identical to
  -<CODE>Apache::Request::params</CODE> only when you have a single valued keys, in case of multivalued keys (e.g.
  -when using checkbox groups) you will have to write some more code, since if
  -you do a simple:
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  %params = $r-&gt;args;</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -only the last value will be stored and the rest will collapse, something
  -that you will solve with <CODE>Apache::Request::params</CODE> as:
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  @values = $q-&gt;params('key');</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -In addition <CODE>Apache::Request</CODE> has many more functions that ease input processing, like handling file
  -uploads.
  -
  -<P>
  -Therefore assuming that the only functionality that you need is the parsing
  -of the key-value pairs, and assuming that every key has a single value, we
  -will compare a slightly modified script from the previous section (<EM>apache_request.pl</EM>) and write a new one that uses
  -<CODE>args()</CODE>:
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  benchmarks/apache_request.pl
  -  ----------------------------
  -  use strict;
  -  use Apache::Request ();
  -  my $r = Apache-&gt;request;
  -  my $q = Apache::Request-&gt;new($r);
  -  $r-&gt;send_http_header('text/plain');
  -  print join &quot;\n&quot;, $q-&gt;param;</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  benchmarks/apache_args.pl
  -  -------------------------
  -  use strict;
  -  my $r = Apache-&gt;request;
  -  $r-&gt;send_http_header('text/plain');
  -  print join &quot;\n&quot;, $r-&gt;args;</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -Now let's benchmark the two:
  -
  -<P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  % ab -n 1000 -c 10 \
  -  '<A HREF="http://localhost/perl/benchmarks/apache_request.pl?a=b&amp;c=k&amp;d=asf&amp;as=1">http://localhost/perl/benchmarks/apache_request.pl?a=b&amp;c=k&amp;d=asf&amp;as=1</A>'</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  Time taken for tests:   16.961 seconds
  -  Requests per second:    58.96
  -  Connnection Times (ms)
  -                min   avg   max
  -  Connect:        0     0    20
  -  Processing:   150   168   343
  -  Total:        150   168   363</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  % ab -n 1000 -c 10 \
  -  '<A HREF="http://localhost/perl/benchmarks/apache_args.pl?a=b&amp;c=k&amp;d=asf&amp;as=1">http://localhost/perl/benchmarks/apache_args.pl?a=b&amp;c=k&amp;d=asf&amp;as=1</A>'</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -
  -    <table>
  -      <tr>
  -
  -	<td bgcolor="blue" width="1">
  -	  &nbsp;
  -        </td>
  -
  -	<td>
  -	  <pre>  Time taken for tests:   17.154 seconds
  -  Requests per second:    58.30
  -  Connnection Times (ms)
  -                min   avg   max
  -  Connect:        0     2   136
  -  Processing:    68   168   202
  -  Total:         68   170   338</pre>
  -        </td>
  -	    
  -      </tr>
  -    </table>
  -    <P>
  -Apparently the two run at the same speed.
  -
  -<P>
  -[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  -<HR>
   <CENTER><H2><A NAME="Using_1_Under_mod_perl_and_Be">Using $|=1 Under mod_perl and Better print() Techniques.</A></H2></CENTER>
   <P>
   As you know, <CODE>local $|=1;</CODE> disables the buffering of the currently selected file handle (default is <CODE>STDOUT</CODE>). If you enable it,
  @@ -6944,12 +6635,12 @@
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  -<CENTER><H2><A NAME="Global_vs_Fully_Qualified_Variab">Global vs Fully Qualified Variables</A></H2></CENTER>
  +<CENTER><H2><A NAME="Global_vs_Fully_Qualified_Varia">Global vs. Fully Qualified Variables</A></H2></CENTER>
   <P>
  -It's always a good idea to avoid global variables where possible. Some
  +It's always a good idea to avoid global variables where it's possible. Some
   variables must be either global, such as a module's <CODE>@ISA</CODE> or
   <CODE>$VERSION</CODE> variables or else fully qualified such as
  -<STRONG>@MyModule::ISA</STRONG>), so that Perl can see them.
  +<STRONG>@MyModule::ISA</STRONG>), so that Perl can see them from different packages.
   
   <P>
   A combination of <CODE>strict</CODE> and <CODE>vars</CODE> pragmas keeps modules clean and reduces a bit of noise. However, the <CODE>vars</CODE> pragma also creates aliases, as does <CODE>Exporter</CODE>, which eat up more memory. When possible, try to use fully qualified names
  @@ -7009,7 +6700,7 @@
   When possible, avoid importing a module's functions into your name space.
   The aliases which are created can take up quite a bit of memory. Try to use
   function interfaces and fully qualified names like
  -<CODE>Package::function</CODE> or <CODE>$Package::variable</CODE> instead. For benchmarks see <A HREF="././performance.html#Object_Methods_Calls_Versus_Func">Object Methods Calls Versus Function Calls</A>.
  +<CODE>Package::function</CODE> or <CODE>$Package::variable</CODE> instead. For benchmarks see <A HREF="././performance.html#Object_Methods_Calls_vs_Functio">Object Methods Calls vs. Function Calls</A>.
   
   <P>
   Note: method interfaces are a little bit slower than function calls. You
  @@ -7018,7 +6709,7 @@
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  -<CENTER><H2><A NAME="Object_Methods_Calls_Versus_Func">Object Methods Calls Versus Function Calls</A></H2></CENTER>
  +<CENTER><H2><A NAME="Object_Methods_Calls_vs_Functio">Object Methods Calls vs. Function Calls</A></H2></CENTER>
   <P>
   Which subroutine calling form is more efficient: OOP methods or functions?
   
  @@ -7246,7 +6937,7 @@
         </tr>
       </table>
       <P>
  -versus
  +vs
   
   <P>
   
  @@ -7664,7 +7355,7 @@
         </tr>
       </table>
       <P>
  -Two <CODE>stat()</CODE> calls saved!
  +Two <CODE>stat()</CODE> calls were saved!
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  @@ -7677,14 +7368,81 @@
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  -<CENTER><H2><A NAME="Be_carefull_with_symbolic_links">Be carefull with symbolic links</A></H2></CENTER>
  +<CENTER><H2><A NAME="Be_Careful_with_Symbolic_Links">Be Careful with Symbolic Links</A></H2></CENTER>
  +<P>
  +As you know <CODE>Apache::Registry</CODE> caches the scripts in the packages whose names are constructed by scripts'
  +URI. If you have the same script that can be reached by different URIs,
  +which is possible if you have used symbolic links, you will get the same
  +script stored twice in the memory.
  +
  +<P>
  +For example:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  % ln -s /home/httpd/perl/news/news.pl /home/httpd/perl/news.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Now the script can be reached through the both URIs <EM>/news/news.pl</EM>
  +and <EM>/news.pl</EM>. It doesn't really matter until you advertise the two URIs, and users
  +reach the same script from both of them.
  +
   <P>
  -As you know <CODE>Apache::Registry</CODE> caches the scripts based on their URI. If you have the same script that can
  -be reached by different URIs, which is possible if you have used symbolic
  -links, you will get the same script cached twice!
  +So let's assume that you have issued the requests to the both URIs:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  <A HREF="http://localhost/perl/news/news.pl">http://localhost/perl/news/news.pl</A>
  +  <A HREF="http://localhost/perl/news.pl">http://localhost/perl/news.pl</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +To spot the duplication you should use the
  +<A HREF="././debug.html#Apache_Status_Embedded_Inter"><CODE>Apache::Status</CODE></A> module. Amongst other things, it shows all the compiled <CODE>Apache::Registry</CODE>
  +scripts (using their respective packages):
  +
  +<P>
  +If you are using the default configuration directives you should either use
  +this URI:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
   
  -<P>
  -For example:
  +	<td>
  +	  <pre>  <A HREF="http://localhost/perl-status?rgysubs">http://localhost/perl-status?rgysubs</A></pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +or just go to the main menu at:
   
   <P>
   
  @@ -7696,25 +7454,24 @@
           </td>
   
   	<td>
  -	  <pre>  % ln -s /home/httpd/perl/news/news.pl /home/httpd/perl/news.pl</pre>
  +	  <pre>  <A HREF="http://localhost/perl-status">http://localhost/perl-status</A></pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -Now the script can be reached through the both URIs <CODE>/news/news.pl</CODE>
  -and <CODE>/news.pl</CODE>. It doesn't really matter until you advertise the two URIs, and users
  -reach the same script from both of them.
  +And click on <CODE>Compiled Registry Scripts</CODE> menu item.
   
   <P>
  -To detect this, use the
  -<A HREF="././debug.html#Apache_Status_Embedded_Inter">/perl-status</A> handler to see all the compiled scripts and their packages. In our example,
  -when requesting: <A
  -HREF="http://localhost/perl-status?rgysubs">http://localhost/perl-status?rgysubs</A>
  -you would see:
  +META: we need a screen snapshot here!!!
   
   <P>
  +If you the script was accessed through the URI that was remapped to the
  +real file and through the URI that was remapped to the symbolic link, you
  +will see the following output:
   
  +<P>
  +
       <table>
         <tr>
   
  @@ -7730,9 +7487,10 @@
         </tr>
       </table>
       <P>
  -after both the URIs have been requested from the same child process that
  -happened to serve your request. To make the debugging easier see
  -<A HREF="././control.html#Running_a_Server_in_Single_Proce">run the server in single mode</A>.
  +You should run the server in the single mode, to see it immediately. If you
  +test it in the normal mode--it's possible that some child processes would
  +show only one entry or none at all, since they might not serve the same
  +requests as the others. For more hints see the section ``<A HREF="././control.html#Running_a_Server_in_Single_Proce">Run the server in single mode</A>''.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  @@ -7741,8 +7499,14 @@
   <P>
   There are two ways to improve performance: one is by tuning to squeeze the
   most out of your hardware and software; and the other is preventing certain
  -bad things from happening, e.g. memory leaks, unshared memory, Denial of
  -Service (DoS) attacks, etc.
  +bad things from happening, like impolite robots that crawl your site
  +without pausing between requests, memory leakages, getting the memory
  +unshared, making sure that some processes won't take up all the CPU etc.
  +
  +<P>
  +In the following sections we are going to discuss about the tools and
  +programming techniques that would help you to keep your service in order,
  +even if you are not around.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  @@ -8219,23 +7983,49 @@
       </table>
       <P>
   You might also want to check the section <A HREF="././performance.html#Limiting_the_Size_of_the_Process">Limiting the Size of the Processes</A>
  -and <A HREF="././performance.html#Limiting_the_Resources_Used_by_h">Limiting the Resources Used by httpd children</A>.
  +and <A HREF="././performance.html#Limiting_Other_Resources_Used_by">Limiting Other Resources Used by Apache Child Processes</A>.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  -<CENTER><H2><A NAME="Limiting_the_Size_of_the_Process">Limiting the Size of the Processes</A></H2></CENTER>
  +<CENTER><H2><A NAME="Keeping_the_Shared_Memory_Limit">Keeping the Shared Memory Limit</A></H2></CENTER>
  +<P>
  +As we have discussed already, during the child process' life a part of the
  +memory pages becomes unshared as some data structures become
  +<EM>"dirty"</EM> leading to the increased real memory consuming. As you remember to prevent
  +from the process from growing, it should be killed and the newly started
  +process will have all its memory shared with the parent process. While it
  +serves requests the unsharing process repeats and it has to be replaced
  +again.
  +
   <P>
  -<CODE>Apache::SizeLimit</CODE> allows you to kill off Apache httpd processes if they grow too large.  
  +As you remember the <CODE>MaxRequestsPerChild</CODE> directive allows you to specify the number of requests the server should
  +process before it gets killed. So you have to tune this directive, by
  +finding the optimal value using which, the process won't get too much
  +unshared memory. But this is very inconvenient solution since chances are
  +that your service is undergoing constant changes and you will have to
  +re-tune this number again and again to adapt to the ever changing code
  +base.
   
   <P>
  -Configuration:
  +It would be so nice if we could just set some guardian to watch the shared
  +size and kill the process based on the actual shared memory usage, when it
  +goes below the specified limit, so it's possible that the processes will
  +never be killed if there limit is never passed.
   
   <P>
  -In your <EM>startup.pl</EM>:
  +That's where the <CODE>Apache::GTopLimit</CODE> module comes to help. If you are lucky to have your OS among those that can
  +build the
  +<A HREF="././download.html#libgtop">libgtop</A> library, you will be able to build the
  +<CODE>GTop</CODE> module that provides the Perl API for <CODE>libgtop</CODE>, which in turn used by <CODE>Apache::GTopLimit</CODE> (that's the <EM>GTop</EM> part in the name).
   
   <P>
  +To set the shared memory lower limit of 4MB using the
  +<CODE>Apache::GTopLimit</CODE> add the following code into the <EM>startup.pl</EM>
  +file:
   
  +<P>
  +
       <table>
         <tr>
   
  @@ -8244,15 +8034,14 @@
           </td>
   
   	<td>
  -	  <pre>  use Apache::SizeLimit;
  -  $Apache::SizeLimit::MAX_PROCESS_SIZE = 10000; 
  -  # in KB, so this is 10MB</pre>
  +	  <pre>  use Apache::GTopLimit;
  +  $Apache::GTopLimit::MIN_PROCESS_SHARED_SIZE = 4096;</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -In your <EM>httpd.conf</EM>:
  +and in <EM>httpd.conf</EM>:
   
   <P>
   
  @@ -8264,36 +8053,104 @@
           </td>
   
   	<td>
  -	  <pre>  PerlFixupHandler Apache::SizeLimit</pre>
  +	  <pre>  PerlFixupHandler Apache::GTopLimit</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -See perldoc <CODE>Apache::SizeLimit</CODE> for more details.
  +and don't forget to restart the server for the changes to take the effect.
   
   <P>
  -By using this module, you should be able to avoid using the Apache
  -configuration directive <CODE>MaxRequestsPerChild</CODE>, although for some folks, using both in combination does the job.
  +If you don't want to set this limit by default but only for those requests
  +that are likely to get the memory unshared. In this case the memory size
  +testing would be be done only if you decide that you want it. You register
  +the post-processing check by using the <CODE>set_min_shared_size()</CODE>
  +function. For example:
   
   <P>
  -[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  -<HR>
  -<CENTER><H2><A NAME="Keeping_the_Shared_Memory_Limit">Keeping the Shared Memory Limit</A></H2></CENTER>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    use Apache::GTopLimit;
  +    if ($need_to_limit){
  +      Apache::GTopLimit-&gt;set_min_shared_size(4096);
  +    }</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Since accessing the process info might add a little overhead, you may want
  +to only check the process size every N times. And that's where the <CODE>$Apache::GTopLimit::CHECK_EVERY_N_REQUESTS</CODE> variable comes to help. For example to test the size every other time--put
  +in your
  +<EM>startup.pl</EM>:
  +
   <P>
  -<CODE>Apache::GTopLimit</CODE> module allows you to kill off Apache httpd processes if they grow too large
  -(just like <CODE>Apache::SizeLimit</CODE>) or have too little shared memory left. See
  -<A HREF="././modules.html#Apache_GTopLimit_Limit_Apache">Apache::GTopLimit</A>.
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $Apache::GTopLimit::CHECK_EVERY_N_REQUESTS = 2;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +If you want to run this module in the debug mode, add the following
  +directive in your <EM>startup.pl</EM>:
   
   <P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $Apache::GTopLimit::DEBUG = 1;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  -<CENTER><H2><A NAME="Limiting_the_Resources_Used_by_h">Limiting the Resources Used by httpd Children</A></H2></CENTER>
  +<CENTER><H2><A NAME="Limiting_the_Size_of_the_Process">Limiting the Size of the Processes</A></H2></CENTER>
  +<P>
  +So now you know how to prevent processes from consuming more real memory
  +when the memory gets unshared. An even more important restriction that we
  +want to impose is the absolute size of the process. If the process grows
  +after each request, especially if your code has memory leaks or you are
  +unfortunate to run an OS with C libraries that leak memory, you can easily
  +run out of memory if nothing will restrict those processes from growing.
  +The only restriction we can impose is killing the processes when they
  +become too big.
  +
   <P>
  -<CODE>Apache::Resource</CODE> uses the <CODE>BSD::Resource</CODE> module, which in turn uses the C function <CODE>setrlimit()</CODE> to set limits on system resources such as memory and cpu usage.
  +You can set the <CODE>MaxRequestPerChild</CODE> directive to kill the processes after only a few requests have been served.
  +But as we have explained in the previous section this solution is not as
  +good as the ability to control the process size and killing it only when
  +the limit is crossed.
   
   <P>
  -Configuration example:
  +If you have the <CODE>Apache::GTopLimit</CODE> we have described in the previous section you can control the upper limit
  +by setting the
  +<CODE>$Apache::GTopLimit::MAX_PROCESS_SIZE</CODE> directive. For example if you want the processes to be killed when they are
  +growing bigger than 10MB you should set the following limit in the <EM>startup.pl</EM> file:
   
   <P>
   
  @@ -8305,27 +8162,127 @@
           </td>
   
   	<td>
  -	  <pre>    # preload the module
  -  PerlModule Apache::Resource
  -  
  -    # set child memory limit (DATA segment) in megabytes
  -    # (default is 64 Meg)
  -  PerlSetEnv PERL_RLIMIT_DATA 32:48
  -    # set child CPU limit in seconds
  -    # (default is 360 seconds)
  -  PerlSetEnv PERL_RLIMIT_CPU 120:360
  -  
  -  PerlChildInitHandler Apache::Resource</pre>
  +	  <pre>    $Apache::GTopLimit::MAX_PROCESS_SIZE = 10240;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Just like with the shared memory limiting, you can set the limit for the
  +current process using the <CODE>set_max_size()</CODE> method in your code:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    use Apache::GTopLimit;
  +    Apache::GTopLimit-&gt;set_max_size(10000);</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Another alternative is to use the <CODE>Apache::SizeLimit</CODE> module, which is available for more platforms than <CODE>Apache::GTopLimit</CODE> at the moment of this writing. You should check the module's manpage to
  +find out what they are.
  +
  +<P>
  +To usage is very similar to <CODE>Apache::GTopLimit</CODE>, you control the upper size limit by setting the
  +<CODE>$Apache::SizeLimit::MAX_PROCESS_SIZE</CODE> variable in your <EM>startup.pl</EM>
  +file:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use Apache::SizeLimit;
  +  $Apache::SizeLimit::MAX_PROCESS_SIZE = 10240; </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +And in your <EM>httpd.conf</EM> you should add:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlFixupHandler Apache::SizeLimit</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Just like with <CODE>Apache::GTopLimit</CODE>, you can test the memory every few times, by setting the <CODE>$Apache::SizeLimit::CHECK_EVERY_N_REQUESTS</CODE>
  +variable. For example every fourth time:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $Apache::SizeLimit::CHECK_EVERY_N_REQUESTS = 4;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +And you can set the limit from within your code, rather from the global
  +configuration:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
           </td>
  +
  +	<td>
  +	  <pre>  use Apache::SizeLimit;
  +  Apache::SizeLimit-&gt;setmax(10240);</pre>
  +        </td>
   	    
         </tr>
       </table>
       <P>
  -If you configure <CODE>Apache::Status</CODE>, it will let you review the resources set in this way.
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H2><A NAME="Limiting_Other_Resources_Used_by">Limiting Other Resources Used by Apache Child Processes</A></H2></CENTER>
  +<P>
  +In addition to the absolute and shared memory sizes limiting, you might
  +need to prevent the processes from excessive consumption of the system
  +resources. Like limiting the CPU usage, the number of files that can be
  +opened, or memory segment usage and more.
   
   <P>
  -The following limit values are in megabytes: <CODE>DATA</CODE>, <CODE>RSS</CODE>,
  -<CODE>STACK</CODE>, <CODE>FSIZE</CODE>, <CODE>CORE</CODE>, <CODE>MEMLOCK</CODE>; all others are treated as their natural unit. Prepend <CODE>PERL_RLIMIT_</CODE> for each one you want to use. Refer to the <CODE>setrlimit</CODE> man page on your OS for other possible resources.
  +The <CODE>Apache::Resource</CODE> module allows this all by deploying the
  +<CODE>BSD::Resource</CODE> module, which in turn uses the C function
  +<CODE>setrlimit()</CODE> to set limits on system resources.
   
   <P>
   A resource limit is specified as a soft limit and a hard limit. When a soft
  @@ -8337,23 +8294,23 @@
   
   <P>
   If the value of the variable is of the form <CODE>S:H</CODE>, <CODE>S</CODE> is treated as the soft limit, and <CODE>H</CODE> is the hard limit. If it is just a single number, it is used for both soft
  -and hard limits.
  +and hard limits. So if you set
  +<CODE>10:20</CODE>, the soft limit is 10 and the hard limit is 20. If you set just <CODE>10</CODE>--both the soft and the hard limits are set to 20.
   
   <P>
  -[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  -<HR>
  -<CENTER><H3><A NAME="OS_Specific_notes">OS Specific notes</A></H3></CENTER>
  +The mostly spread usage of this module is to limit the CPU usage. The
  +environment variable <CODE>PERL_RLIMIT_CPU</CODE> defines the maximum amount of CPU time the process can use. If it runs for
  +longer than this, it gets killed, no matter what it does, either processing
  +a new request or just waiting. This is very useful when you have a code
  +with a bug and the process starts to spin in an endless loop or alike using
  +a lot of CPU and never completing the request. 
  +
   <P>
  -Note that under Linux <CODE>malloc()</CODE> uses <CODE>mmap()</CODE>
  -instead of <CODE>brk().</CODE> This is done to conserve virtual memory -
  -that is, when you malloc a large block of memory, it isn't actually given
  -to your program until you initialize it. The old-style <CODE>brk()</CODE>
  -syscall obeyed resource limits on data segment size as set in
  -<CODE>setrlimit()</CODE> - <CODE>mmap()</CODE> doesn't.
  +META: verify this.
   
   <P>
  -<CODE>Apache::Resource</CODE>'s defaults put caps on data size and stack size. Linux's current memory
  -allocation scheme doesn't honor these limits, so if you just do
  +The value is measured in seconds. The following example sets the soft limit
  +of the CPU usage to 120 seconds (the default is 360).
   
   <P>
   
  @@ -8365,25 +8322,43 @@
           </td>
   
   	<td>
  -	  <pre>  PerlSetEnv PERL_RLIMIT_DEFAULTS On
  -  PerlModule Apache::Resource
  -  PerlChildInitHandler Apache::Resource</pre>
  +	  <pre>  PerlModule Apache::Resource
  +  PerlSetEnv PERL_RLIMIT_CPU 120</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -Your Apache processes are still free to use as much memory as they like.
  +Of course you should tell mod_perl to use this module, which is done by
  +adding the following directive to <EM>httpd.conf</EM>:
   
   <P>
  -However, <CODE>BSD::Resource</CODE> also has a limit called <CODE>RLIMIT_AS</CODE>
  -(Address Space) which limits the total number of bytes of virtual memory
  -assigned to a process. Happily, Linux's memory manager <EM>does</EM>
  -honor this limit.
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlChildInitHandler Apache::Resource</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +There are other resources that you might want to limit. For example you can
  +limit the memory data and stack segment sizes (<CODE>PERL_RLIMIT_DATA</CODE> and <CODE>PERL_RLIMIT_STACK</CODE>), the maximum process file size (<CODE>PERL_RLIMIT_FSIZE</CODE>), the core file size (<CODE>PERL_RLIMIT_CORE</CODE>), the address space (virtual memory) limit (<CODE>PERL_RLIMIT_AS</CODE>), etc. Refer to the <CODE>setrlimit(2)</CODE> man page on your OS for
  +other possible resources. Remember to prepend <CODE>PERL_</CODE> before the resource types you will see in the man page.
   
   <P>
  -Therefore, you <EM>can</EM> limit memory usage under Linux with
  -<CODE>Apache::Resource</CODE> -- simply add a line to <EM>httpd.conf</EM>:
  +If you configure <CODE>Apache::Status</CODE>, it will let you review the resources set in this way. Remember that <CODE>Apache::Status</CODE> must be loaded before <CODE>Apache::Resource</CODE> in order to enable the resources display menu.
  +
  +<P>
  +If you want to set the debug mode set the <CODE>$Apache::Resource::Debug</CODE>
  +before loading the module, for example by using the Perl sections in
  +<EM>httpd.conf</EM>.
   
   <P>
   
  @@ -8395,20 +8370,34 @@
           </td>
   
   	<td>
  -	  <pre>  PerlSetEnv PERL_RLIMIT_AS  67108864</pre>
  +	  <pre>  &lt;Perl&gt;
  +    $Apache::Resource::Debug = 1;
  +    require Apache::Resource;
  +  &lt;/Perl&gt;
  +  PerlChildInitHandler Apache::Resource</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -This example sets a hard and soft limit of 64Mb of total address space.
  +Now open in the <EM>error_log</EM> file using tell and watch the debug messages showing up, when the requests
  +are served.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  -<CENTER><H3><A NAME="Debug">Debug</A></H3></CENTER>
  +<CENTER><H3><A NAME="OS_Specific_notes">OS Specific notes</A></H3></CENTER>
  +<P>
  +Note that under Linux <CODE>malloc()</CODE> uses <CODE>mmap()</CODE>
  +instead of <CODE>brk().</CODE> This is done to conserve virtual memory -
  +that is, when you malloc a large block of memory, it isn't actually given
  +to your program until you initialize it. The old-style <CODE>brk()</CODE>
  +system call obeyed resource limits on data segment size as set in
  +<CODE>setrlimit()</CODE> - <CODE>mmap()</CODE> doesn't.
  +
   <P>
  -To debug add:
  +<CODE>Apache::Resource</CODE>'s defaults put caps on data size and stack size. Linux's current memory
  +allocation scheme doesn't honor these limits, so if you just do
   
   <P>
   
  @@ -8420,20 +8409,46 @@
           </td>
   
   	<td>
  -	  <pre>  &lt;Perl&gt;
  -    $Apache::Resource::Debug = 1;
  -    require Apache::Resource;
  -  &lt;/Perl&gt;
  +	  <pre>  PerlSetEnv PERL_RLIMIT_DEFAULTS On
  +  PerlModule Apache::Resource
     PerlChildInitHandler Apache::Resource</pre>
           </td>
   	    
         </tr>
       </table>
  +    <P>
  +Your Apache processes are still free to use as much memory as they like.
  +
  +<P>
  +However, <CODE>BSD::Resource</CODE> also has a limit called <CODE>RLIMIT_AS</CODE>
  +(Address Space) which limits the total number of bytes of virtual memory
  +assigned to a process. Happily, Linux's memory manager <EM>does</EM>
  +honor this limit.
  +
  +<P>
  +Therefore, you <EM>can</EM> limit memory usage under Linux with
  +<CODE>Apache::Resource</CODE> -- simply add a line to <EM>httpd.conf</EM>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlSetEnv PERL_RLIMIT_AS  67108864</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
       <P>
  -and look in the <EM>error_log</EM> to see what it's doing.
  +This example sets a hard and soft limit of 64MB of total address space.
   
   <P>
  -Refer to <CODE>perldoc Apache::Resource</CODE> and <CODE>man 2 setrlimit</CODE> for more info.
  +Refer to the <CODE>Apache::Resource</CODE> and <CODE>setrlimit(2)</CODE> manpages for more information.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  @@ -8446,8 +8461,13 @@
   
   <P>
   It solves the problem of too many concurrent request accessing the same
  -URI, if for example it's very CPU intensive. For example you have three
  -base URIs:
  +URI, if for example the handler that serves this URI uses some resource
  +that has a limitation on the maximum number of possible users or the
  +handlers code is very CPU intensive and you cannot afford more than a
  +certain number of concurrent requests to this specific URI.
  +
  +<P>
  +Imagine that your service provides the three following URIs:
   
   <P>
   
  @@ -8470,12 +8490,12 @@
   The first two URIs are response critical as people want to read news and
   their email. The third URI is very CPU and RAM intensive image morphing
   service, provided as a bonus to your users. Since you don't want users to
  -abuse this service, you better set some limits on the number of concurrent
  +abuse this service, you have to set some limits on the number of concurrent
   requests for this resource, since if you don't--the other two critical
   resources can be hurt.
   
   <P>
  -The following setting:
  +When you compile in and enable the Apache mod_throttle_access module, the <CODE>MaxConcurrentReqs</CODE> directive becomes available. For example, the following setting:
   
   <P>
   
  @@ -8488,7 +8508,7 @@
   
   	<td>
   	  <pre>  &lt;Location &quot;/perl/morphing&quot;&gt;
  -    &lt;Limit PUT GET&gt;
  +    &lt;Limit PUT GET POST&gt;
         MaxConcurrentReqs 10
       &lt;/Limit&gt;
     &lt;/Location&gt; </pre>
  @@ -8497,8 +8517,8 @@
         </tr>
       </table>
       <P>
  -will allow only 10 concurrent requests under the URI <EM>/perl/morphing</EM>
  -and of methods PUT and GET to be processed at one time.
  +will allow only 10 concurrent PUT, GET or POST requests under the URI
  +<EM>/perl/morphing</EM> to be processed at one time. The other two URIs remain unlimited.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  @@ -9606,7 +9626,7 @@
   <td align=center valign=center>
   
   <b><font size=-1>Written by <a
  -href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/07/2000
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 08/05/2000
   </font></b>
   <br>
   
  
  
  
  1.14      +210 -18   modperl-site/guide/perl.html
  
  Index: perl.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/perl.html,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- perl.html	2000/06/07 22:45:36	1.13
  +++ perl.html	2000/08/05 20:48:07	1.14
  @@ -81,6 +81,7 @@
   		<LI><A HREF="#Making_Variables_Global_With_str">Making Variables Global With strict Pragma On</A>
   		<LI><A HREF="#Using_Exporter_pm_to_Share_Globa">Using Exporter.pm to Share Global Variables</A>
   		<LI><A HREF="#Using_the_Perl_Aliasing_Feature_">Using the Perl Aliasing Feature to Share Global Variables</A>
  +		<LI><A HREF="#Using_Non_Hardcoded_Configuratio">Using Non-Hardcoded Configuration Module Names</A>
   	</UL>
   
   	<LI><A HREF="#The_Scope_of_the_Special_Perl_Va">The Scope of the Special Perl Variables</A>
  @@ -1587,7 +1588,7 @@
       $counter = increment_counter($counter);
     
       sub increment_counter{
  -      my $counter = shift || 0 ;
  +      my $counter = shift;
     
         $counter++;
         print &quot;Counter is equal to $counter !\n&quot;;
  @@ -1637,7 +1638,7 @@
       increment_counter(\$counter);
     
       sub increment_counter{
  -      my $r_counter = shift || 0;
  +      my $r_counter = shift;
     
         $$r_counter++;
         print &quot;Counter is equal to $$r_counter !\n&quot;;
  @@ -1823,11 +1824,11 @@
   <CODE>%INC</CODE> is another special Perl variable that is used to cache the names of the
   files and the modules that were successfully loaded and compiled by
   <CODE>use(),</CODE> <CODE>require()</CODE> or <CODE>do()</CODE> statements.
  -Before attempting to load a file or a module, Perl checks whether it's
  -already in the
  -<CODE>%INC</CODE> hash. If it's there, the loading and therefore the compilation are not
  +Before attempting to load a file or a module with <CODE>use()</CODE> or
  +<CODE>require(),</CODE> Perl checks whether it's already in the <CODE>%INC</CODE> hash. If it's there, the loading and therefore the compilation are not
   performed at all. Otherwise the file is loaded into memory and an attempt
  -is made to compile it.
  +is made to compile it. <CODE>do()</CODE> does unconditional loading--no
  +lookup in the <CODE>%INC</CODE> hash is made.
   
   <P>
   If the file is successfully loaded and compiled, a new key-value pair is
  @@ -2634,6 +2635,19 @@
   <HR>
   <CENTER><H1><A NAME="Using_Global_Variables_and_Shari">Using Global Variables and Sharing Them Between Modules/Packages</A></H1></CENTER>
   <P>
  +It helps when you code your application in a structured way, using the perl
  +packages, but as you probably know once you start using packages it's much
  +harder to share the variables between the various packagings. A
  +configuration package comes to mind as a good example of the package that
  +will want its variables to be accessible from the other modules.
  +
  +<P>
  +Of course using the Object Oriented (OO) programming is the best way to
  +provide an access to variables through the access methods. But if you are
  +not yet ready for OO techniques you can still benefit from using the
  +techniques we are going to talk about.
  +
  +<P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
   <CENTER><H2><A NAME="Making_Variables_Global">Making Variables Global</A></H2></CENTER>
  @@ -2738,8 +2752,7 @@
     use My::HTML qw($q); # My/HTML.pm is in the same dir as script.pl
     $q = CGI-&gt;new;
     
  -  My::HTML::printmyheader();
  -  ----------------</pre>
  +  My::HTML::printmyheader();</pre>
           </td>
   	    
         </tr>
  @@ -2778,8 +2791,7 @@
       # Whatever you want to do with $q... e.g.
       print $q-&gt;header();
     }
  -  1;
  -  -------------------</pre>
  +  1;</pre>
           </td>
   	    
         </tr>
  @@ -2810,7 +2822,7 @@
         </tr>
       </table>
       <P>
  -Then you write <CODE>My::Doc</CODE> exactly like <CODE>My::HTML</CODE> - except of course that the content is different :).
  +Then you add the same <CODE>Exporter</CODE> code that we used in <CODE>My::HTML</CODE>, into <CODE>My::Doc</CODE>, so that it also exports <CODE>$q</CODE>.
   
   <P>
   One possible pitfall is when you want to use <CODE>My::Doc</CODE> in both
  @@ -2853,8 +2865,7 @@
     use My::Doc  qw($q); # Ditto
     $q = new CGI;
     
  -  My::HTML::printmyheader();
  -  ----------------</pre>
  +  My::HTML::printmyheader();</pre>
           </td>
   	    
         </tr>
  @@ -2892,8 +2903,7 @@
     
       My::Doc::printtitle('Guide');
     }
  -  1;
  -  -------------------</pre>
  +  1;</pre>
           </td>
   	    
         </tr>
  @@ -2929,8 +2939,7 @@
       
       print $q-&gt;h1($title);
     }
  -  1;
  -  -------------------</pre>
  +  1;</pre>
           </td>
   	    
         </tr>
  @@ -3059,6 +3068,189 @@
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +<CENTER><H2><A NAME="Using_Non_Hardcoded_Configuratio">Using Non-Hardcoded Configuration Module Names</A></H2></CENTER>
  +<P>
  +You have just seen how to use a configuration module for configuration
  +centralization and an easy access to the information stored in this module.
  +However, there is somewhat of a chicken-and-egg problem--how to let your
  +other modules know the name of this file? Hardcoding the name is
  +brittle--if you have only a single project it should be fine, but if you
  +have more projects which use different configurations and you will want to
  +reuse their code you will have to find all instances of the hardcoded name
  +and replace it. 
  +
  +<P>
  +Another solution could be to have the same name for a configuration module,
  +like <CODE>My::Config</CODE> but putting a different copy of it into different locations. But this won't
  +work under mod_perl because of the namespace collision. You cannot load
  +different modules which uses the same name, only the first one will be
  +loaded.
  +
  +<P>
  +Luckily, there is another solution which allows us to stay flexible.
  +<CODE>PerlSetVar</CODE> comes to rescue. Just like with environment variables, you can set server's
  +global Perl variables which can be retrieved from any module and script.
  +Those statements are placed into the
  +<EM>httpd.conf</EM> file. For example
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlSetVar FooBaseDir       /home/httpd/foo
  +  PerlSetVar FooConfigModule  Foo::Config</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Now we <CODE>require()</CODE> the file where the above configuration will
  +be used.
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  PerlRequire /home/httpd/perl/startup.pl</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +In the <EM>startup.pl</EM> we might have the following code:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>    # retrieve the configuration module path
  +  use Apache:
  +  my $s             = Apache-&gt;server;
  +  my $base_dir      = $s-&gt;dir_config('FooBaseDir')      || '';
  +  my $config_module = $s-&gt;dir_config('FooConfigModule') || '';
  +  die &quot;FooBaseDir and FooConfigModule aren't set in httpd.conf&quot; 
  +    unless $base_dir and $config_module;
  +  
  +    # build the real path to the config module
  +  my $path = &quot;$base_dir/$config_module&quot;;
  +  $path =~ s|::|/|;
  +  $path .= &quot;.pm&quot;;
  +    # we have something like &quot;/home/httpd/foo/Foo/Config.pm&quot;
  +  
  +    # now we can pull in the configuration module
  +  require $path;</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Now we know the module name and it's loaded, so for example if we need to
  +use some variables stored in this module to open a database connection, we
  +will do:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Apache::DBI-&gt;connect_on_init
  +  (&quot;DBI:mysql:${$config_module.'::DB_NAME'}::${$config_module.'::SERVER'}&quot;,
  +   ${$config_module.'::USER'},
  +   ${$config_module.'::USER_PASSWD'},
  +   {
  +    PrintError =&gt; 1, # warn() on errors
  +    RaiseError =&gt; 0, # don't die on error
  +    AutoCommit =&gt; 1, # commit executes immediately
  +   }
  +  );</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +Where variable like:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  ${$config_module.'::USER'}</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +In our example are really:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  $Foo::Config::USER</pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +If you want to access these variable from within your code at the run time,
  +instead accessing to the server object <CODE>$c</CODE>, use the request object <CODE>$r</CODE>:
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  my $r = shift;
  +  my $base_dir      = $r-&gt;dir_config('FooBaseDir')      || '';
  +  my $config_module = $r-&gt;dir_config('FooConfigModule') || '';
  +  </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="The_Scope_of_the_Special_Perl_Va">The Scope of the Special Perl Variables</A></H1></CENTER>
   <P>
   Special Perl variables like <CODE>$|</CODE> (buffering), <CODE>$^T</CODE> (script's start time), <CODE>$^W</CODE> (warnings mode), <CODE>$/</CODE> (input record separator), <CODE>$\</CODE>
  @@ -4227,7 +4419,7 @@
   <td align=center valign=center>
   
   <b><font size=-1>Written by <a
  -href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/05/2000
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 07/27/2000
   </font></b>
   <br>
   
  
  
  
  1.29      +42 -30    modperl-site/guide/porting.html
  
  Index: porting.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/porting.html,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- porting.html	2000/06/07 22:45:36	1.28
  +++ porting.html	2000/08/05 20:48:08	1.29
  @@ -471,11 +471,11 @@
   doesn't occur.
   
   <P>
  -For example if we put the subroutine <CODE>increment_counter()</CODE> into
  -<CODE>mylib.pl</CODE>, save it in the same directory as the main script and
  +For example if we move wrap the code from the script into the subroutine <EM>thecode</EM>, place the both subroutines into the the
  +<EM>mylib.pl</EM> file, save it in the same directory as the script itself and
   <CODE>require()</CODE> it, there will be no problem at all. (Don't forget
  -the <CODE>1;</CODE>
  -at the end of the library or the <CODE>require()</CODE> might fail.)
  +the
  +<CODE>1;</CODE> at the end of the library or the <CODE>require()</CODE> might fail.)
   
   <P>
   
  @@ -489,6 +489,14 @@
   	<td>
   	  <pre>  mylib.pl:
     ---------
  +  my $counter;
  +  sub run{
  +    print &quot;Content-type: text/plain\r\n\r\n&quot;;
  +    $counter = 0;
  +    for (1..5) {
  +      increment_counter();
  +    }
  +  }
     sub increment_counter{
       $counter++;
       print &quot;Counter is equal to $counter !\r\n&quot;;
  @@ -510,30 +518,30 @@
   	<td>
   	  <pre>  counter.pl:
     ----------
  -  #!/usr/bin/perl -w
  -  
     use strict;
     require &quot;./mylib.pl&quot;;
  -  
  -  print &quot;Content-type: text/plain\r\n\r\n&quot;;
  -  
  -  my $counter = 0;
  -  
  -  for (1..5) {
  -    increment_counter();
  -  }</pre>
  +  run();</pre>
           </td>
   	    
         </tr>
       </table>
       <P>
  -Unless the script is very short, I tend to write all the code in external
  -libraries, and to have only a few lines in the main script. Generally the
  -main script simply calls the main function of my library. Usually I call it <CODE>init()</CODE>. I don't worry about nested subroutine effects anymore (unless I create
  +This solution provides the easiest and the fastest way to solve the nested
  +subroutines problem, since all you have to do is to move the code into a
  +separate file, by first wrapping the initial code into some function that
  +you later will call from the script and keeping the lexically scoped
  +variables that could cause the problem out of this function.
  +
  +<P>
  +But as a general rule of thumb, unless the script is very short, I tend to
  +write all the code in external libraries, and to have only a few lines in
  +the main script. Generally the main script simply calls the main function
  +of my library. Usually I call it <CODE>init()</CODE> or
  +<CODE>run()</CODE>. I don't worry about nested subroutine effects anymore (unless I create
   them myself :).
   
   <P>
  -The section '<A HREF="././perl.html#Remedies_for_Inner_Subroutines">Remedies for Inner Subroutines</A>' discusses other possible workarounds for this problem.
  +The section '<A HREF="././perl.html#Remedies_for_Inner_Subroutines">Remedies for Inner Subroutines</A>' discusses many other possible workarounds for this problem.
   
   <P>
   You shouldn't be intimidated by this issue at all, since Perl is your
  @@ -921,7 +929,7 @@
       </table>
       <P>
   Note that this setting will be ignored if you have the
  -<CODE>PerlTaintMode</CODE> mode turned on.
  +<CODE>PerlTaintCheck</CODE> mode turned on.
   
   <P><LI>
   <P>
  @@ -994,8 +1002,8 @@
   checked for modification and you need to do something about that.
   
   <P>
  -So how do we get our modperl-enabled server to recognize changes in library
  -modules? Well, there are a couple of techniques:
  +So how do we get our mod_perl-enabled server to recognize changes in
  +library modules? Well, there are a couple of techniques:
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  @@ -1765,7 +1773,7 @@
     
     print $q-&gt;header(-type=&gt;'text/html');
     print $q-&gt;p(qq{$fname $lname holds the patch pumpkin
  -               for this perl release.});</pre>
  +               for this Perl release.});</pre>
           </td>
   	    
         </tr>
  @@ -1939,7 +1947,7 @@
     my $config_file = &quot;./config.pl&quot;;
     reread_conf($config_file);
     print $q-&gt;p(qq{$fname $lname holds the patch pumpkin
  -               for this perl release.});
  +               for this Perl release.});
     
     sub reread_conf{
       my $file = shift;
  @@ -3206,8 +3214,12 @@
   <HR>
   <CENTER><H1><A NAME="Terminating_requests_and_process">Terminating requests and processes, the exit() and child_terminate() functions</A></H1></CENTER>
   <P>
  -Perl's <CODE>exit()</CODE> built-in function cannot be used in mod_perl scripts. Calling it causes the
  -mod_perl process to exit (which defeats the purpose of using mod_perl). The <CODE>Apache::exit()</CODE> function should be used instead.
  +Perl's <CODE>exit()</CODE> built-in function (all versions prior to 5.6) cannot be used in mod_perl
  +scripts. Calling it causes the mod_perl process to exit (which defeats the
  +purpose of using mod_perl). The
  +<CODE>Apache::exit()</CODE> function should be used instead. Starting from Perl version 5.6 mod_perl
  +will override <CODE>exit()</CODE> behind the scenes, using
  +<CODE>CORE::GLOBAL::</CODE>, a new <EM>magical</EM> package.
   
   <P>
   You might start your scripts by overriding the <CODE>exit()</CODE>
  @@ -4561,7 +4573,7 @@
   <HR>
   <CENTER><H1><A NAME="Passing_ENV_variables_to_CGI">Passing ENV variables to CGI</A></H1></CENTER>
   <P>
  -META: you have a duplication with config.pod here.
  +META: there is a duplication with config.pod here.
   
   <P>
   To pass an environment variable from a configuration file, add to it:
  @@ -5109,9 +5121,9 @@
     sub print_header{
         # prepare a cooke
       my $c = CGI::Cookie-&gt;new
  -      (-name    =&gt; 'sessionID',
  -       -value   =&gt; $sessionID,
  -       -expires =&gt; '+1h');
  +      ('-name'    =&gt; 'sessionID',
  +       '-value'   =&gt; $sessionID,
  +       '-expires' =&gt; '+1h');
       
       print $q-&gt;header
         (-type   =&gt; 'text/html',
  @@ -5882,7 +5894,7 @@
   <td align=center valign=center>
   
   <b><font size=-1>Written by <a
  -href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/07/2000
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 08/03/2000
   </font></b>
   <br>
   
  
  
  
  1.27      +1 -3      modperl-site/guide/scenario.html
  
  Index: scenario.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/scenario.html,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- scenario.html	2000/06/07 22:45:36	1.26
  +++ scenario.html	2000/08/05 20:48:08	1.27
  @@ -3225,8 +3225,6 @@
   	  <pre>  RewriteEngine     on
     RewriteLogLevel   0
     RewriteRule       ^/(perl.*)$  <A HREF="http://127.0.0.1:8052/">http://127.0.0.1:8052/</A>$1   [P,L]
  -  RewriteRule       ^proxy:.*       -                         [F]
  -  ProxyRequests     on
     NoCache           *
     ProxyPassReverse  /  <A HREF="http://www.example.com/">http://www.example.com/</A></pre>
           </td>
  @@ -3627,7 +3625,7 @@
   <td align=center valign=center>
   
   <b><font size=-1>Written by <a
  -href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/31/2000
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 08/05/2000
   </font></b>
   <br>
   
  
  
  
  1.13      +95 -8     modperl-site/guide/security.html
  
  Index: security.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/security.html,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- security.html	2000/06/07 22:45:37	1.12
  +++ security.html	2000/08/05 20:48:08	1.13
  @@ -48,6 +48,7 @@
   		<LI><A HREF="#OK_AUTH_REQUIRED_and_FORBIDDEN_">OK, AUTH_REQUIRED and FORBIDDEN in Authentication handlers</A>
   	</UL>
   
  +	<LI><A HREF="#Apache_Auth_modules">Apache:Auth* modules</A>
   </UL>
   
       </div>
  @@ -126,7 +127,7 @@
   <P>
   You might want to allow user <STRONG>foo</STRONG> to have access to some resource, but restrict her from accessing another
   resource, which in turn is accessible only for user <STRONG>bar</STRONG>. The process of checking access rights is called <STRONG>Authorization</STRONG>. For <STRONG>Authorization</STRONG> all you need is an authenticated username or some other attribute which you
  -can authorize against. For example, you can authorize upon IP number,
  +can authorize against. For example, you can authorize against IP number,
   allowing only your local users to use some service. But be warned that IP
   numbers or session_ids can be spoofed (forged), and that is why you should
   not do
  @@ -172,7 +173,7 @@
   else to require authentication.
   
   <P>
  -Once user passes the authentication stage, either bypassing it because of
  +Once a user passes the authentication stage, either bypassing it because of
   his IP address or after entering a correct login/password pair, the
   <CODE>REMOTE_USER</CODE> variable is set. Then we can talk about authorization.
   
  @@ -295,7 +296,7 @@
   <HR>
   <CENTER><H2><A NAME="Forcing_re_authentication">Forcing re-authentication</A></H2></CENTER>
   <P>
  -To force authenticated user to reauthenticate just send the following
  +To force an authenticated user to reauthenticate just send the following
   header to the browser:
   
   <P>
  @@ -321,8 +322,8 @@
   previous username already in place.
   
   <P>
  -In the Perl API you would use <CODE>note_basic_auth_failure()</CODE> method
  -to force reauthentication.
  +In the Perl API you would use the <CODE>note_basic_auth_failure()</CODE>
  +method to force reauthentication.
   
   <P>
   This may not work! The browser's behaviour is in no way guaranteed.
  @@ -342,7 +343,7 @@
   <CODE>get_basic_auth_pw()</CODE> method.
   
   <P>
  -If there is a failure, unless it's the first time the <CODE>AUTH_REQUIRED</CODE>
  +If there is a failure, unless it's the first time, the <CODE>AUTH_REQUIRED</CODE>
   flag will tell the browser to pop up an authentication window, to try
   again. For example:
   
  @@ -401,7 +402,93 @@
   	    
         </tr>
       </table>
  -    [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
  +<CENTER><H1><A NAME="Apache_Auth_modules">Apache:Auth* modules</A></H1></CENTER>
  +<UL>
  +<P><LI><STRONG><A NAME="item_PerlAuthenHandler">PerlAuthenHandler's</A></STRONG>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Apache::AuthAny           Authenticate with any username/password 
  +  Apache::AuthenCache       Cache authentication credentials        
  +  Apache::AuthCookie        Authen + Authz via cookies              
  +  Apache::AuthenDBI         Authenticate via Perl's DBI             
  +  Apache::AuthExpire        Expire Basic auth credentials           
  +  Apache::AuthenGSS         Generic Security Service (RFC 2078)     
  +  Apache::AuthenIMAP        Authentication via an IMAP server       
  +  Apache::AuthenPasswdSrv   External authentication server          
  +  Apache::AuthenPasswd      Authenticate against /etc/passwd        
  +  Apache::AuthLDAP          LDAP authentication module              
  +  Apache::AuthPerLDAP       LDAP authentication module (PerLDAP)    
  +  Apache::AuthenNIS         NIS authentication                      
  +  Apache::AuthNISPlus       NIS Plus authentication/authorization   
  +  Apache::AuthenRaduis      Authentication via a Radius server      
  +  Apache::AuthenSmb         Authenticate against NT server          
  +  Apache::AuthenURL         Authenticate via another URL            
  +  Apache::DBILogin          Authenticate to backend database        
  +  Apache::DCELogin          Obtain a DCE login context              
  +  Apache::PHLogin           Authenticate via a PH database          
  +  Apache::TicketAccess      Ticket based access/authentication      </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI><STRONG><A NAME="item_PerlAuthzHandler">PerlAuthzHandler's</A></STRONG>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Apache::AuthCookie        Authen + Authz via cookies              
  +  Apache::AuthzAge          Authorize based on age                  
  +  Apache::AuthzDCE          DFS/DCE ACL based access control        
  +  Apache::AuthzDBI          Group authorization via Perl's DBI      
  +  Apache::AuthzGender       Authorize based on gender               
  +  Apache::AuthzNIS          NIS authorization                       
  +  Apache::AuthzPasswd       Authorize against /etc/passwd           
  +  Apache::AuthzSSL          Authorize based on client cert          
  +  Apache::RoleAuthz         Role-based authorization                </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P><LI><STRONG><A NAME="item_PerlAccessHandler">PerlAccessHandler's</A></STRONG>
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  Apache::AccessLimitNum    Limit user access by number of requests 
  +  Apache::BlockAgent        Block access from certain agents        
  +  Apache::DayLimit          Limit access based on day of week       
  +  Apache::IPThrottle        Limit bandwith consumption by IP        
  +  Apache::RobotLimit        Limit access of robots                  
  +  Apache::SpeedLimit        Control client request rate             </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    </UL>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
   
   
  @@ -454,7 +541,7 @@
   <td align=center valign=center>
   
   <b><font size=-1>Written by <a
  -href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/26/2000
   </font></b>
   <br>
   
  
  
  
  1.25      +68 -3     modperl-site/guide/snippets.html
  
  Index: snippets.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/snippets.html,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- snippets.html	2000/06/07 22:45:37	1.24
  +++ snippets.html	2000/08/05 20:48:08	1.25
  @@ -62,6 +62,7 @@
   	<LI><A HREF="#SSI_and_Embperl_Doing_Both">SSI and Embperl - Doing Both</A>
   	<LI><A HREF="#Getting_the_Front_end_Server_s_N">Getting the Front-end Server's Name in the Back-end Server</A>
   	<LI><A HREF="#Authentication_Snippets">Authentication Snippets</A>
  +	<LI><A HREF="#An_example_of_using_Apache_Sess">An example of using Apache::Session::DBI with cookies</A>
   	<LI><A HREF="#Using_DESTROY_to_Finalize_Output">Using DESTROY to Finalize Output</A>
   	<LI><A HREF="#Setting_Environment_Variables_Fo">Setting Environment Variables For Scripts Called From CGI.</A>
   	<LI><A HREF="#Mysql_Backup_and_Restore_Scripts">Mysql Backup and Restore Scripts</A>
  @@ -696,7 +697,7 @@
   <CENTER><H1><A NAME="More_on_Relative_Paths">More on Relative Paths</A></H1></CENTER>
   <P>
   Many people use relative paths for <CODE>require</CODE>, <CODE>use</CODE>, etc., and when they open files in their scripts they make assumptions
  -about the current directory. This will fail if you don't <A HREF="#item_chdir">chdir()</A> to the correct directory first (as could easily happen if you have another
  +about the current directory. This will fail if you don't <CODE>chdir()</CODE> to the correct directory first (as could easily happen if you have another
   script which calls the first script by its full path).
   
   <P>
  @@ -1044,7 +1045,7 @@
   
   	<td>
   	  <pre>   # First handler:
  -   my %my_data = qw(foo =&gt; 1, bar =&gt; 2);
  +   my %my_data = (foo =&gt; 1, bar =&gt; 2);
      $r-&gt;pnotes('my_data' =&gt; \%my_data);</pre>
           </td>
   	    
  @@ -1820,6 +1821,65 @@
       <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
  +<CENTER><H1><A NAME="An_example_of_using_Apache_Sess">An example of using Apache::Session::DBI with cookies</A></H1></CENTER>
  +<P>
  +META: should be annotated at some point. (an example posted to the mod_perl
  +list)
  +
  +<P>
  +
  +    <table>
  +      <tr>
  +
  +	<td bgcolor="blue" width="1">
  +	  &nbsp;
  +        </td>
  +
  +	<td>
  +	  <pre>  use strict;
  +  use DBI;
  +  use Apache::Session::DBI;
  +  use CGI;
  +  
  +  # [...]
  +  
  +  # Initiate a session ID
  +  my $session = ();
  +  my $opts = {  autocommit =&gt; 0, 
  +                lifetime   =&gt; 3600 };     # 3600 is one hour
  +  
  +  # Read in the cookie if this is an old session
  +  my $r = Apache-&gt;request;
  +  my $no_cookie = '';
  +  my $cookie = $r-&gt;header_in('Cookie');
  +  {
  +      # eliminate logging from Apache::Session::DBI's use of `warn'
  +      local $^W = 0;      
  +  
  +      if (defined($cookie) &amp;&amp; $cookie ne '') {
  +          $cookie =~ s/SESSION_ID=(\w*)/$1/;
  +          $session = Apache::Session::DBI-&gt;open($cookie, $opts);
  +          $no_cookie = 'Y' unless defined($session);
  +      }
  +      # Could have been obsolete - get a new one
  +      $session = Apache::Session::DBI-&gt;new($opts) unless defined($session);
  +  }
  +  
  +  # Might be a new session, so let's give them a cookie back
  +  if (! defined($cookie) || $no_cookie) {
  +      local $^W = 0;
  +  
  +      my $session_cookie = &quot;SESSION_ID=$session-&gt;{'_ID'}&quot;;
  +      $r-&gt;header_out(&quot;Set-Cookie&quot; =&gt; $session_cookie);
  +  }
  +  </pre>
  +        </td>
  +	    
  +      </tr>
  +    </table>
  +    <P>
  +[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  +<HR>
   <CENTER><H1><A NAME="Using_DESTROY_to_Finalize_Output">Using DESTROY to Finalize Output</A></H1></CENTER>
   <P>
   Well, as always with Perl -- TMTOWTDI (There's More Than One Way To Do It),
  @@ -2209,6 +2269,11 @@
   These are kinda dirty scripts, but they work... if you come up with cleaner
   scripts, please contribute them... thanks
   
  +<P>
  +Update: there is now a ``mysqlhotcopy'' utility distributed with MySQL that
  +can make an atomic snapshot of a database. (by Tim Bunce) So you may
  +consider using it instead.
  +
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
   <HR>
   
  @@ -2262,7 +2327,7 @@
   <td align=center valign=center>
   
   <b><font size=-1>Written by <a
  -href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/26/2000
   </font></b>
   <br>
   
  
  
  
  1.23      +24 -21    modperl-site/guide/start.html
  
  Index: start.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/start.html,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- start.html	2000/06/07 22:45:37	1.22
  +++ start.html	2000/08/05 20:48:08	1.23
  @@ -79,26 +79,26 @@
   <P>
   <CENTER><H1><A NAME="What_s_inside_">What's inside?</A></H1></CENTER>
   <P>
  -Before you start with mod_perl installation, you should have an overall
  +Before you start a mod_perl installation, you should have an overall
   picture of this wonderful technology. There is more than one way to use a
  -mod_perl-enabled webserver. You have to decide what mod_perl scheme you
  +mod_perl-enabled webserver. You have to decide which mod_perl scheme you
   want to use. <A HREF="././strategy.html#">Picking the Right Strategy</A> chapter presents various approaches and discusses their pros and cons.
   
   <P>
  -Once you know what fits your requirements the best, you should proceed to <A HREF="././scenario.html#">Real World Scenarios Implementation</A>. This chapter provides very detailed scenarios of the schemes discussed in
  +Once you know what best fits your requirements, you should proceed to <A HREF="././scenario.html#">Real World Scenarios Implementation</A>. This chapter provides very detailed scenarios of the schemes discussed in
   the
   <A HREF="././strategy.html#">Picking the Right Strategy</A> chapter.
   
   <P>
  -The <A HREF="././install.html#">Server Installation</A> chapter follows on to the <A HREF="././scenario.html#">Real World Scenarios Implementaion</A> chapter by providing more in-depth installation details.
  +The <A HREF="././install.html#">Server Installation</A> chapter follows on from the <A HREF="././scenario.html#">Real World Scenarios Implementaion</A> chapter by providing more in-depth installation details.
   
   <P>
   The <A HREF="././config.html#">Server Configuration</A> chapter adds to the basic configurations presented in the <A HREF="././scenario.html#">Real World Scenarios Implementaion</A> chapter with extended configurations and various configuration examples.
   
   <P>
  -The <A HREF="././frequent.html#">Frequent mod_perl problems</A> chapter just collects links to other chapters. It is an attempt to stress
  -some of the most frequently encountered mod_perl problems. So this is the
  -first place you should check if you have got a problem.
  +The <A HREF="././frequent.html#">Frequent mod_perl problems</A> chapter is a collection of links to other chapters. It is an attempt to
  +stress some of the most frequently encountered mod_perl problems. So this
  +is the first place you should check if you have got a problem.
   
   <P>
   Probably the most important chapter is <A HREF="././porting.html#">CGI to mod_perl Porting. mod_perl Coding guidelines</A>. It explains the differences between scripts running under mod_cgi and
  @@ -154,7 +154,7 @@
   chapter shows you the ways you can peek at what is going on in a
   mod_perl-enabled server while it is running. Like looking at the value of
   some global variable, what database connections are open, looking up what
  -modules were loaded and their paths, what is the value of
  +modules are loaded and their paths, what is the value of
   <CODE>@INC</CODE>, and much more.
   
   <P>
  @@ -162,34 +162,37 @@
   task with plain Perl. Just invoke the program with the <CODE>-d</CODE>
   flag and debug it. Is it possible to do the same under mod_perl? After all
   you cannot debug every CGI script by executing it from the command line:
  -some scripts will not run from the command line. The <A HREF="././debug.html#">Debugging mod_perl</A> chapter proves debugging under mod_perl is possible and real.
  +some scripts will not run from the command line. The <A HREF="././debug.html#">Debugging mod_perl</A> chapter proves debugging under mod_perl is possible.
   
   <P>
   Sometimes browsers that interact with our servers have bugs, which cause
  -big headaches for CGI developers. Preventing these bugs from happening is
  -discussed in the <A HREF="././browserbugs.html#">Workarounds for some known bugs in browsers</A> chapter.
  +big headaches for CGI developers. Coping with these bugs is discussed in
  +the <A HREF="././browserbugs.html#">Workarounds for some known bugs in browsers</A> chapter.
   
   <P>
  -Many modules were written to extend the mod_perl's core functionality. Some
  +Many modules were written to extend mod_perl's core functionality. Some
   important modules are covered in the <A HREF="././modules.html#">Apache::* modules</A> chapter.
   
   <P>
  -Some folks decide to go with mod_perl, but they are missing a basic
  -understanding of Perl, which is absolutely not tolerated by mod_perl. If
  -you are such a person, there is nothing to be ashamed of; we all went
  -through this. Get a good Perl book and start reading. The
  -<A HREF="././perl.html#">Perl Reference</A> chapter gives some basic perl lessons, delivering the knowledge without
  -which you cannot start to program mod_perl scripts.
  +Some folks decide to go with mod_perl even though they are not experienced
  +Perl programmers. mod_perl is a demanding environment which does not permit
  +the `casual' programming style which plain Perl allows. Lack of
  +knowledge/experience with Perl need not be any barrier; Perl comes with
  +copious and high quality on-line documentation and there are many Perl
  +books available which will get you up to speed. Get a good Perl book and
  +start reading. The <A HREF="././perl.html#">Perl Reference</A> chapter gives some basic, mod_perl specific Perl lessons, delivering the
  +knowledge without which you cannot start to program mod_perl scripts.
   
   <P>
   The <A HREF="././snippets.html#">Code Snippets</A> chapter is just a collection of code snippets I have found useful while
   writing the scripts.
   
   <P>
  -The <A HREF="././hardware.html#">Choosing an Operating System and Hardware</A> chapter gives you an idea on how to choose the SW and HW for the webserver.
  +The <A HREF="././hardware.html#">Choosing an Operating System and Hardware</A> chapter gives you an idea on how to choose the software and hardware for
  +the webserver.
   
   <P>
  -The <A HREF="././advocacy.html#">mod_perl Advocacy</A> tries to help to make it easier to advocate mod_perl around the world.
  +The <A HREF="././advocacy.html#">mod_perl Advocacy</A> tries to make it easier to advocate mod_perl around the world.
   
   <P>
   The <A HREF="././help.html#">Getting Help and Further Learning</A> chapter refers you to other related information resources, like learning
  @@ -254,7 +257,7 @@
   <td align=center valign=center>
   
   <b><font size=-1>Written by <a
  -href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/19/2000
   </font></b>
   <br>
   
  
  
  
  1.7       +25 -24    modperl-site/guide/troubleshooting.html
  
  Index: troubleshooting.html
  ===================================================================
  RCS file: /home/cvs/modperl-site/guide/troubleshooting.html,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- troubleshooting.html	2000/06/07 22:45:37	1.6
  +++ troubleshooting.html	2000/08/05 20:48:08	1.7
  @@ -185,9 +185,9 @@
         </tr>
       </table>
       <P>
  -The above error seems to indicate that Perl was compiled with a shared
  -library. mod_perl does detect this and links the Apache executable to the
  -Perl shared library (<EM>libperl.so</EM>).
  +it probably means that Perl was compiled with a shared library. mod_perl
  +does detect this and links the Apache executable to the Perl shared library
  +(<EM>libperl.so</EM>).
   
   <P>
   First of all make sure you have Perl installed on the machine, and that you
  @@ -221,7 +221,7 @@
       </table>
       <P>
   This can happen when you have a mod_perl enabled Apache compiled with DSO
  -(Generally it's an installed RPM or other binary package) but the mod_perl
  +(generally it's an installed RPM or other binary package) but the mod_perl
   module isn't loaded. In this case you have to tell Apache to load mod_perl
   by adding:
   
  @@ -440,7 +440,7 @@
   Solaris OS specific:
   
   <P>
  -``<CODE>Can't load DBI</CODE>'' or similar Error for the IO module or whatever dynamic module mod_perl
  +``<CODE>Can't load DBI</CODE>'' or similar error for the IO module or whatever dynamic module mod_perl
   tries to pull in first. The solution is to re-configure, re-build and
   re-install Perl and dynamic modules with the following flags when Configure
   asks for ``<CODE>additional LD flags</CODE>'':
  @@ -547,7 +547,8 @@
   see the rwrite messages if <CODE>LogLevel</CODE> is set to <CODE>debug</CODE>.
   
   <P>
  -There was a bug that reported this debug message regardless of the value of <CODE>LogLevel</CODE> directive. It was fixed in mod_perl 1.19_01 (<A HREF="././download.html#mod_perl">CVS version</A>).
  +There was a bug that reported this debug message regardless of the value of
  +the <CODE>LogLevel</CODE> directive. It was fixed in mod_perl 1.19_01 (<A HREF="././download.html#mod_perl">CVS version</A>).
   
   <P>
   Generally <CODE>LogLevel</CODE> is either <CODE>debug</CODE> or <CODE>info</CODE>.  <CODE>debug</CODE> logs everything, <CODE>info</CODE> is the next level, which doesn't include debug messages. You shouldn't use
  @@ -582,9 +583,10 @@
         </tr>
       </table>
       <P>
  -That's the <CODE>$SIG{PIPE}</CODE> handler installed by mod_perl/<CODE>Apache::SIG</CODE>, which is called if a connection times out or Client presses the 'Stop'
  -button. It gives you an opportunity to do cleanups if the script was
  -aborted in the middle of its execution. See <A HREF="././debug.html#Handling_the_User_pressed_Stop_">Handling the 'User pressed Stop button' case</A> for more info.
  +That's the <CODE>$SIG{PIPE}</CODE> handler installed by mod_perl/<CODE>Apache::SIG</CODE>, which is called if a connection times out or if the client presses the
  +'Stop' button. It gives you an opportunity to do cleanups if the script was
  +aborted in the middle of its execution. See <A HREF="././debug.html#Handling_the_User_pressed_Stop_">Handling the 'User pressed Stop button' case</A>
  +for more info.
   
   <P>
   If your mod_perl version is earlier than 1.17 you might also get the
  @@ -698,7 +700,7 @@
   lines) is printed to the <EM>error_log</EM> file as code that the server has tried to <CODE>eval()</CODE>uate.
   
   <P>
  -May be you have a <CODE>$SIG{__DIE__}</CODE> handler installed (<CODE>Carp::confess()</CODE>?). If so that's what's expected if so.
  +May be you have a <CODE>$SIG{__DIE__}</CODE> handler installed (<CODE>Carp::confess()</CODE>?). If so that's what's expected.
   
   <P>
   You might wish to try something more terse such as "local
  @@ -750,8 +752,8 @@
         </tr>
       </table>
       <P>
  -In the second case, <CODE>$param</CODE> will always be <CODE>defined</CODE>, either
  -<CODE>$q-&gt;param('test')</CODE> returns some value or <CODE>undef</CODE>.
  +In the second case, <CODE>$param</CODE> will always be <CODE>defined</CODE>, either with
  +<CODE>$q-&gt;param('test')</CODE>'s return value, or if the parameter doesn't exist or is <CODE>undef</CODE>ined then the empty string, <CODE>''</CODE>, will be assigned to <CODE>$param</CODE>.
   
   <P>
   Also read about <A HREF="././debug.html#Finding_the_Line_Which_Triggered">Finding the Line Which Triggered the Error or Warning</A>.
  @@ -770,7 +772,7 @@
   <P>
   <EM>Callback called exit</EM> is just a generic message when some unrecoverable error occurs inside Perl
   during <CODE>perl_call_sv()</CODE> (which mod_perl uses to invoke all handler subroutines. Such problems seem
  -far less with 5.005_03 than 5.004.
  +to occur far less with 5.005_03 than 5.004.
   
   <P>
   Sometimes you discover that your server is not responding and its error_log
  @@ -1064,13 +1066,13 @@
   That's a mandatory warning inside Perl which happens only if you modify
   your script and Apache::Registry reloads it. Perl is warning you that the
   <CODE>subroutine(s)</CODE> were redefined. It is mostly harmless. If you
  -don't like seeing these warnings, just <CODE>kill -USR2</CODE> (graceful restart) Apache when you modify your scripts.
  +don't like seeing these warnings, just <CODE>kill -USR1</CODE> (graceful restart) Apache when you modify your scripts.
   
   <P>
  -You aren't supposed to see these warnings when if don't modify the code
  -with perl 5.004_05 or 5.005+.and higher. If you still experince a problem
  -with code within a CGI script, moving all the code into a module (or a
  -library) and <CODE>require()ing</CODE> it should solve the problem.
  +You aren't supposed to see these warnings if you don't modify the code with
  +perl 5.004_05 or 5.005+.and higher. If you still experience a problem with
  +code within a CGI script, moving all the code into a module (or a library)
  +and <CODE>require()ing</CODE> it should solve the problem.
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  @@ -1109,10 +1111,10 @@
   <P>
   From mod_perl.pod: With Apache versions 1.3.0 and higher, mod_perl will
   call the <CODE>perl_destruct()</CODE> Perl API function during the child
  -exit phase. This will cause proper execution of <CODE>END</CODE> blocks found during server startup along with invoking the <CODE>DESTROY</CODE> method on global objects who are still alive. It is possible that this
  +exit phase. This will cause proper execution of <CODE>END</CODE> blocks found during server startup as well as invoking the <CODE>DESTROY</CODE> method on global objects which are still alive. It is possible that this
   operation may take a long time to finish, causing problems during a
  -restart. If your code does not contain and <CODE>END</CODE> blocks or <CODE>DESTROY</CODE> methods which need to be run during child server shutdown, this destruction
  -can be avoided by setting the <CODE>PERL_DESTRUCT_LEVEL</CODE> environment variable to <CODE>-1</CODE>.
  +restart. If your code does not contain any <CODE>END</CODE> blocks or <CODE>DESTROY</CODE> methods which need to be run during child server shutdown, this destruction
  +can be avoided by setting the <CODE>PERL_DESTRUCT_LEVEL</CODE> environment variable to <CODE>-1</CODE>. Be aware that `your code' includes any modules you use and <EM>they</EM> may well have <CODE>DESTROY</CODE> and <CODE>END</CODE> blocks...
   
   <P>
   [ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]
  @@ -1171,8 +1173,7 @@
         </tr>
       </table>
       <P>
  -at the top of mod_perl.h or add it to the defines in MSVC++ Options
  -dialog).
  +at the top of <EM>mod_perl.h</EM> or add it to the defines in the MSVC++ and similar applications' <CODE>Options</CODE> dialog).
   
   <P>
   Apache loads all Apache modules twice, to make sure the server will
  @@ -1233,7 +1234,7 @@
   <td align=center valign=center>
   
   <b><font size=-1>Written by <a
  -href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 05/27/2000
  +href="help.html#Contacting_me">Stas Bekman</a>.<br> Last Modified at 06/15/2000
   </font></b>
   <br>