httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Joe Orton <jor...@redhat.com>
Subject [PATCH] add ap_brigade_insert_file()
Date Thu, 04 Nov 2004 22:07:58 GMT
This factors out the logic for correctly inserting a file into a
brigade, doing the special little dance for large files if necessary;
the code was already duplicated twice and it's needed in other places
too.  (pervasive largefile support being my top 2.1 goal :)

Any comments, naming preferences, "put it in apr-util you twit" flames?

Index: include/util_filter.h
===================================================================
RCS file: /home/cvs/httpd-2.0/include/util_filter.h,v
retrieving revision 1.92
diff -u -r1.92 util_filter.h
--- include/util_filter.h	31 Oct 2004 18:00:43 -0000	1.92
+++ include/util_filter.h	4 Nov 2004 21:53:57 -0000
@@ -489,6 +489,22 @@
                                          apr_bucket_brigade **b, apr_pool_t *p);    
 
 /**
+ * Utility function to insert a file of given length onto the end of
+ * the brigade.  The file is split into multiple buckets if it is
+ * larger than the maximum size which can be represented by a single bucket.
+ * @param bb the brigade to insert into
+ * @param f the file to insert
+ * @param start the offset into the file
+ * @param len the length of the file to insert
+ * @param p pool from which file buckets are allocated
+ * @return the last bucket inserted
+ */
+AP_DECLARE(apr_bucket *) ap_brigade_insert_file(apr_bucket_brigade *bb,
+                                                apr_file_t *f, apr_off_t start,
+                                                apr_off_t len, apr_pool_t *p);
+
+
+/**
  * Flush function for apr_brigade_* calls.  This calls ap_pass_brigade
  * to flush the brigade if the brigade buffer overflows.
  * @param bb The brigade to flush
Index: modules/experimental/mod_disk_cache.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/experimental/mod_disk_cache.c,v
retrieving revision 1.68
diff -u -r1.68 mod_disk_cache.c
--- modules/experimental/mod_disk_cache.c	4 Nov 2004 21:51:12 -0000	1.68
+++ modules/experimental/mod_disk_cache.c	4 Nov 2004 21:53:59 -0000
@@ -502,14 +502,10 @@
 
 static apr_status_t recall_body(cache_handle_t *h, apr_pool_t *p, apr_bucket_brigade *bb)
 {
-    apr_bucket *e;
     disk_cache_object_t *dobj = (disk_cache_object_t*) h->cache_obj->vobj;
 
-    e = apr_bucket_file_create(dobj->fd, 0, (apr_size_t) dobj->file_size, p,
-                               bb->bucket_alloc);
-    APR_BRIGADE_INSERT_HEAD(bb, e);
-    e = apr_bucket_eos_create(bb->bucket_alloc);
-    APR_BRIGADE_INSERT_TAIL(bb, e);
+    ap_brigade_insert_file(bb, dobj->fd, 0, dobj->file_size, p);
+    APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_eos_create(bb->bucket_alloc));
 
     return APR_SUCCESS;
 }
Index: modules/generators/mod_asis.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/generators/mod_asis.c,v
retrieving revision 1.51
diff -u -r1.51 mod_asis.c
--- modules/generators/mod_asis.c	9 Feb 2004 20:29:19 -0000	1.51
+++ modules/generators/mod_asis.c	4 Nov 2004 21:53:59 -0000
@@ -76,7 +76,6 @@
 
     if (!r->header_only) {
         apr_bucket_brigade *bb;
-        apr_bucket *b;
         apr_off_t pos = 0;
 
         rv = apr_file_seek(f, APR_CUR, &pos);
@@ -89,30 +88,8 @@
         }
 
         bb = apr_brigade_create(r->pool, c->bucket_alloc);
-#if APR_HAS_LARGE_FILES
-        if (r->finfo.size - pos > AP_MAX_SENDFILE) {
-            /* APR_HAS_LARGE_FILES issue; must split into mutiple buckets, 
-             * no greater than MAX(apr_size_t), and more granular than that
-             * in case the brigade code/filters attempt to read it directly.
-             */
-            apr_off_t fsize = r->finfo.size - pos;
-            b = apr_bucket_file_create(f, pos, AP_MAX_SENDFILE,
-                                       r->pool, c->bucket_alloc);
-            while (fsize > AP_MAX_SENDFILE) {
-                APR_BRIGADE_INSERT_TAIL(bb, b);
-                apr_bucket_copy(b, &b);
-                b->start += AP_MAX_SENDFILE;
-                fsize -= AP_MAX_SENDFILE;
-            }
-            b->length = (apr_size_t)fsize; /* Resize just the last bucket */
-        }
-        else
-#endif
-        b = apr_bucket_file_create(f, pos, (apr_size_t) (r->finfo.size - pos),
-                                   r->pool, c->bucket_alloc);
-        APR_BRIGADE_INSERT_TAIL(bb, b);
-        b = apr_bucket_eos_create(c->bucket_alloc);
-        APR_BRIGADE_INSERT_TAIL(bb, b);
+        ap_brigade_insert_file(bb, f, pos, (apr_size_t) (r->finfo.size - pos), 
+                               r->pool);
         rv = ap_pass_brigade(r->output_filters, bb);
         if (rv != APR_SUCCESS) {
             ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
Index: server/core.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/core.c,v
retrieving revision 1.292
diff -u -r1.292 core.c
--- server/core.c	4 Nov 2004 16:04:55 -0000	1.292
+++ server/core.c	4 Nov 2004 21:54:00 -0000
@@ -3686,34 +3686,14 @@
 
         bb = apr_brigade_create(r->pool, c->bucket_alloc);
 
-        /* For platforms where the size of the file may be larger than
-         * that which can be stored in a single bucket (where the
-         * length field is an apr_size_t), split it into several
-         * buckets: */
-        if (sizeof(apr_off_t) > sizeof(apr_size_t) 
-            && r->finfo.size > AP_MAX_SENDFILE) {
-            apr_off_t fsize = r->finfo.size;
-            e = apr_bucket_file_create(fd, 0, AP_MAX_SENDFILE, r->pool,
-                                       c->bucket_alloc);
-            while (fsize > AP_MAX_SENDFILE) {
-                apr_bucket *ce;
-                apr_bucket_copy(e, &ce);
-                APR_BRIGADE_INSERT_TAIL(bb, ce);
-                e->start += AP_MAX_SENDFILE;
-                fsize -= AP_MAX_SENDFILE;
-            }
-            e->length = (apr_size_t)fsize; /* Resize just the last bucket */
-        }
-        else
-            e = apr_bucket_file_create(fd, 0, (apr_size_t)r->finfo.size,
-                                       r->pool, c->bucket_alloc);
+        /* insert the file as one or more buckets: */
+        e = ap_brigade_insert_file(bb, fd, 0, r->finfo.size, r->pool);
 
 #if APR_HAS_MMAP
         if (d->enable_mmap == ENABLE_MMAP_OFF) {
             (void)apr_bucket_file_enable_mmap(e, 0);
         }
 #endif
-        APR_BRIGADE_INSERT_TAIL(bb, e);
         e = apr_bucket_eos_create(c->bucket_alloc);
         APR_BRIGADE_INSERT_TAIL(bb, e);
 
Index: server/util_filter.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/util_filter.c,v
retrieving revision 1.102
diff -u -r1.102 util_filter.c
--- server/util_filter.c	1 Nov 2004 23:04:05 -0000	1.102
+++ server/util_filter.c	4 Nov 2004 21:54:00 -0000
@@ -619,3 +619,32 @@
 {
     f->frec->proto_flags = flags ;
 }
+
+AP_DECLARE(apr_bucket *) ap_brigade_insert_file(apr_bucket_brigade *bb,
+                                                apr_file_t *f, apr_off_t start,
+                                                apr_off_t length, apr_pool_t *p)
+{
+    apr_bucket *e;
+
+    if (sizeof(apr_off_t) == sizeof(apr_size_t) || length < AP_MAX_SENDFILE) {
+        e = apr_bucket_file_create(f, start, (apr_size_t)length, p, 
+                                   bb->bucket_alloc);
+    }
+    else {
+        /* Several buckets are needed. */        
+        e = apr_bucket_file_create(f, start, AP_MAX_SENDFILE, p, 
+                                   bb->bucket_alloc);
+
+        while (length > AP_MAX_SENDFILE) {
+            apr_bucket *ce;
+            apr_bucket_copy(e, &ce);
+            APR_BRIGADE_INSERT_TAIL(bb, ce);
+            e->start += AP_MAX_SENDFILE;
+            length -= AP_MAX_SENDFILE;
+        }
+        e->length = (apr_size_t)length; /* Resize just the last bucket */
+    }
+    
+    APR_BRIGADE_INSERT_TAIL(bb, e);
+    return e;
+}


Mime
View raw message