You are viewing a plain text version of this content. The canonical link for it is here.
Posted to docs-cvs@perl.apache.org by st...@apache.org on 2004/08/15 09:54:01 UTC

cvs commit: modperl-docs/src/docs/2.0/user/handlers filters.pod http.pod protocols.pod

stas        2004/08/15 00:54:01

  Modified:    src/docs/2.0/user/handlers filters.pod http.pod
                        protocols.pod
  Log:
  - make sure that $b->remove is not called before $r->read. since if it
  does, and there is a filebucket, it'll get split into more than bucket and
  all but the first bucket will be lost. after read() it's safe to unlink
  the old bucket
  - other improvements
  
  Revision  Changes    Path
  1.46      +27 -41    modperl-docs/src/docs/2.0/user/handlers/filters.pod
  
  Index: filters.pod
  ===================================================================
  RCS file: /home/cvs/modperl-docs/src/docs/2.0/user/handlers/filters.pod,v
  retrieving revision 1.45
  retrieving revision 1.46
  diff -u -u -r1.45 -r1.46
  --- filters.pod	10 Jun 2004 15:02:21 -0000	1.45
  +++ filters.pod	15 Aug 2004 07:54:00 -0000	1.46
  @@ -1150,22 +1150,21 @@
         my $data = '';
         my $seen_eos = 0;
         do {
  -          $r->input_filters->get_brigade($bb,
  -              Apache::MODE_READBYTES, APR::BLOCK_READ, IOBUFSIZE);
  -  
  -          while (!$bb->is_empty) {
  -              my $b = $bb->first;
  -              $b->remove;
  +          $r->input_filters->get_brigade($bb, Apache::MODE_READBYTES,
  +                                         APR::BLOCK_READ, IOBUFSIZE);
     
  +          for (my $b = $bb->first; $b; $b = $bb->next($b)) {
                 if ($b->is_eos) {
                     $seen_eos++;
                     last;
                 }
     
  -              $b->read(my $data);
  -              $data .= $buf;
  -          }
  +              if ($b->read(my $buf)) {
  +                  $data .= $buf;
  +              }
     
  +              $b->remove; # optimization to reuse memory
  +          }
         } while (!$seen_eos);
     
         $bb->destroy;
  @@ -1536,8 +1535,8 @@
             warn("data: $data\n");
     
             if ($data and $data =~ s|^GET|HEAD|) {
  -              my $bn = APR::Bucket->new($data);
  -              $b->insert_after($bn);
  +              my $nb = APR::Bucket->new($data);
  +              $b->insert_after($nb);
                 $b->remove; # no longer needed
                 $f->ctx(1); # flag that that we have done the job
                 last;
  @@ -1632,7 +1631,7 @@
   we have just modified and immediately remove that bucket that we don't
   need anymore:
   
  -            $b->insert_after($bn);
  +            $b->insert_after($nb);
               $b->remove; # no longer needed
   
   Finally we set the context to 1, so we know not to apply the
  @@ -1764,8 +1763,6 @@
         while (!$bb_ctx->is_empty) {
             my $b = $bb_ctx->first;
     
  -          $b->remove;
  -  
             if ($b->is_eos) {
                 $bb->insert_tail($b);
                 last;
  @@ -1774,6 +1771,7 @@
             my $len = $b->read(my $data);
             $b = APR::Bucket->new(lc $data) if $len;
     
  +          $b->remove;
             $bb->insert_tail($b);
         }
     
  @@ -2114,8 +2112,6 @@
         while (!$bb->is_empty) {
             my $b = $bb->first;
     
  -          $b->remove;
  -  
             if ($b->is_eos) {
                 $bb_ctx->insert_tail($b);
                 last;
  @@ -2127,6 +2123,7 @@
                 $b = APR::Bucket->new($data);
             }
     
  +          $b->remove;
             $bb_ctx->insert_tail($b);
         }
     
  @@ -2291,43 +2288,32 @@
     
     sub read_post {
         my $r = shift;
  -      my $debug = shift || 0;
     
  -      my @data = ();
  -      my $seen_eos = 0;
  -      my $filters = $r->input_filters();
  -      my $ba = $r->connection->bucket_alloc;
  -      my $bb = APR::Brigade->new($r->pool, $ba);
  +      my $bb = APR::Brigade->new($r->pool, $r->connection->bucket_alloc);
     
  +      my $data = '';
  +      my $seen_eos = 0;
         do {
  -          my $rv = $filters->get_brigade($bb,
  -              Apache::MODE_READBYTES, APR::BLOCK_READ, IOBUFSIZE);
  -          if ($rv != APR::SUCCESS) {
  -              return $rv;
  -          }
  -  
  -          while (!$bb->is_empty) {
  -              my $buf;
  -              my $b = $bb->first;
  -  
  -              $b->remove;
  +          $r->input_filters->get_brigade($bb, Apache::MODE_READBYTES,
  +                                         APR::BLOCK_READ, IOBUFSIZE);
     
  +          for (my $b = $bb->first; $b; $b = $bb->next($b)) {
                 if ($b->is_eos) {
  -                  warn "EOS bucket:\n" if $debug;
                     $seen_eos++;
                     last;
                 }
     
  -              $b->read(my $buf);
  -              warn "DATA bucket: [$buf]\n" if $debug;
  -              push @data, $buf;
  -          }
  -  
  -          $bb->destroy;
  +              if ($b->read(my $buf)) {
  +                  $data .= $buf;
  +              }
     
  +              $b->remove; # optimization to reuse memory
  +          }
         } while (!$seen_eos);
     
  -      return join '', @data;
  +      $bb->destroy;
  +  
  +      return $data;
     }
   
   The C<response()> handler is trivial -- it reads the POSTed data and
  
  
  
  1.44      +8 -9      modperl-docs/src/docs/2.0/user/handlers/http.pod
  
  Index: http.pod
  ===================================================================
  RCS file: /home/cvs/modperl-docs/src/docs/2.0/user/handlers/http.pod,v
  retrieving revision 1.43
  retrieving revision 1.44
  diff -u -u -r1.43 -r1.44
  --- http.pod	9 Aug 2004 03:04:23 -0000	1.43
  +++ http.pod	15 Aug 2004 07:54:00 -0000	1.44
  @@ -495,22 +495,21 @@
         my $data = '';
         my $seen_eos = 0;
         do {
  -          $r->input_filters->get_brigade($bb,
  -              Apache::MODE_READBYTES, APR::BLOCK_READ, IOBUFSIZE);
  -  
  -          while (!$bb->is_empty) {
  -              my $b = $bb->first;
  -              $b->remove;
  +          $r->input_filters->get_brigade($bb, Apache::MODE_READBYTES,
  +                                         APR::BLOCK_READ, IOBUFSIZE);
     
  +          for (my $b = $bb->first; $b; $b = $bb->next($b)) {
                 if ($b->is_eos) {
                     $seen_eos++;
                     last;
                 }
     
  -              $b->read(my $buf);
  -              $data .= $buf;
  -          }
  +              if ($b->read(my $buf)) {
  +                  $data .= $buf;
  +              }
     
  +              $b->remove; # optimization to reuse memory
  +          }
         } while (!$seen_eos);
     
         $bb->destroy;
  
  
  
  1.28      +51 -2     modperl-docs/src/docs/2.0/user/handlers/protocols.pod
  
  Index: protocols.pod
  ===================================================================
  RCS file: /home/cvs/modperl-docs/src/docs/2.0/user/handlers/protocols.pod,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -u -r1.27 -r1.28
  --- protocols.pod	5 Jul 2004 01:39:59 -0000	1.27
  +++ protocols.pod	15 Aug 2004 07:54:00 -0000	1.28
  @@ -358,8 +358,6 @@
             while (!$bb_in->is_empty) {
                 my $b = $bb_in->first;
     
  -              $b->remove;
  -  
                 if ($b->is_eos) {
                     $bb_out->insert_tail($b);
                     last;
  @@ -371,6 +369,7 @@
                     $b = APR::Bucket->new($data);
                 }
     
  +              $b->remove;
                 $bb_out->insert_tail($b);
             }
     
  @@ -446,6 +445,56 @@
   the connection) or when the received data contains nothing but new
   line characters which we used to to tell the server to terminate the
   connection.
  +
  +Now that you've learned how to move buckets from one brigade to
  +another, let's see how the presented handler can be reimplemented
  +using a single bucket brigade. Here is the modified code:
  +
  +  sub handler {
  +      my $c = shift;
  +  
  +      $c->client_socket->opt_set(APR::SO_NONBLOCK, 0);
  +  
  +      my $bb = APR::Brigade->new($c->pool, $c->bucket_alloc);
  +  
  +      while (1) {
  +          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;
  +  
  +          for (my $b = $bb->first; $b; $b = $bb->next($b)) {
  +  
  +              last if $b->is_eos;
  +  
  +              if ($b->read(my $data)) {
  +                  last if $data =~ /^[\r\n]+$/;
  +                  my $nb = APR::Bucket->new(uc $data);
  +                  # head->...->$nb->$b ->...->tail
  +                  $b->insert_before($nb);
  +                  $b->remove;
  +              }
  +          }
  +  
  +          $c->output_filters->fflush($bb);
  +      }
  +  
  +      $bb->destroy;
  +  
  +      Apache::OK;
  +  }
  +
  +This code is shorter and simpler. Since it sends out the same bucket
  +brigade it got from the incoming filters, it only needs to replace
  +buckets that get modified, which is probably the only tricky part
  +here. The code:
  +
  +                  # head->...->$nb->$b ->...->tail
  +                  $b->insert_before($nb);
  +                  $b->remove;
  +
  +inserts a new bucket in front of the currently processed bucket, so
  +that when the latter removed the former takes place of the latter.
   
   Notice that this handler could be much simpler, since we don't modify
   the data. We could simply pass the whole brigade unmodified without
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: docs-cvs-unsubscribe@perl.apache.org
For additional commands, e-mail: docs-cvs-help@perl.apache.org