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 */