Author: stas
Date: Wed Dec  1 16:04:07 2004
New Revision: 109401

URL: http://svn.apache.org/viewcvs?view=rev&rev=109401
Log:
port Apache::Resource

Added:
   perl/modperl/trunk/lib/Apache/Resource.pm
   perl/modperl/trunk/t/modules/apache_resource.t
Modified:
   perl/modperl/trunk/t/conf/modperl_extra.pl
   perl/modperl/trunk/todo/release

Added: perl/modperl/trunk/lib/Apache/Resource.pm
Url: 
http://svn.apache.org/viewcvs/perl/modperl/trunk/lib/Apache/Resource.pm?view=auto&rev=109401
==============================================================================
--- (empty file)
+++ perl/modperl/trunk/lib/Apache/Resource.pm   Wed Dec  1 16:04:07 2004
@@ -0,0 +1,149 @@
+# Copyright 2003-2004 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 Apache::Resource;
+
+use strict;
+use warnings FATAL => 'all';
+
+use mod_perl 1.99;
+
+use Apache::Module ();
+
+use BSD::Resource qw(setrlimit getrlimit get_rlimits);
+
+use Apache::Const -compile => qw(OK);
+
+$Apache::Resource::VERSION = '1.72';
+
+our $Debug;
+
+$Debug ||= 0;
+
+sub MB ($) {
+    my $num = shift;
+    return ($num < (1024 * 1024)) ?  $num*1024*1024 : $num;
+}
+
+sub BM ($) {
+    my $num = shift;
+    return ($num > (1024 * 1024)) ?  '(' . ($num>>20) . 'Mb)' : '';
+}
+
+sub DEFAULT_RLIMIT_DATA  () { 64   } # data (memory) size in MB
+sub DEFAULT_RLIMIT_AS    () { 64   } # address space (memory) size in MB
+sub DEFAULT_RLIMIT_CPU   () { 60*6 } # cpu time in seconds
+sub DEFAULT_RLIMIT_CORE  () { 0    } # core file size (MB)
+sub DEFAULT_RLIMIT_RSS   () { 16   } # resident set size (MB)
+sub DEFAULT_RLIMIT_FSIZE () { 10   } # file size  (MB)
+sub DEFAULT_RLIMIT_STACK () { 20   } # stack size (MB)
+
+my %is_mb = map {$_, 1} qw{DATA RSS STACK FSIZE CORE MEMLOCK AS};
+
+sub debug { print STDERR @_ if $Debug }
+
+sub install_rlimit ($$$) {
+    my($res, $soft, $hard) = @_;
+
+    my $name = $res;
+
+    my $cv = \&{"BSD::Resource::RLIMIT_${res}"};
+    eval { $res = $cv->() };
+    return if $@;
+
+    unless ($soft) {
+       my $defval = \&{"DEFAULT_RLIMIT_${name}"};
+       if (defined &$defval) {
+           $soft = $defval->();
+       }
+       else {
+           warn "can't find default for `$defval'\n";
+       }
+    }
+
+    $hard ||= $soft;
+
+    debug "Apache::Resource: PID $$ attempting to set `$name'=$soft:$hard ...";
+
+    ($soft, $hard) = (MB $soft, MB $hard) if $is_mb{$name};
+
+    return setrlimit $res, $soft, $hard;
+}
+
+sub handler {
+    while (my($k, $v) = each %ENV) {
+       next unless $k =~ /^PERL_RLIMIT_(\w+)$/;
+       $k = $1;
+       next if $k eq "DEFAULTS";
+       my($soft, $hard) = split ":", $v, 2;
+       $hard ||= $soft;
+
+       my $set = install_rlimit $k, $soft, $hard;
+       debug "not " unless $set;
+       debug "ok\n";
+       debug $@ if $@;
+    }
+
+    Apache::OK;
+}
+
+sub default_handler {
+    while (my($k, $v) = each %Apache::Resource::) {
+       next unless $k =~ s/^DEFAULT_/PERL_/;
+       $ENV{$k} = "";
+    }
+    handler();
+}
+
+sub status_rlimit {
+    my $lim = get_rlimits();
+    my @retval = ("<table border=1><tr>",
+                 (map "<th>$_</th>", qw(Resource Soft Hard)),
+                 "</tr>");
+
+    for my $res (keys %$lim) {
+       my $val = eval "&BSD::Resource::${res}()";
+       my($soft, $hard) = getrlimit $val;
+       (my $limit = $res) =~ s/^RLIMIT_//;
+       ($soft, $hard) = ("$soft " . BM($soft), "$hard ". BM($hard))
+            if $is_mb{$limit};
+       push @retval,
+            "<tr>", (map { "<td>$_</td>" } $res, $soft, $hard), "</tr>\n";
+    }
+
+    push @retval, "</table><P>";
+    push @retval, "<small>Apache::Resource $Apache::Resource::VERSION</small>";
+
+    return [EMAIL PROTECTED];
+}
+
+if ($ENV{MOD_PERL}) {
+    if ($ENV{PERL_RLIMIT_DEFAULTS}) {
+       Apache->server->push_handlers(
+            PerlChildInitHandler => \&default_handler);
+    }
+
+    Apache::Status->menu_item(rlimit => "Resource Limits",
+                              \&status_rlimit)
+          if Apache::Module::loaded("Apache::Status");
+}
+
+# perl Apache/Resource.pm
+++$Debug, default_handler unless caller();
+
+1;
+
+__END__
+

Modified: perl/modperl/trunk/t/conf/modperl_extra.pl
Url: 
http://svn.apache.org/viewcvs/perl/modperl/trunk/t/conf/modperl_extra.pl?view=diff&rev=109401&p1=perl/modperl/trunk/t/conf/modperl_extra.pl&r1=109400&p2=perl/modperl/trunk/t/conf/modperl_extra.pl&r2=109401
==============================================================================
--- perl/modperl/trunk/t/conf/modperl_extra.pl  (original)
+++ perl/modperl/trunk/t/conf/modperl_extra.pl  Wed Dec  1 16:04:07 2004
@@ -47,6 +47,8 @@
 
 test_apache_status();
 
+test_apache_resource();
+
 test_perl_ithreads();
 
 
@@ -163,6 +165,23 @@
        }
     ) if Apache::Module::loaded('Apache::Status');
 }
+
+sub test_apache_resource {
+    ### Apache::Resource tests
+
+    # load first for the menu
+    require Apache::Status;
+
+    # uncomment for local tests
+    #$ENV{PERL_RLIMIT_DEFAULTS} = 1;
+    #$Apache::Resource::Debug   = 1;
+
+    # requires optional BSD::Resource
+    return unless eval { require BSD::Resource };
+
+    require Apache::Resource;
+}
+
 
 sub test_perl_ithreads {
     # this is needed for TestPerl::ithreads

Added: perl/modperl/trunk/t/modules/apache_resource.t
Url: 
http://svn.apache.org/viewcvs/perl/modperl/trunk/t/modules/apache_resource.t?view=auto&rev=109401
==============================================================================
--- (empty file)
+++ perl/modperl/trunk/t/modules/apache_resource.t      Wed Dec  1 16:04:07 2004
@@ -0,0 +1,25 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 1, need qw[BSD::Resource],
+    { "CGI.pm (2.93 or higher) or Apache::Request is needed" =>
+          !!(eval { require CGI && $CGI::VERSION >= 2.93 } ||
+             eval { require Apache::Request })};
+
+{
+    # Apache::Status menu inserted by Apache::Resource
+    my $url = '/status/perl?rlimit';
+    my $body = GET_BODY_ASSERT $url;
+    ok $body =~ /RLIMIT_CPU/;
+}
+
+# more tests would be nice, but I'm not sure how to write those w/o
+# causing problems to the rest of the test suite.
+# we could enable $ENV{PERL_RLIMIT_DEFAULTS} = 1; before loading
+# Apache::Resource, which sets certain default values (works for me)
+# but it's not guaranteed that it'll work for others (since it's very
+# OS specific)

Modified: perl/modperl/trunk/todo/release
Url: 
http://svn.apache.org/viewcvs/perl/modperl/trunk/todo/release?view=diff&rev=109401&p1=perl/modperl/trunk/todo/release&r1=109400&p2=perl/modperl/trunk/todo/release&r2=109401
==============================================================================
--- perl/modperl/trunk/todo/release     (original)
+++ perl/modperl/trunk/todo/release     Wed Dec  1 16:04:07 2004
@@ -58,8 +58,6 @@
   => Ideally the tools should work transparently with threaded and
   non-threaded mpms, but how?
 
-* Apache::Resource
-
 * It'd be nice to have PAUSE and the clients support packages with
   several versions, like mod_perl 1.0 and mod_perl 2.0, since once we
   release it any dependency on mod_perl will be resolved as mod_perl

Reply via email to