I have a patch for Apache::SizeLimit which I'd like to get into the 1.28
build, but CVS is not cooperating with me. I guess I don't have
permission to update the modperl tree.
Can someone commit this for me? I'm attaching a SizeLimit patch and a
patch to Changes that describes it.
- Perrin
--- ../../../mod_perl-1.27/lib/Apache/SizeLimit.pm 2002-03-23 20:51:45.000000000
-0500
+++ SizeLimit.pm 2003-05-29 23:55:57.000000000 -0400
@@ -18,9 +18,7 @@
$Apache::SizeLimit::MAX_UNSHARED_SIZE = 12000; # 12MB
# in your httpd.conf:
- PerlFixupHandler Apache::SizeLimit
- # you can set this up as any Perl*Handler that handles part of the
- # request, even the LogHandler will do.
+ PerlCleanupHandler Apache::SizeLimit
Or you can just check those requests that are likely to get big, such as
CGI requests. This way of checking is also easier for those who are mostly
@@ -127,6 +125,11 @@
Uses BSD::Resource::getrusage() to determine process size. Not sure if the
shared memory calculations will work or not. AIX users?
+=item Win32
+
+Uses Win32::API to access process memory information. Win32::API can be
+installed under ActiveState perl using the supplied ppm utility.
+
=back
If your platform is not supported, and if you can tell me how to check for
@@ -148,7 +151,7 @@
use strict;
use vars qw($VERSION $HOW_BIG_IS_IT $MAX_PROCESS_SIZE
$REQUEST_COUNT $CHECK_EVERY_N_REQUESTS
- $MIN_SHARE_SIZE $MAX_UNSHARED_SIZE $START_TIME);
+ $MIN_SHARE_SIZE $MAX_UNSHARED_SIZE $START_TIME $WIN32);
$VERSION = '0.03';
$CHECK_EVERY_N_REQUESTS = 1;
@@ -156,6 +159,7 @@
$MAX_PROCESS_SIZE = 0;
$MIN_SHARE_SIZE = 0;
$MAX_UNSHARED_SIZE = 0;
+$WIN32 = 0;
BEGIN {
@@ -172,6 +176,13 @@
} else {
die "you must install BSD::Resource for Apache::SizeLimit to work on your
platform.";
}
+ } elsif ($Config{'osname'} eq 'MSWin32') {
+ $WIN32 = 1;
+ if (eval("require Win32::API")) {
+ $HOW_BIG_IS_IT = \&win32_size_check;
+ } else {
+ die "you must install Win32::API for Apache::SizeLimit to work on your
platform.";
+ }
} else {
die "Apache::SizeLimit not implemented on your platform.";
}
@@ -202,6 +213,53 @@
return (&BSD::Resource::getrusage())[2,3];
}
+sub win32_size_check {
+ # get handle on current process
+ my $GetCurrentProcess = new Win32::API('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 = new Win32::API('psapi',
+ 'GetProcessMemoryInfo',
+ ['I', 'P', 'I'],
+ 'I');
+
+ my $bool = $GetProcessMemoryInfo->Call($hProcess,
+ $pProcessMemoryCounters,
+ length($pProcessMemoryCounters));
+
+ # unpack ProcessMemoryCounters structure
+ my ($cb,
+ $PageFaultCount,
+ $PeakWorkingSetSize,
+ $WorkingSetSize,
+ $QuotaPeakPagedPoolUsage,
+ $QuotaPagedPoolUsage,
+ $QuotaPeakNonPagedPoolUsage,
+ $QuotaNonPagedPoolUsage,
+ $PagefileUsage,
+ $PeakPagefileUsage) = unpack($pmem_struct, $pProcessMemoryCounters);
+
+ # only care about peak working set size
+ my $size = int($PeakWorkingSetSize / 1024);
+
+ return ($size, 0);
+}
+
+
sub exit_if_too_big {
my $r = shift;
return DECLINED if ($CHECK_EVERY_N_REQUESTS &&
@@ -218,13 +276,18 @@
($MAX_UNSHARED_SIZE && ($size - $share) > $MAX_UNSHARED_SIZE)) {
# wake up! time to die.
- if (getppid > 1) { # this is a child httpd
+ if ($WIN32 || (getppid > 1)) { # this is a child httpd
my $e = time - $START_TIME;
my $msg = "httpd process too big, exiting at SIZE=$size KB ";
$msg .= " SHARE=$share KB " if ($share);
$msg .= " REQUESTS=$REQUEST_COUNT LIFETIME=$e seconds";
error_log($msg);
- $r->child_terminate;
+
+ if ($WIN32) {
+ CORE::exit(-2); # child_terminate() is disabled in win32 Apache
+ } else {
+ $r->child_terminate();
+ }
} else { # this is the main httpd, whose parent is init?
my $msg = "main process too big, SIZE=$size KB ";
@@ -254,8 +317,14 @@
sub handler {
my $r = shift || Apache->request;
- $r->post_connection(\&exit_if_too_big)
- if ($r->is_main);
+ if ($r->is_main()) {
+ # we want to operate in a cleanup handler
+ if ($r->current_callback eq 'PerlCleanupHandler') {
+ exit_if_too_big($r);
+ } else {
+ $r->post_connection(\&exit_if_too_big);
+ }
+ }
return(DECLINED);
}
@@ -274,4 +343,7 @@
Doug Steinwand and Perrin Harkins <[EMAIL PROTECTED]>: added support
for shared memory and additional diagnostic info
+Matt Phillips <[EMAIL PROTECTED]> and Mohamed Hendawi <[EMAIL PROTECTED]>:
+ Win32 support
+
=cut
--- Changes~ 2003-05-29 22:44:13.000000000 -0400
+++ Changes 2003-05-30 00:00:42.000000000 -0400
@@ -10,6 +10,14 @@
=item 1.27_01-dev
+Add Win32 support to Apache::SizeLimit [Matt Phillips
+<[EMAIL PROTECTED]> and Mohamed Hendawi <[EMAIL PROTECTED]>]
+
+Change Apache::SizeLimit to not push a cleanup handler if already in
+the cleanup handler phase, and adjust docs to show that cleanup
+handler is the preferred phase to use [Perrin Harkins
+<[EMAIL PROTECTED]>]
+
Rename Apache::test to Apache::testold because Apache::test on
case-insensitive systems will collide with Apache::Test which
supercedes Apache::test. So if you want to keep on using Apache::test,
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]