stas 2004/08/20 17:27:23
Modified: lib/Apache compat.pm
t/conf modperl_extra.pl
t/filter/TestFilter in_bbs_body.pm in_bbs_msg.pm
out_bbs_ctx.pm out_bbs_filebucket.pm
t/protocol/TestProtocol echo_bbs.pm
t/response/TestAPI in_out_filters.pm
Log:
bb traversal fixes, deploying $b->delete so not to create temp memory
leaks
Revision Changes Path
1.116 +3 -2 modperl-2.0/lib/Apache/compat.pm
Index: compat.pm
===================================================================
RCS file: /home/cvs/modperl-2.0/lib/Apache/compat.pm,v
retrieving revision 1.115
retrieving revision 1.116
diff -u -u -r1.115 -r1.116
--- compat.pm 9 Aug 2004 21:42:35 -0000 1.115
+++ compat.pm 21 Aug 2004 00:27:21 -0000 1.116
@@ -487,8 +487,9 @@
do {
$r->input_filters->get_brigade($bb, Apache::MODE_READBYTES,
APR::BLOCK_READ, IOBUFSIZE);
+ while (!$bb->is_empty) {
+ my $b = $bb->first;
- for (my $b = $bb->first; $b; $b = $bb->next($b)) {
if ($b->is_eos) {
$seen_eos++;
last;
@@ -498,7 +499,7 @@
$data .= $buf;
}
- $b->remove; # optimization to reuse memory
+ $b->delete;
}
} while (!$seen_eos);
1.61 +4 -2 modperl-2.0/t/conf/modperl_extra.pl
Index: modperl_extra.pl
===================================================================
RCS file: /home/cvs/modperl-2.0/t/conf/modperl_extra.pl,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -u -r1.60 -r1.61
--- modperl_extra.pl 12 Aug 2004 23:38:02 -0000 1.60
+++ modperl_extra.pl 21 Aug 2004 00:27:22 -0000 1.61
@@ -174,7 +174,9 @@
warn "read_post: bb $count\n" if $debug;
- for (my $b = $bb->first; $b; $b = $bb->next($b)) {
+ while (!$bb->is_empty) {
+ my $b = $bb->first;
+
if ($b->is_eos) {
warn "read_post: EOS bucket:\n" if $debug;
$seen_eos++;
@@ -186,7 +188,7 @@
$data .= $buf;
}
- $b->remove; # optimization to reuse memory
+ $b->delete;
}
} while (!$seen_eos);
1.10 +7 -18 modperl-2.0/t/filter/TestFilter/in_bbs_body.pm
Index: in_bbs_body.pm
===================================================================
RCS file: /home/cvs/modperl-2.0/t/filter/TestFilter/in_bbs_body.pm,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -u -r1.9 -r1.10
--- in_bbs_body.pm 19 Aug 2004 04:50:18 -0000 1.9
+++ in_bbs_body.pm 21 Aug 2004 00:27:22 -0000 1.10
@@ -16,30 +16,19 @@
sub handler : FilterRequestHandler {
my($filter, $bb, $mode, $block, $readbytes) = @_;
- #warn "Called!";
- my $ba = $filter->r->connection->bucket_alloc;
+ $filter->next->get_brigade($bb, $mode, $block, $readbytes);
- my $ctx_bb = APR::Brigade->new($filter->r->pool, $ba);
+ for (my $b = $bb->first; $b; $b = $bb->next($b)) {
- $filter->next->get_brigade($ctx_bb, $mode, $block, $readbytes);
-
- while (!$ctx_bb->is_empty) {
- my $b = $ctx_bb->first;
-
- $b->remove;
-
- if ($b->is_eos) {
- #warn "EOS!!!!";
- $bb->insert_tail($b);
- last;
- }
+ last if $b->is_eos;
if ($b->read(my $data)) {
#warn"[$data]\n";
- $b = APR::Bucket->new(scalar reverse $data);
+ my $nb = APR::Bucket->new(scalar reverse $data);
+ $b->insert_before($nb);
+ $b->delete;
+ $b = $nb;
}
-
- $bb->insert_tail($b);
}
Apache::OK;
1.14 +14 -23 modperl-2.0/t/filter/TestFilter/in_bbs_msg.pm
Index: in_bbs_msg.pm
===================================================================
RCS file: /home/cvs/modperl-2.0/t/filter/TestFilter/in_bbs_msg.pm,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -u -r1.13 -r1.14
--- in_bbs_msg.pm 19 Aug 2004 04:50:18 -0000 1.13
+++ in_bbs_msg.pm 21 Aug 2004 00:27:22 -0000 1.14
@@ -22,36 +22,27 @@
my($filter, $bb, $mode, $block, $readbytes) = @_;
debug "FILTER CALLED";
- my $c = $filter->c;
- my $ctx_bb = APR::Brigade->new($c->pool, $c->bucket_alloc);
- $filter->next->get_brigade($ctx_bb, $mode, $block, $readbytes);
+ $filter->next->get_brigade($bb, $mode, $block, $readbytes);
- while (!$ctx_bb->is_empty) {
- my $b = $ctx_bb->first;
+ for (my $b = $bb->first; $b; $b = $bb->next($b)) {
- $b->remove;
+ last if $b->is_eos;
- if ($b->is_eos) {
- debug "EOS!!!";
- $bb->insert_tail($b);
- last;
- }
-
- $b->read(my $data);
- debug "FILTER READ:\n$data";
-
- if ($data and $data =~ s,GET $from_url,GET $to_url,) {
+ if ($b->read(my $data)) {
+ next unless $data =~ s|GET $from_url|GET $to_url|;
debug "GET line rewritten to be:\n$data";
- $b = APR::Bucket->new($data);
- # XXX: currently a bug in httpd doesn't allow to remove
- # the first connection filter. once it's fixed adjust the test
- # to test that it was invoked only once.
- # debug "removing the filter";
- # $filter->remove; # this filter is no longer needed
+ my $nb = APR::Bucket->new($data);
+ $b->insert_before($nb);
+ $b->delete;
+ $b = $nb;
}
- $bb->insert_tail($b);
+ # XXX: currently a bug in httpd doesn't allow to remove
+ # the first connection filter. once it's fixed adjust the test
+ # to test that it was invoked only once.
+ # debug "removing the filter";
+ # $filter->remove; # this filter is no longer needed
}
Apache::OK;
1.10 +17 -3 modperl-2.0/t/filter/TestFilter/out_bbs_ctx.pm
Index: out_bbs_ctx.pm
===================================================================
RCS file: /home/cvs/modperl-2.0/t/filter/TestFilter/out_bbs_ctx.pm,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -u -r1.9 -r1.10
--- out_bbs_ctx.pm 19 Aug 2004 04:50:18 -0000 1.9
+++ out_bbs_ctx.pm 21 Aug 2004 00:27:22 -0000 1.10
@@ -11,9 +11,12 @@
use APR::Brigade ();
use APR::Bucket ();
+use APR::BucketType ();
use base qw(Apache::Filter);
+use Apache::TestTrace;
+
use Apache::Const -compile => qw(OK M_POST);
use APR::Const -compile => ':common';
@@ -22,6 +25,8 @@
sub handler {
my($filter, $bb) = @_;
+ debug "filter got called";
+
my $c = $filter->c;
my $bb_ctx = APR::Brigade->new($c->pool, $c->bucket_alloc);
@@ -31,19 +36,22 @@
my $data = exists $ctx->{data} ? $ctx->{data} : '';
while (my $b = $bb->first) {
- $b->remove;
if ($b->is_eos) {
+ debug "got EOS";
# flush the remainings and send a stats signature
$bb_ctx->insert_tail(APR::Bucket->new("$data\n")) if $data;
my $sig = join "\n", "received $ctx->{blocks} complete blocks",
"filter invoked $ctx->{invoked} times\n";
$bb_ctx->insert_tail(APR::Bucket->new($sig));
+ $b->remove;
$bb_ctx->insert_tail($b);
last;
}
if ($b->read(my $bdata)) {
+ debug "got data";
+ $b->delete;
$data .= $bdata;
my $len = length $data;
@@ -55,10 +63,16 @@
$ctx->{blocks} += $blocks;
}
if ($blocks) {
- $b = APR::Bucket->new("#" x $blocks);
- $bb_ctx->insert_tail($b);
+ my $nb = APR::Bucket->new("#" x $blocks);
+ $bb_ctx->insert_tail($nb);
}
}
+ else {
+ debug "got bucket with no data: type: " . $b->type->name;
+ $b->remove;
+ $bb_ctx->insert_tail($b);
+ }
+
}
$ctx->{data} = $data;
1.5 +5 -13 modperl-2.0/t/filter/TestFilter/out_bbs_filebucket.pm
Index: out_bbs_filebucket.pm
===================================================================
RCS file: /home/cvs/modperl-2.0/t/filter/TestFilter/out_bbs_filebucket.pm,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -u -r1.4 -r1.5
--- out_bbs_filebucket.pm 19 Aug 2004 04:50:18 -0000 1.4
+++ out_bbs_filebucket.pm 21 Aug 2004 00:27:22 -0000 1.5
@@ -23,9 +23,6 @@
sub handler {
my($filter, $bb) = @_;
- my $c = $filter->c;
- my $bb_ctx = APR::Brigade->new($c->pool, $c->bucket_alloc);
-
debug "FILTER INVOKED";
my $cnt = 0;
@@ -34,22 +31,17 @@
$cnt++;
debug "reading bucket #$cnt";
- if ($b->is_eos) {
- $b->remove;
- $bb_ctx->insert_tail($b);
- last;
- }
+ last if $b->is_eos;
if (my $len = $b->read(my $data)) {
my $nb = APR::Bucket->new(uc $data);
- $bb_ctx->insert_tail($nb);
+ $b->insert_before($nb);
+ $b->delete;
+ $b = $nb;
}
}
- my $rv = $filter->next->pass_brigade($bb_ctx);
- return $rv unless $rv == APR::SUCCESS;
-
- return Apache::OK;
+ return $filter->next->pass_brigade($bb);
}
sub response {
1.8 +21 -18 modperl-2.0/t/protocol/TestProtocol/echo_bbs.pm
Index: echo_bbs.pm
===================================================================
RCS file: /home/cvs/modperl-2.0/t/protocol/TestProtocol/echo_bbs.pm,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -u -r1.7 -r1.8
--- echo_bbs.pm 19 Aug 2004 04:50:18 -0000 1.7
+++ echo_bbs.pm 21 Aug 2004 00:27:22 -0000 1.8
@@ -4,6 +4,9 @@
# manipulations on the buckets inside the connection handler, rather
# then using filter
+# it also demonstrates how to use a single bucket bridade to do all
+# the manipulation
+
use strict;
use warnings FATAL => 'all';
@@ -13,6 +16,8 @@
use APR::Brigade ();
use APR::Error ();
+use Apache::TestTrace;
+
use Apache::Const -compile => qw(OK MODE_GETLINE);
use APR::Const -compile => qw(SUCCESS EOF SO_NONBLOCK);
@@ -23,38 +28,36 @@
# the socket to a blocking IO mode
$c->client_socket->opt_set(APR::SO_NONBLOCK, 0);
- my $bb_in = APR::Brigade->new($c->pool, $c->bucket_alloc);
- my $bb_out = APR::Brigade->new($c->pool, $c->bucket_alloc);
+ my $bb = APR::Brigade->new($c->pool, $c->bucket_alloc);
while (1) {
- my $rc = $c->input_filters->get_brigade($bb_in,
- Apache::MODE_GETLINE);
+ debug "asking new line";
+ my $rc = $c->input_filters->get_brigade($bb, Apache::MODE_GETLINE);
last if $rc == APR::EOF;
die APR::Error::strerror($rc) unless $rc == APR::SUCCESS;
- while (!$bb_in->is_empty) {
- my $bucket = $bb_in->first;
+ for (my $b = $bb->first; $b; $b = $bb->next($b)) {
- $bucket->remove;
+ last if $b->is_eos;
- if ($bucket->is_eos) {
- $bb_out->insert_tail($bucket);
- last;
- }
+ debug "processing new line";
- if ($bucket->read(my $data)) {
+ if ($b->read(my $data)) {
last if $data =~ /^[\r\n]+$/;
- $bucket = APR::Bucket->new(uc $data);
+ my $nb = APR::Bucket->new(uc $data);
+ # head->...->$nb->$b ->...->tail
+ # XXX: the next 3 lines could be replaced with a
+ # wrapper function $b->replace($nb);
+ $b->insert_before($nb);
+ $b->delete;
+ $b = $nb;
}
-
- $bb_out->insert_tail($bucket);
}
- $c->output_filters->fflush($bb_out);
+ $c->output_filters->fflush($bb);
}
- $bb_in->destroy;
- $bb_out->destroy;
+ $bb->destroy;
Apache::OK;
}
1.3 +1 -5 modperl-2.0/t/response/TestAPI/in_out_filters.pm
Index: in_out_filters.pm
===================================================================
RCS file: /home/cvs/modperl-2.0/t/response/TestAPI/in_out_filters.pm,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -u -r1.2 -r1.3
--- in_out_filters.pm 24 Jul 2004 07:27:31 -0000 1.2
+++ in_out_filters.pm 21 Aug 2004 00:27:22 -0000 1.3
@@ -46,7 +46,6 @@
sub read_request_body {
my $r = shift;
- my $debug = shift || 0;
my $bb = APR::Brigade->new($r->pool,
$r->connection->bucket_alloc);
@@ -59,21 +58,18 @@
APR::BLOCK_READ, IOBUFSIZE);
$count++;
- warn "read_post: bb $count\n" if $debug;
for (my $b = $bb->first; $b; $b = $bb->next($b)) {
if ($b->is_eos) {
- warn "read_post: EOS bucket:\n" if $debug;
$seen_eos++;
last;
}
if ($b->read(my $buf)) {
- warn "read_post: DATA bucket: [$buf]\n" if $debug;
$data .= $buf;
}
- $b->remove; # optimization to reuse memory
+ $b->delete;
}
} while (!$seen_eos);