First cut at integrating Apache-SizeLimit into mp2 dynamic builds.

Note: this requires corresponding changes in Apache-SizeLimit s 
      top-level Makefile.PL

TODO:
  Do we want to run the Apache-SizeLimit test-suite during mp2's make test ?
  static builds



git-svn-id: https://svn.apache.org/repos/asf/perl/modperl/branches/apache_sizelimit_integration@441417 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/Makefile.PL b/Makefile.PL
index c53cc17..4c3ab6f 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -119,10 +119,12 @@
     # mod_perl test suite relies on having Apache-Test bundled with
     # the mod_perl source, since any pre-installed version may not do
     # the right thing
-    unless (-d "Apache-Test") {
-        error "Can't find a sub-directory Apache-Test. " .
-            "Make sure that you are using a complete source distribution";
-        exit 1;
+    foreach my $dir (qw(Apache-Test Apache-SizeLimit)) {
+        unless (-d $dir) {
+            error "Can't find a sub-directory $dir. " .
+                "Make sure that you are using a complete source distribution";
+            exit 1;
+        }
     }
 
     set_modperl_version();
@@ -225,6 +227,7 @@
 
     if ($build->{MP_APXS}) {
         debug "Using APXS => $build->{MP_APXS}";
+        $ENV{MP_APXS} = $build->{MP_APXS}; # for Apache-SizeLimit
     }
     elsif ($build->{MP_AP_PREFIX}) {
         if (my $reason = $build->ap_prefix_invalid) {
diff --git a/lib/Apache2/SizeLimit.pm b/lib/Apache2/SizeLimit.pm
deleted file mode 100644
index 558e7db..0000000
--- a/lib/Apache2/SizeLimit.pm
+++ /dev/null
@@ -1,281 +0,0 @@
-# Copyright 2003-2006 The Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-package Apache2::SizeLimit;
-
-use strict;
-use warnings FATAL => 'all';
-
-use mod_perl2;
-
-use Apache2::RequestRec ();
-use Apache2::RequestUtil ();
-use Apache2::MPM ();
-use APR::Pool ();
-use ModPerl::Util ();
-
-use Config;
-
-use constant WIN32    => $^O eq 'MSWin32';
-use constant SOLARIS  => $^O eq 'solaris';
-use constant LINUX    => $^O eq 'linux';
-use constant BSD_LIKE => $^O =~ /(bsd|aix)/i;
-
-use Apache2::Const -compile => qw(OK DECLINED);
-
-our $VERSION = '0.05';
-
-our $CHECK_EVERY_N_REQUESTS = 1;
-our $REQUEST_COUNT          = 1;
-our $MAX_PROCESS_SIZE       = 0;
-our $MIN_SHARE_SIZE         = 0;
-our $MAX_UNSHARED_SIZE      = 0;
-our $USE_SMAPS              = 1;
-
-our ($HOW_BIG_IS_IT, $START_TIME);
-
-BEGIN {
-
-    die "Apache2::SizeLimit at the moment works only with non-threaded MPMs"
-        if Apache2::MPM->is_threaded();
-
-    # decide at compile time how to check for a process' memory size.
-    if (SOLARIS && $Config{'osvers'} >= 2.6) {
-
-        $HOW_BIG_IS_IT = \&solaris_2_6_size_check;
-
-    }
-    elsif (LINUX) {
-        if ( eval { require Linux::Smaps } and Linux::Smaps->new($$) ) {
-            $HOW_BIG_IS_IT = \&linux_smaps_size_check_first_time;
-        }
-        else {
-            $USE_SMAPS = 0;
-            $HOW_BIG_IS_IT = \&linux_size_check;
-        }
-    }
-    elsif (BSD_LIKE) {
-
-        # will getrusage work on all BSDs?  I should hope so.
-        if ( eval { require BSD::Resource } ) {
-            $HOW_BIG_IS_IT = \&bsd_size_check;
-        }
-        else {
-            die "you must install BSD::Resource for Apache2::SizeLimit " .
-                "to work on your platform.";
-        }
-
-#  Currently unsupported for mp2 because of threads...
-#     }
-#      elsif (WIN32) {
-# 
-#         if ( eval { require Win32::API } ) {
-#             $HOW_BIG_IS_IT = \&win32_size_check;
-#         }
-#          else {
-#             die "you must install Win32::API for Apache2::SizeLimit " .
-#                 "to work on your platform.";
-#         }
-
-    }
-    else {
-
-        die "Apache2::SizeLimit not implemented on $^O";
-
-    }
-}
-
-sub linux_smaps_size_check_first_time {
-
-    if ($USE_SMAPS) {
-        $HOW_BIG_IS_IT = \&linux_smaps_size_check;
-    } else {
-        $HOW_BIG_IS_IT = \&linux_size_check;
-    }
-
-    goto &$HOW_BIG_IS_IT;
-}
-
-sub linux_smaps_size_check {
-
-    my $s = Linux::Smaps->new($$)->all;
-    return ($s->size, $s->shared_cleani + $s->shared_dirty);
-}
-
-# return process size (in KB)
-sub linux_size_check {
-    my ($size, $resident, $share) = (0, 0, 0);
-
-    my $file = "/proc/self/statm";
-    if (open my $fh, "<$file") {
-        ($size, $resident, $share) = split /\s/, scalar <$fh>;
-        close $fh;
-    }
-    else {
-        error_log("Fatal Error: couldn't access $file");
-    }
-
-    # linux on intel x86 has 4KB page size...
-    return ($size * 4, $share * 4);
-}
-
-sub solaris_2_6_size_check {
-    my $file = "/proc/self/as";
-    my $size = -s $file
-        or &error_log("Fatal Error: $file doesn't exist or is empty");
-    $size = int($size / 1024); # in Kb
-    return ($size, 0);
-}
-
-# rss is in KB but ixrss is in BYTES.
-# This is true on at least FreeBSD, OpenBSD, NetBSD
-# Philip M. Gollucci
-sub _bsd_size_check {
-
-    my @results = BSD::Resource::getrusage();
-    my $max_rss   = $results[2];
-    my $max_ixrss = int ( $results[3] / 1024 );
-
-    return ( $max_rss, $max_ixrss );
-}
-
-sub win32_size_check {
-
-    # get handle on current process
-    my $GetCurrentProcess =
-        Win32::API->new( 'kernel32', 'GetCurrentProcess', [], 'I' );
-    my $hProcess = $GetCurrentProcess->Call();
-
-    # memory usage is bundled up in ProcessMemoryCounters structure
-    # populated by GetProcessMemoryInfo() win32 call
-    my $DWORD  = 'B32';    # 32 bits
-    my $SIZE_T = 'I';      # unsigned integer
-
-    # build a buffer structure to populate
-    my $pmem_struct            = "$DWORD" x 2 . "$SIZE_T" x 8;
-    my $pProcessMemoryCounters =
-        pack $pmem_struct, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
-
-    # GetProcessMemoryInfo is in "psapi.dll"
-    my $GetProcessMemoryInfo = Win32::API->new('psapi',
-                                               'GetProcessMemoryInfo',
-                                               [ 'I', 'P', 'I' ], 'I' );
-
-    my $bool =
-        $GetProcessMemoryInfo->Call($hProcess, $pProcessMemoryCounters,
-                                    length $pProcessMemoryCounters);
-
-    # unpack ProcessMemoryCounters structure
-    my $PeakWorkingSetSize =
-        (unpack $pmem_struct, $pProcessMemoryCounters)[2];
-
-    # only care about peak working set size
-    my $size = int($PeakWorkingSetSize / 1024);
-
-    return ($size, 0);
-}
-
-sub exit_if_too_big {
-    my $r = shift;
-
-    #warn "Apache2::Size::Limit exit sub called";
-
-    return Apache2::Const::DECLINED if $CHECK_EVERY_N_REQUESTS &&
-        ($REQUEST_COUNT++ % $CHECK_EVERY_N_REQUESTS);
-
-    $START_TIME ||= time;
-
-    my ($size, $share) = $HOW_BIG_IS_IT->();
-    my $unshared = $size - $share;
-
-    my $kill_size     = $MAX_PROCESS_SIZE  && $size > $MAX_PROCESS_SIZE;
-    my $kill_share    = $MIN_SHARE_SIZE    && $share < $MIN_SHARE_SIZE;
-    my $kill_unshared = $MAX_UNSHARED_SIZE && $unshared > $MAX_UNSHARED_SIZE;
-
-    if ($kill_size || $kill_share || $kill_unshared) {
-        # wake up! time to die.
-        if (WIN32 || ( getppid > 1 )) {
-            # this is a child httpd
-            my $e   = time - $START_TIME;
-            my $msg = "httpd process too big, exiting at SIZE=$size/$MAX_PROCESS_SIZE KB ";
-            $msg .= " SHARE=$share/$MIN_SHARE_SIZE KB " if $share;
-            $msg .= " UNSHARED=$unshared/$MAX_UNSHARED_SIZE KB " if $unshared;
-            $msg .= " REQUESTS=$REQUEST_COUNT LIFETIME=$e seconds";
-            error_log($msg);
-
-            $r->child_terminate();
-        }
-        else {    # this is the main httpd, whose parent is init?
-            my $msg = "main process too big, SIZE=$size/$MAX_PROCESS_SIZE KB ";
-            $msg .= " SHARE=$share/$MIN_SHARE_SIZE KB" if $share;
-            $msg .= " UNSHARED=$unshared/$MAX_UNSHARED_SIZE KB" if $unshared;
-            error_log($msg);
-        }
-    }
-
-    return Apache2::Const::OK;
-}
-
-# setmax can be called from within a CGI/Registry script to tell the httpd
-# to exit if the CGI causes the process to grow too big.
-sub setmax {
-    $MAX_PROCESS_SIZE = shift;
-    my $r = shift || Apache2::RequestUtil->request();
-    unless ($r->pnotes('size_limit_cleanup')) {
-        $r->pool->cleanup_register(\&exit_if_too_big, $r);
-        $r->pnotes('size_limit_cleanup', 1);
-    }
-}
-
-sub setmin {
-    $MIN_SHARE_SIZE = shift;
-    my $r = shift || Apache2::RequestUtil->request();
-    unless ($r->pnotes('size_limit_cleanup')) {
-        $r->pool->cleanup_register(\&exit_if_too_big, $r);
-        $r->pnotes('size_limit_cleanup', 1);
-    }
-}
-
-sub setmax_unshared {
-    $MAX_UNSHARED_SIZE = shift;
-    my $r = shift || Apache2::RequestUtil->request();
-    unless ($r->pnotes('size_limit_cleanup')) {
-        $r->pool->cleanup_register(\&exit_if_too_big, $r);
-        $r->pnotes('size_limit_cleanup', 1);
-    }
-}
-
-sub handler {
-    my $r = shift;
-
-    if ($r->is_initial_req()) {
-        # we want to operate in a cleanup handler
-        if (ModPerl::Util::current_callback() eq 'PerlCleanupHandler') {
-            exit_if_too_big($r);
-        }
-        else {
-            $r->pool->cleanup_register(\&exit_if_too_big, $r);
-        }
-    }
-
-    return Apache2::Const::DECLINED;
-}
-
-sub error_log {
-    print STDERR "[", scalar(localtime time),
-        "] ($$) Apache2::SizeLimit @_\n";
-}
-
-1;
-
diff --git a/t/conf/post_config_startup.pl b/t/conf/post_config_startup.pl
index 8bc9947..d8855c3 100644
--- a/t/conf/post_config_startup.pl
+++ b/t/conf/post_config_startup.pl
@@ -70,7 +70,7 @@
     if ($@) {
         # unsupported platform
         die $@ unless $@ =~ /Apache2::SizeLimit not implemented on/
-            or $@ =~ /you must install BSD::Resource/;
+            or $@ =~ /You must install BSD::Resource/;
     }
 }