jwoolley 02/03/29 00:12:08
Modified: . CHANGES
buckets Makefile.in apr_brigade.c apr_buckets_eos.c
apr_buckets_file.c apr_buckets_flush.c
apr_buckets_heap.c apr_buckets_mmap.c
apr_buckets_pipe.c apr_buckets_pool.c
apr_buckets_simple.c apr_buckets_socket.c
include apr_buckets.h
Added: buckets apr_buckets_alloc.c
Log:
BUCKET FREELISTS
Add an allocator-passing mechanism throughout the bucket brigades API.
This allows us to get away from malloc and free for the most part, which
will hopefully be a huge performance win.
Revision Changes Path
1.60 +5 -0 apr-util/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apr-util/CHANGES,v
retrieving revision 1.59
retrieving revision 1.60
diff -u -d -u -r1.59 -r1.60
--- CHANGES 14 Mar 2002 23:18:56 -0000 1.59
+++ CHANGES 29 Mar 2002 08:12:08 -0000 1.60
@@ -1,5 +1,10 @@
Changes with APR-util b1
+ *) Change bucket brigades API to allow a "bucket allocator" to be
+ passed in at certain points. This allows us to implement freelists
+ so that we can stop using malloc/free so frequently.
+ [Cliff Woolley, Brian Pane]
+
*) add apr_rmm_realloc() function
[Madhusudan Mathihalli <[EMAIL PROTECTED]>]
1.16 +4 -3 apr-util/buckets/Makefile.in
Index: Makefile.in
===================================================================
RCS file: /home/cvs/apr-util/buckets/Makefile.in,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -u -r1.15 -r1.16
--- Makefile.in 6 Feb 2002 12:42:50 -0000 1.15
+++ Makefile.in 29 Mar 2002 08:12:08 -0000 1.16
@@ -3,9 +3,10 @@
INCLUDES = @APR_INCLUDES@ @APRUTIL_INCLUDES@ @APRUTIL_PRIV_INCLUDES@
TARGETS = apr_buckets_file.lo apr_buckets_pool.lo apr_buckets_flush.lo \
-apr_buckets_refcount.lo apr_buckets_heap.lo apr_buckets_simple.lo
apr_buckets.lo \
-apr_buckets_mmap.lo apr_buckets_socket.lo apr_buckets_eos.lo
apr_buckets_pipe.lo \
-apr_brigade.lo
+ apr_buckets_refcount.lo apr_buckets_heap.lo apr_buckets_simple.lo \
+ apr_buckets.lo apr_buckets_mmap.lo apr_buckets_socket.lo \
+ apr_buckets_eos.lo apr_buckets_pipe.lo apr_brigade.lo \
+ apr_buckets_alloc.lo
# bring in rules.mk for standard functionality
@INCLUDE_RULES@
1.37 +9 -7 apr-util/buckets/apr_brigade.c
Index: apr_brigade.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_brigade.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -u -r1.36 -r1.37
--- apr_brigade.c 17 Mar 2002 18:40:45 -0000 1.36
+++ apr_brigade.c 29 Mar 2002 08:12:08 -0000 1.37
@@ -63,7 +63,6 @@
#define APR_WANT_STRFUNC
#include "apr_want.h"
-#include <stdlib.h>
#if APR_HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif
@@ -98,12 +97,14 @@
return apr_brigade_cleanup(b);
}
-APU_DECLARE(apr_bucket_brigade *) apr_brigade_create(apr_pool_t *p)
+APU_DECLARE(apr_bucket_brigade *) apr_brigade_create(apr_pool_t *p,
+ apr_bucket_alloc_t
*list)
{
apr_bucket_brigade *b;
b = apr_palloc(p, sizeof(*b));
b->p = p;
+ b->bucket_alloc = list;
APR_RING_INIT(&b->list, apr_bucket, link);
@@ -117,7 +118,7 @@
apr_bucket_brigade *a;
apr_bucket *f;
- a = apr_brigade_create(b->p);
+ a = apr_brigade_create(b->p, b->bucket_alloc);
/* Return an empty brigade if there is nothing left in
* the first brigade to split off
*/
@@ -415,12 +416,12 @@
if (nbyte > APR_BUCKET_BUFF_SIZE) {
/* too big to buffer */
if (flush) {
- e = apr_bucket_transient_create(str, nbyte);
+ e = apr_bucket_transient_create(str, nbyte, b->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(b, e);
return flush(b, ctx);
}
else {
- e = apr_bucket_heap_create(str, nbyte, 1);
+ e = apr_bucket_heap_create(str, nbyte, NULL,
b->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(b, e);
return APR_SUCCESS;
}
@@ -428,8 +429,9 @@
else {
/* bigger than the current buffer can handle, but we don't
* mind making a new buffer */
- buf = malloc(APR_BUCKET_BUFF_SIZE);
- e = apr_bucket_heap_create(buf, APR_BUCKET_BUFF_SIZE, 0);
+ buf = apr_bucket_alloc(APR_BUCKET_BUFF_SIZE, b->bucket_alloc);
+ e = apr_bucket_heap_create(buf, APR_BUCKET_BUFF_SIZE,
+ apr_bucket_free, b->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(b, e);
e->length = 0; /* We are writing into the brigade, and
* allocating more memory than we need. This
1.33 +4 -4 apr-util/buckets/apr_buckets_eos.c
Index: apr_buckets_eos.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_buckets_eos.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -u -r1.32 -r1.33
--- apr_buckets_eos.c 13 Mar 2002 20:40:46 -0000 1.32
+++ apr_buckets_eos.c 29 Mar 2002 08:12:08 -0000 1.33
@@ -53,7 +53,6 @@
*/
#include "apr_buckets.h"
-#include <stdlib.h>
static apr_status_t eos_read(apr_bucket *b, const char **str,
apr_size_t *len, apr_read_type_e block)
@@ -73,12 +72,13 @@
return b;
}
-APU_DECLARE(apr_bucket *) apr_bucket_eos_create(void)
+APU_DECLARE(apr_bucket *) apr_bucket_eos_create(apr_bucket_alloc_t *list)
{
- apr_bucket *b = (apr_bucket *)malloc(sizeof(*b));
+ apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
APR_BUCKET_INIT(b);
- b->free = free;
+ b->free = apr_bucket_free;
+ b->list = list;
return apr_bucket_eos_make(b);
}
1.65 +15 -15 apr-util/buckets/apr_buckets_file.c
Index: apr_buckets_file.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_buckets_file.c,v
retrieving revision 1.64
retrieving revision 1.65
diff -u -d -u -r1.64 -r1.65
--- apr_buckets_file.c 13 Mar 2002 20:40:46 -0000 1.64
+++ apr_buckets_file.c 29 Mar 2002 08:12:08 -0000 1.65
@@ -56,7 +56,6 @@
#include "apr_general.h"
#include "apr_file_io.h"
#include "apr_buckets.h"
-#include <stdlib.h>
#if APR_HAS_MMAP
#include "apr_mmap.h"
@@ -70,10 +69,12 @@
static void file_destroy(void *data)
{
- if (apr_bucket_shared_destroy(data)) {
+ apr_bucket_file *f = data;
+
+ if (apr_bucket_shared_destroy(f)) {
/* no need to close the file here; it will get
* done automatically when the pool gets cleaned up */
- free(data);
+ apr_bucket_free(f);
}
}
@@ -146,17 +147,17 @@
? APR_BUCKET_BUFF_SIZE
: filelength;
*str = NULL; /* in case we die prematurely */
- buf = malloc(*len);
+ buf = apr_bucket_alloc(*len, e->list);
/* Handle offset ... */
rv = apr_file_seek(f, APR_SET, &fileoffset);
if (rv != APR_SUCCESS) {
- free(buf);
+ apr_bucket_free(buf);
return rv;
}
rv = apr_file_read(f, buf, len);
if (rv != APR_SUCCESS && rv != APR_EOF) {
- free(buf);
+ apr_bucket_free(buf);
return rv;
}
filelength -= *len;
@@ -170,12 +171,12 @@
if (filelength > 0) {
/* for efficiency, we can just build a new apr_bucket struct
* to wrap around the existing file bucket */
- b = malloc(sizeof(*b));
+ b = apr_bucket_alloc(sizeof(*b), e->list);
b->start = fileoffset + (*len);
b->length = filelength;
b->data = a;
b->type = &apr_bucket_type_file;
- b->free = free;
+ b->free = apr_bucket_free;
APR_BUCKET_INSERT_AFTER(e, b);
}
else {
@@ -192,10 +193,7 @@
{
apr_bucket_file *f;
- f = malloc(sizeof(*f));
- if (f == NULL) {
- return NULL;
- }
+ f = apr_bucket_alloc(sizeof(*f), b->list);
f->fd = fd;
f->readpool = p;
@@ -207,12 +205,14 @@
APU_DECLARE(apr_bucket *) apr_bucket_file_create(apr_file_t *fd,
apr_off_t offset,
- apr_size_t len, apr_pool_t
*p)
+ apr_size_t len, apr_pool_t
*p,
+ apr_bucket_alloc_t *list)
{
- apr_bucket *b = (apr_bucket *)malloc(sizeof(*b));
+ apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
APR_BUCKET_INIT(b);
- b->free = free;
+ b->free = apr_bucket_free;
+ b->list = list;
return apr_bucket_file_make(b, fd, offset, len, p);
}
1.25 +4 -4 apr-util/buckets/apr_buckets_flush.c
Index: apr_buckets_flush.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_buckets_flush.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -u -r1.24 -r1.25
--- apr_buckets_flush.c 13 Mar 2002 20:40:46 -0000 1.24
+++ apr_buckets_flush.c 29 Mar 2002 08:12:08 -0000 1.25
@@ -53,7 +53,6 @@
*/
#include "apr_buckets.h"
-#include <stdlib.h>
static apr_status_t flush_read(apr_bucket *b, const char **str,
apr_size_t *len, apr_read_type_e block)
@@ -73,12 +72,13 @@
return b;
}
-APU_DECLARE(apr_bucket *) apr_bucket_flush_create(void)
+APU_DECLARE(apr_bucket *) apr_bucket_flush_create(apr_bucket_alloc_t *list)
{
- apr_bucket *b = (apr_bucket *)malloc(sizeof(*b));
+ apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
APR_BUCKET_INIT(b);
- b->free = free;
+ b->free = apr_bucket_free;
+ b->list = list;
return apr_bucket_flush_make(b);
}
1.41 +17 -16 apr-util/buckets/apr_buckets_heap.c
Index: apr_buckets_heap.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_buckets_heap.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -u -r1.40 -r1.41
--- apr_buckets_heap.c 13 Mar 2002 20:40:46 -0000 1.40
+++ apr_buckets_heap.c 29 Mar 2002 08:12:08 -0000 1.41
@@ -54,9 +54,7 @@
#include "apr_buckets.h"
#define APR_WANT_MEMFUNC
-#define APR_WANT_STRFUNC
#include "apr_want.h"
-#include <stdlib.h>
static apr_status_t heap_read(apr_bucket *b, const char **str,
apr_size_t *len, apr_read_type_e block)
@@ -73,28 +71,27 @@
apr_bucket_heap *h = data;
if (apr_bucket_shared_destroy(h)) {
- free(h->base);
- free(h);
+ (*h->free_func)(h->base);
+ apr_bucket_free(h);
}
}
APU_DECLARE(apr_bucket *) apr_bucket_heap_make(apr_bucket *b, const char
*buf,
- apr_size_t length, int copy)
+ apr_size_t length,
+ void (*free_func)(void *data))
{
apr_bucket_heap *h;
- h = malloc(sizeof(*h));
- if (h == NULL) {
- return NULL;
- }
+ h = apr_bucket_alloc(sizeof(*h), b->list);
- if (copy) {
+ if (!free_func) {
h->alloc_len = length;
- h->base = malloc(h->alloc_len);
+ h->base = apr_bucket_alloc(h->alloc_len, b->list);
if (h->base == NULL) {
- free(h);
+ apr_bucket_free(h);
return NULL;
}
+ h->free_func = apr_bucket_free;
memcpy(h->base, buf, length);
}
else {
@@ -103,6 +100,7 @@
*/
h->base = (char *) buf;
h->alloc_len = length;
+ h->free_func = free_func;
}
b = apr_bucket_shared_make(b, h, 0, length);
@@ -112,13 +110,16 @@
}
APU_DECLARE(apr_bucket *) apr_bucket_heap_create(const char *buf,
- apr_size_t length, int copy)
+ apr_size_t length,
+ void (*free_func)(void
*data),
+ apr_bucket_alloc_t *list)
{
- apr_bucket *b = (apr_bucket *)malloc(sizeof(*b));
+ apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
APR_BUCKET_INIT(b);
- b->free = free;
- return apr_bucket_heap_make(b, buf, length, copy);
+ b->free = apr_bucket_free;
+ b->list = list;
+ return apr_bucket_heap_make(b, buf, length, free_func);
}
APU_DECLARE_DATA const apr_bucket_type_t apr_bucket_type_heap = {
1.48 +7 -11 apr-util/buckets/apr_buckets_mmap.c
Index: apr_buckets_mmap.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_buckets_mmap.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -d -u -r1.47 -r1.48
--- apr_buckets_mmap.c 13 Mar 2002 20:40:46 -0000 1.47
+++ apr_buckets_mmap.c 29 Mar 2002 08:12:08 -0000 1.48
@@ -53,9 +53,6 @@
*/
#include "apr_buckets.h"
-#define APR_WANT_MEMFUNC
-#include "apr_want.h"
-#include <stdlib.h>
#if APR_HAS_MMAP
@@ -83,7 +80,7 @@
/* if we are the owner of the mmaped region, apr_mmap_delete will
* munmap it for us. if we're not, it's essentially a noop. */
apr_mmap_delete(m->mmap);
- free(m);
+ apr_bucket_free(m);
}
}
@@ -96,10 +93,7 @@
{
apr_bucket_mmap *m;
- m = malloc(sizeof(*m));
- if (m == NULL) {
- return NULL;
- }
+ m = apr_bucket_alloc(sizeof(*m), b->list);
m->mmap = mm;
b = apr_bucket_shared_make(b, m, start, length);
@@ -111,12 +105,14 @@
APU_DECLARE(apr_bucket *) apr_bucket_mmap_create(apr_mmap_t *mm,
apr_off_t start,
- apr_size_t length)
+ apr_size_t length,
+ apr_bucket_alloc_t *list)
{
- apr_bucket *b = (apr_bucket *)malloc(sizeof(*b));
+ apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
APR_BUCKET_INIT(b);
- b->free = free;
+ b->free = apr_bucket_free;
+ b->list = list;
return apr_bucket_mmap_make(b, mm, start, length);
}
1.45 +9 -8 apr-util/buckets/apr_buckets_pipe.c
Index: apr_buckets_pipe.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_buckets_pipe.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -d -u -r1.44 -r1.45
--- apr_buckets_pipe.c 13 Mar 2002 20:40:46 -0000 1.44
+++ apr_buckets_pipe.c 29 Mar 2002 08:12:08 -0000 1.45
@@ -53,7 +53,6 @@
*/
#include "apr_buckets.h"
-#include <stdlib.h>
static apr_status_t pipe_read(apr_bucket *a, const char **str,
apr_size_t *len, apr_read_type_e block)
@@ -70,7 +69,7 @@
*str = NULL;
*len = APR_BUCKET_BUFF_SIZE;
- buf = malloc(*len); /* XXX: check for failure? */
+ buf = apr_bucket_alloc(*len, a->list); /* XXX: check for failure? */
rv = apr_file_read(p, buf, len);
@@ -79,7 +78,7 @@
}
if (rv != APR_SUCCESS && rv != APR_EOF) {
- free(buf);
+ apr_bucket_free(buf);
return rv;
}
/*
@@ -101,10 +100,10 @@
h = a->data;
h->alloc_len = APR_BUCKET_BUFF_SIZE; /* note the real buffer size */
*str = buf;
- APR_BUCKET_INSERT_AFTER(a, apr_bucket_pipe_create(p));
+ APR_BUCKET_INSERT_AFTER(a, apr_bucket_pipe_create(p, a->list));
}
else {
- free(buf);
+ apr_bucket_free(buf);
a = apr_bucket_immortal_make(a, "", 0);
*str = a->data;
if (rv == APR_EOF) {
@@ -137,12 +136,14 @@
return b;
}
-APU_DECLARE(apr_bucket *) apr_bucket_pipe_create(apr_file_t *p)
+APU_DECLARE(apr_bucket *) apr_bucket_pipe_create(apr_file_t *p,
+ apr_bucket_alloc_t *list)
{
- apr_bucket *b = (apr_bucket *)malloc(sizeof(*b));
+ apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
APR_BUCKET_INIT(b);
- b->free = free;
+ b->free = apr_bucket_free;
+ b->list = list;
return apr_bucket_pipe_make(b, p);
}
1.27 +11 -11 apr-util/buckets/apr_buckets_pool.c
Index: apr_buckets_pool.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_buckets_pool.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -u -r1.26 -r1.27
--- apr_buckets_pool.c 13 Mar 2002 20:40:46 -0000 1.26
+++ apr_buckets_pool.c 29 Mar 2002 08:12:08 -0000 1.27
@@ -53,7 +53,6 @@
*/
#include "apr_buckets.h"
-#include <stdlib.h>
#define APR_WANT_MEMFUNC
#include "apr_want.h"
@@ -73,7 +72,7 @@
* can typecast a pool bucket struct to make it look like a
* regular old heap bucket struct.
*/
- p->heap.base = malloc(p->heap.alloc_len);
+ p->heap.base = apr_bucket_alloc(p->heap.alloc_len, p->list);
memcpy(p->heap.base, p->base, p->heap.alloc_len);
p->base = NULL;
p->pool = NULL;
@@ -116,7 +115,7 @@
*/
if (apr_bucket_shared_destroy(p)) {
apr_pool_cleanup_kill(p->pool, p, pool_bucket_cleanup);
- free(p);
+ apr_bucket_free(p);
}
}
else {
@@ -134,10 +133,7 @@
{
apr_bucket_pool *p;
- p = malloc(sizeof(*p));
- if (p == NULL) {
- return NULL;
- }
+ p = apr_bucket_alloc(sizeof(*p), b->list);
/* XXX: we lose the const qualifier here which indicates
* there's something screwy with the API...
@@ -146,6 +142,7 @@
* the problem? --jcw */
p->base = (char *) buf;
p->pool = pool;
+ p->list = b->list;
b = apr_bucket_shared_make(b, p, 0, length);
b->type = &apr_bucket_type_pool;
@@ -159,13 +156,16 @@
return b;
}
-APU_DECLARE(apr_bucket *) apr_bucket_pool_create(
- const char *buf, apr_size_t length, apr_pool_t *pool)
+APU_DECLARE(apr_bucket *) apr_bucket_pool_create(const char *buf,
+ apr_size_t length,
+ apr_pool_t *pool,
+ apr_bucket_alloc_t *list)
{
- apr_bucket *b = (apr_bucket *)malloc(sizeof(*b));
+ apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
APR_BUCKET_INIT(b);
- b->free = free;
+ b->free = apr_bucket_free;
+ b->list = list;
return apr_bucket_pool_make(b, buf, length, pool);
}
1.38 +14 -13 apr-util/buckets/apr_buckets_simple.c
Index: apr_buckets_simple.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_buckets_simple.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -u -r1.37 -r1.38
--- apr_buckets_simple.c 13 Mar 2002 20:40:46 -0000 1.37
+++ apr_buckets_simple.c 29 Mar 2002 08:12:08 -0000 1.38
@@ -53,14 +53,11 @@
*/
#include "apr_buckets.h"
-#include <stdlib.h>
APU_DECLARE_NONSTD(apr_status_t) apr_bucket_simple_copy(apr_bucket *a,
apr_bucket **b)
{
- if ((*b = malloc(sizeof(**b))) == NULL) {
- return APR_ENOMEM;
- }
+ *b = apr_bucket_alloc(sizeof(**b), a->list); /* XXX: check for failure?
*/
**b = *a;
return APR_SUCCESS;
@@ -105,13 +102,15 @@
return b;
}
-APU_DECLARE(apr_bucket *) apr_bucket_immortal_create(
- const char *buf, apr_size_t length)
+APU_DECLARE(apr_bucket *) apr_bucket_immortal_create(const char *buf,
+ apr_size_t length,
+ apr_bucket_alloc_t
*list)
{
- apr_bucket *b = (apr_bucket *)malloc(sizeof(*b));
+ apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
APR_BUCKET_INIT(b);
- b->free = free;
+ b->free = apr_bucket_free;
+ b->list = list;
return apr_bucket_immortal_make(b, buf, length);
}
@@ -126,7 +125,7 @@
*/
static apr_status_t transient_setaside(apr_bucket *b, apr_pool_t *pool)
{
- b = apr_bucket_heap_make(b, (char *)b->data + b->start, b->length, 1);
+ b = apr_bucket_heap_make(b, (char *)b->data + b->start, b->length, NULL);
if (b == NULL) {
return APR_ENOMEM;
}
@@ -143,13 +142,15 @@
return b;
}
-APU_DECLARE(apr_bucket *) apr_bucket_transient_create(
- const char *buf, apr_size_t length)
+APU_DECLARE(apr_bucket *) apr_bucket_transient_create(const char *buf,
+ apr_size_t length,
+ apr_bucket_alloc_t
*list)
{
- apr_bucket *b = (apr_bucket *)malloc(sizeof(*b));
+ apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
APR_BUCKET_INIT(b);
- b->free = free;
+ b->free = apr_bucket_free;
+ b->list = list;
return apr_bucket_transient_make(b, buf, length);
}
1.36 +10 -9 apr-util/buckets/apr_buckets_socket.c
Index: apr_buckets_socket.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_buckets_socket.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -u -r1.35 -r1.36
--- apr_buckets_socket.c 13 Mar 2002 20:40:46 -0000 1.35
+++ apr_buckets_socket.c 29 Mar 2002 08:12:08 -0000 1.36
@@ -53,7 +53,6 @@
*/
#include "apr_buckets.h"
-#include <stdlib.h>
static apr_status_t socket_read(apr_bucket *a, const char **str,
apr_size_t *len, apr_read_type_e block)
@@ -70,7 +69,7 @@
*str = NULL;
*len = APR_BUCKET_BUFF_SIZE;
- buf = malloc(*len); /* XXX: check for failure? */
+ buf = apr_bucket_alloc(*len, a->list); /* XXX: check for failure? */
rv = apr_recv(p, buf, len);
@@ -79,7 +78,7 @@
}
if (rv != APR_SUCCESS && rv != APR_EOF) {
- free(buf);
+ apr_bucket_free(buf);
return rv;
}
/*
@@ -100,14 +99,14 @@
if (*len > 0) {
apr_bucket_heap *h;
/* Change the current bucket to refer to what we read */
- a = apr_bucket_heap_make(a, buf, *len, 0);
+ a = apr_bucket_heap_make(a, buf, *len, apr_bucket_free);
h = a->data;
h->alloc_len = APR_BUCKET_BUFF_SIZE; /* note the real buffer size */
*str = buf;
- APR_BUCKET_INSERT_AFTER(a, apr_bucket_socket_create(p));
+ APR_BUCKET_INSERT_AFTER(a, apr_bucket_socket_create(p, a->list));
}
else {
- free(buf);
+ apr_bucket_free(buf);
a = apr_bucket_immortal_make(a, "", 0);
*str = a->data;
}
@@ -132,12 +131,14 @@
return b;
}
-APU_DECLARE(apr_bucket *) apr_bucket_socket_create(apr_socket_t *p)
+APU_DECLARE(apr_bucket *) apr_bucket_socket_create(apr_socket_t *p,
+ apr_bucket_alloc_t *list)
{
- apr_bucket *b = (apr_bucket *)malloc(sizeof(*b));
+ apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
APR_BUCKET_INIT(b);
- b->free = free;
+ b->free = apr_bucket_free;
+ b->list = list;
return apr_bucket_socket_make(b, p);
}
1.1 apr-util/buckets/apr_buckets_alloc.c
Index: apr_buckets_alloc.c
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
#include <stdlib.h>
#include "apr_buckets.h"
/*
* XXX: this file will be filled in later
*/
/** A list of free memory from which new buckets or private bucket
* structures can be allocated.
*/
struct apr_bucket_alloc_t {
};
APU_DECLARE(apr_bucket_alloc_t *) apr_bucket_alloc_create(apr_pool_t *p)
{
return (apr_bucket_alloc_t *)0xFECCFECC;
}
APU_DECLARE(void) apr_bucket_alloc_destroy(apr_bucket_alloc_t *list)
{
}
APU_DECLARE(void *) apr_bucket_alloc(apr_size_t size, apr_bucket_alloc_t
*list)
{
return malloc(size);
}
APU_DECLARE(void) apr_bucket_free(void *block)
{
free(block);
}
1.133 +78 -16 apr-util/include/apr_buckets.h
Index: apr_buckets.h
===================================================================
RCS file: /home/cvs/apr-util/include/apr_buckets.h,v
retrieving revision 1.132
retrieving revision 1.133
diff -u -d -u -r1.132 -r1.133
--- apr_buckets.h 17 Mar 2002 18:40:45 -0000 1.132
+++ apr_buckets.h 29 Mar 2002 08:12:08 -0000 1.133
@@ -148,10 +148,9 @@
* Forward declaration of the main types.
*/
-/** bucket brigade structure */
typedef struct apr_bucket_brigade apr_bucket_brigade;
-
typedef struct apr_bucket apr_bucket;
+typedef struct apr_bucket_alloc_t apr_bucket_alloc_t;
typedef struct apr_bucket_type_t apr_bucket_type_t;
struct apr_bucket_type_t {
@@ -260,6 +259,8 @@
* @param e Pointer to the bucket being freed
*/
void (*free)(void *e);
+ /** The freelist from which this bucket was allocated */
+ apr_bucket_alloc_t *list;
};
/** A list of buckets */
@@ -279,8 +280,11 @@
* doesn't like that.
*/
APR_RING_HEAD(apr_bucket_list, apr_bucket) list;
+ /** The freelist from which this bucket was allocated */
+ apr_bucket_alloc_t *bucket_alloc;
};
+
typedef apr_status_t (*apr_brigade_flush)(apr_bucket_brigade *bb, void *ctx);
/**
@@ -543,6 +547,8 @@
char *base;
/** how much memory was allocated */
apr_size_t alloc_len;
+ /** function to use to delete the data */
+ void (*free_func)(void *data);
};
typedef struct apr_bucket_pool apr_bucket_pool;
@@ -575,6 +581,10 @@
* bucket before continuing.
*/
apr_pool_t *pool;
+ /** The freelist this structure was allocated from, which is
+ * needed in the cleanup phase in order to allocate space on the heap
+ */
+ apr_bucket_alloc_t *list;
};
#if APR_HAS_MMAP
@@ -611,7 +621,8 @@
* of the pool, but a cleanup is registered.
* @return The empty bucket brigade
*/
-APU_DECLARE(apr_bucket_brigade *) apr_brigade_create(apr_pool_t *p);
+APU_DECLARE(apr_bucket_brigade *) apr_brigade_create(apr_pool_t *p,
+ apr_bucket_alloc_t
*list);
/**
* destroy an entire bucket brigade. This includes destroying all of the
@@ -805,6 +816,35 @@
void *ctx,
const char *fmt, va_list va);
+/* ***** Bucket freelist functions ***** */
+/**
+ * Create a bucket allocator.
+ * @param p Pool to allocate the allocator from [note: this is only
+ * used to allocate internal structures of the allocator, NOT
+ * to allocate the memory handed out by the allocator]
+ * @warning The allocator must never be used by more than one thread at a
time.
+ */
+APU_DECLARE(apr_bucket_alloc_t *) apr_bucket_alloc_create(apr_pool_t *p);
+
+/**
+ * Destroy a bucket allocator.
+ * @param list The allocator to be destroyed
+ */
+APU_DECLARE(void) apr_bucket_alloc_destroy(apr_bucket_alloc_t *list);
+
+/**
+ * Allocate memory for use by the buckets.
+ * @param size The amount to allocate.
+ * @param list The allocator from which to allocate the memory.
+ */
+APU_DECLARE(void *) apr_bucket_alloc(apr_size_t size, apr_bucket_alloc_t
*list);
+
+/**
+ * Free memory previously allocated with apr_bucket_alloc().
+ * @param block The block of memory to be freed.
+ */
+APU_DECLARE(void) apr_bucket_free(void *block);
+
/* ***** Bucket Functions ***** */
/**
@@ -1086,9 +1126,10 @@
/**
* Create an End of Stream bucket. This indicates that there is no more data
* coming from down the filter stack. All filters should flush at this
point.
+ * @param list The freelist from which this bucket should be allocated
* @return The new bucket, or NULL if allocation failed
*/
-APU_DECLARE(apr_bucket *) apr_bucket_eos_create(void);
+APU_DECLARE(apr_bucket *) apr_bucket_eos_create(apr_bucket_alloc_t *list);
/**
* Make the bucket passed in an EOS bucket. This indicates that there is no
@@ -1103,9 +1144,10 @@
* Create a flush bucket. This indicates that filters should flush their
* data. There is no guarantee that they will flush it, but this is the
* best we can do.
+ * @param list The freelist from which this bucket should be allocated
* @return The new bucket, or NULL if allocation failed
*/
-APU_DECLARE(apr_bucket *) apr_bucket_flush_create(void);
+APU_DECLARE(apr_bucket *) apr_bucket_flush_create(apr_bucket_alloc_t *list);
/**
* Make the bucket passed in a FLUSH bucket. This indicates that filters
@@ -1120,10 +1162,12 @@
* Create a bucket referring to long-lived data.
* @param buf The data to insert into the bucket
* @param nbyte The size of the data to insert.
+ * @param list The freelist from which this bucket should be allocated
* @return The new bucket, or NULL if allocation failed
*/
APU_DECLARE(apr_bucket *) apr_bucket_immortal_create(const char *buf,
- apr_size_t nbyte);
+ apr_size_t nbyte,
+ apr_bucket_alloc_t
*list);
/**
* Make the bucket passed in a bucket refer to long-lived data
@@ -1140,10 +1184,12 @@
* Create a bucket referring to data on the stack.
* @param buf The data to insert into the bucket
* @param nbyte The size of the data to insert.
+ * @param list The freelist from which this bucket should be allocated
* @return The new bucket, or NULL if allocation failed
*/
APU_DECLARE(apr_bucket *) apr_bucket_transient_create(const char *buf,
- apr_size_t nbyte);
+ apr_size_t nbyte,
+ apr_bucket_alloc_t
*list);
/**
* Make the bucket passed in a bucket refer to stack data
@@ -1165,21 +1211,27 @@
* over responsibility for free()ing the memory.
* @param buf The buffer to insert into the bucket
* @param nbyte The size of the buffer to insert.
- * @param copy Whether to copy the data into newly-allocated memory or not
+ * @param free_func Function to use to free the data; NULL indicates that the
+ * bucket should make a copy of the data
+ * @param list The freelist from which this bucket should be allocated
* @return The new bucket, or NULL if allocation failed
*/
APU_DECLARE(apr_bucket *) apr_bucket_heap_create(const char *buf,
- apr_size_t nbyte, int copy);
+ apr_size_t nbyte,
+ void (*free_func)(void
*data),
+ apr_bucket_alloc_t *list);
/**
* Make the bucket passed in a bucket refer to heap data
* @param b The bucket to make into a HEAP bucket
* @param buf The buffer to insert into the bucket
* @param nbyte The size of the buffer to insert.
- * @param copy Whether to copy the data into newly-allocated memory or not
+ * @param free_func Function to use to free the data; NULL indicates that the
+ * bucket should make a copy of the data
* @return The new bucket, or NULL if allocation failed
*/
APU_DECLARE(apr_bucket *) apr_bucket_heap_make(apr_bucket *b, const char
*buf,
- apr_size_t nbyte, int copy);
+ apr_size_t nbyte,
+ void (*free_func)(void
*data));
/**
* Create a bucket referring to memory allocated from a pool.
@@ -1187,11 +1239,13 @@
* @param buf The buffer to insert into the bucket
* @param length The number of bytes referred to by this bucket
* @param pool The pool the memory was allocated from
+ * @param list The freelist from which this bucket should be allocated
* @return The new bucket, or NULL if allocation failed
*/
APU_DECLARE(apr_bucket *) apr_bucket_pool_create(const char *buf,
apr_size_t length,
- apr_pool_t *pool);
+ apr_pool_t *pool,
+ apr_bucket_alloc_t *list);
/**
* Make the bucket passed in a bucket refer to pool data
@@ -1212,11 +1266,13 @@
* @param start The offset of the first byte in the mmap
* that this bucket refers to
* @param length The number of bytes referred to by this bucket
+ * @param list The freelist from which this bucket should be allocated
* @return The new bucket, or NULL if allocation failed
*/
APU_DECLARE(apr_bucket *) apr_bucket_mmap_create(apr_mmap_t *mm,
apr_off_t start,
- apr_size_t length);
+ apr_size_t length,
+ apr_bucket_alloc_t *list);
/**
* Make the bucket passed in a bucket refer to an MMAP'ed file
@@ -1235,9 +1291,11 @@
/**
* Create a bucket referring to a socket.
* @param thissocket The socket to put in the bucket
+ * @param list The freelist from which this bucket should be allocated
* @return The new bucket, or NULL if allocation failed
*/
-APU_DECLARE(apr_bucket *) apr_bucket_socket_create(apr_socket_t *thissock);
+APU_DECLARE(apr_bucket *) apr_bucket_socket_create(apr_socket_t *thissock,
+ apr_bucket_alloc_t *list);
/**
* Make the bucket passed in a bucket refer to a socket
* @param b The bucket to make into a SOCKET bucket
@@ -1250,9 +1308,11 @@
/**
* Create a bucket referring to a pipe.
* @param thispipe The pipe to put in the bucket
+ * @param list The freelist from which this bucket should be allocated
* @return The new bucket, or NULL if allocation failed
*/
-APU_DECLARE(apr_bucket *) apr_bucket_pipe_create(apr_file_t *thispipe);
+APU_DECLARE(apr_bucket *) apr_bucket_pipe_create(apr_file_t *thispipe,
+ apr_bucket_alloc_t *list);
/**
* Make the bucket passed in a bucket refer to a pipe
@@ -1270,12 +1330,14 @@
* @param len The amount of data in the file we are interested in
* @param p The pool into which any needed structures should be created
* while reading from this file bucket
+ * @param list The freelist from which this bucket should be allocated
* @return The new bucket, or NULL if allocation failed
*/
APU_DECLARE(apr_bucket *) apr_bucket_file_create(apr_file_t *fd,
apr_off_t offset,
apr_size_t len,
- apr_pool_t *p);
+ apr_pool_t *p,
+ apr_bucket_alloc_t *list);
/**
* Make the bucket passed in a bucket refer to a file