You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl-cvs@perl.apache.org by do...@locus.apache.org on 2000/08/21 05:03:52 UTC

cvs commit: modperl-2.0/src/modules/perl modperl_apache_xs.c modperl_apache_xs.h

dougm       00/08/20 20:03:52

  Added:       src/modules/perl modperl_apache_xs.c modperl_apache_xs.h
  Log:
  code for extensions, which may be called from a .xs file or elsewhere
  start playing with buckets and i/o
  
  Revision  Changes    Path
  1.1                  modperl-2.0/src/modules/perl/modperl_apache_xs.c
  
  Index: modperl_apache_xs.c
  ===================================================================
  #include "mod_perl.h"
  #include "modperl_apache_xs.h"
  
  /*
   * it is not optimal to create an ap_bucket for each element of @_
   * so we use our own mini-buffer to build up a decent size buffer
   * before creating an ap_bucket
   */
  
  /*
   * XXX: should make the modperl_wbucket_t hang off of
   * r->per_request_config to avoid "setaside" copies of small buffers
   * that may happen during ap_pass_brigade()
   */
  
  #ifndef MODPERL_WBUCKET_SIZE
  #define MODPERL_WBUCKET_SIZE IOBUFSIZE
  #endif
  
  typedef struct {
      int outcnt;
      char outbuf[MODPERL_WBUCKET_SIZE];
      request_rec *r;
  } modperl_wbucket_t;
  
  static MP_INLINE void modperl_wbucket_pass(modperl_wbucket_t *b,
                                             void *buf, int len)
  {
      ap_bucket_brigade *bb = ap_brigade_create(b->r->pool);
      ap_bucket *bucket = ap_bucket_create_transient(buf, len);
      ap_brigade_append_buckets(bb, bucket);
      ap_pass_brigade(b->r->filters, bb);
  }
  
  static MP_INLINE void modperl_wbucket_flush(modperl_wbucket_t *b)
  {
      modperl_wbucket_pass(b, b->outbuf, b->outcnt);
      b->outcnt = 0;
  }
  
  static MP_INLINE void modperl_wbucket_write(modperl_wbucket_t *b,
                                              void *buf, int len)
  {
      if ((len + b->outcnt) > MODPERL_WBUCKET_SIZE) {
          modperl_wbucket_flush(b);
      }
  
      if (len >= MODPERL_WBUCKET_SIZE) {
          modperl_wbucket_pass(b, buf, len);
      }
      else {
  	memcpy(&b->outbuf[b->outcnt], buf, len);
          b->outcnt += len;
      }
  }
  
  MP_INLINE apr_size_t modperl_apache_xs_write(pTHX_ SV **mark_ptr, SV **sp_ptr)
  {
      modperl_wbucket_t wbucket;
      apr_size_t bytes = 0;
  
      mark_ptr++;
  
      wbucket.r = modperl_sv2request_rec(aTHX_ *mark_ptr++);
      wbucket.outcnt = 0;
  
      if (wbucket.r->connection->aborted) {
          return EOF;
      }
  
      while (mark_ptr <= sp_ptr) {
          STRLEN len;
          char *buf = SvPV(*mark_ptr, len);
          modperl_wbucket_write(&wbucket, buf, len);
          bytes += len;
          mark_ptr++;
      }
  
      modperl_wbucket_flush(&wbucket);
  
      /* XXX: ap_rflush if $| */
  
      return bytes;
  }
  
  
  
  1.1                  modperl-2.0/src/modules/perl/modperl_apache_xs.h
  
  Index: modperl_apache_xs.h
  ===================================================================
  #ifndef MODPERL_APACHE_XS_H
  #define MODPERL_APACHE_XS_H
  
  apr_inline apr_size_t modperl_apache_xs_write(pTHX_ SV **mark_ptr, SV **sp_ptr);
  
  #endif /* MODPERL_APACHE_XS_H */