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]

Reply via email to