I have an application that runs as a stand-alone daemon returning SOAP results. It's been running fine for a long time, but I recently noticed the memory growing and not being released after every connection.
I've created a custom module based on the code of SOAP::Transport::HTTP::Daemon, but supporting spawning threads when a connection is accepted. Running ActivePerl 5.8.8.822 with threads 1.6.3 and threads::shared 1.12 under CentOS Linux. Here's a sample application that can be used to reproduce the problem. SOAPServer.pl: -------------- #!perl use strict; use threads ('stack_size' => 32*4096, 'exit' => 'threads_only'); use SOAPDaemon; sub Start { my $SOAPServerThread = threads->new(sub { my $SOAPServer = SOAPDaemon->new( LocalPort => 10000, ReuseAddr => 1 )->dispatch_to('main'); $SOAPServer->Handle; }); } sub Ping { my $Self = shift; return {Valid => 1, Output => 'Pong'}; } Start(); while(1) { sleep(1); } SOAPDaemon.pm: -------------- #!perl package SOAPDaemon; # Custom package derived from SOAP::Transport::HTTP::Daemon use Data::Dumper; use Carp (); use HTTP::Daemon; use SOAP::Transport::HTTP; use vars qw($AUTOLOAD @ISA); @ISA = qw(SOAP::Transport::HTTP::Server); sub DESTROY { SOAP::Trace::objects('()') } sub new { my $self = shift; unless (ref $self) { my $class = ref($self) || $self; my(@params, @methods); while (@_) { $class->can($_[0]) ? push(@methods, shift() => shift) : push(@params, shift) } $self = $class->SUPER::new; $self->{_daemon} = HTTP::Daemon->new(@params) or Carp::croak "Can't create daemon: $!"; $self->myuri(URI->new($self->url)->canonical->as_string); while (@methods) { my($method, $params) = splice(@methods,0,2); $self->$method(ref $params eq 'ARRAY' ? @$params : $params) } SOAP::Trace::objects('()'); } return $self; } sub AUTOLOAD { my $method = substr($AUTOLOAD, rindex($AUTOLOAD, '::') + 2); return if $method eq 'DESTROY'; no strict 'refs'; *$AUTOLOAD = sub { shift->{_daemon}->$method(@_) }; goto &$AUTOLOAD; } sub Handle { my $self = shift->new; while (my $c = $self->accept) { threads->new(\&SOAPWorker, $self, $c); } } sub SOAPWorker { my $Obj = shift; my $c = shift; while (my $r = $c->get_request(0)) { $Obj->request($r); $Obj->SUPER::handle; $c->send_response($Obj->response); } # replaced ->close, thanks to Sean Meisner <[EMAIL PROTECTED]> # shutdown() doesn't work on AIX. close() is used in this case. Thanks to Jos Clijmans <[EMAIL PROTECTED]> UNIVERSAL::isa($c, 'shutdown') ? $c->shutdown(2) : $c->close(); $c->close; threads->self()->detach(); } # Always end package with true 1; __END__