~ubuntu-branches/ubuntu/feisty/apache2/feisty

« back to all changes in this revision

Viewing changes to srclib/apr-util/buckets/apr_buckets_pool.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Barth
  • Date: 2006-12-09 21:05:45 UTC
  • mfrom: (0.6.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061209210545-h70s0xaqc2v8vqr2
Tags: 2.2.3-3.2
* Non-maintainer upload.
* 043_ajp_connection_reuse: Patch from upstream Bugzilla, fixing a critical
  issue with regard to connection reuse in mod_proxy_ajp.
  Closes: #396265

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
 
2
 * applicable.
 
3
 *
 
4
 * Licensed under the Apache License, Version 2.0 (the "License");
 
5
 * you may not use this file except in compliance with the License.
 
6
 * You may obtain a copy of the License at
 
7
 *
 
8
 *     http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
10
 * Unless required by applicable law or agreed to in writing, software
 
11
 * distributed under the License is distributed on an "AS IS" BASIS,
 
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
13
 * See the License for the specific language governing permissions and
 
14
 * limitations under the License.
 
15
 */
 
16
 
 
17
#include "apr_buckets.h"
 
18
#define APR_WANT_MEMFUNC
 
19
#include "apr_want.h"
 
20
 
 
21
static apr_status_t pool_bucket_cleanup(void *data)
 
22
{
 
23
    apr_bucket_pool *p = data;
 
24
 
 
25
    /*
 
26
     * If the pool gets cleaned up, we have to copy the data out
 
27
     * of the pool and onto the heap.  But the apr_buckets out there
 
28
     * that point to this pool bucket need to be notified such that
 
29
     * they can morph themselves into a regular heap bucket the next
 
30
     * time they try to read.  To avoid having to manipulate
 
31
     * reference counts and b->data pointers, the apr_bucket_pool
 
32
     * actually _contains_ an apr_bucket_heap as its first element,
 
33
     * so the two share their apr_bucket_refcount member, and you
 
34
     * can typecast a pool bucket struct to make it look like a
 
35
     * regular old heap bucket struct.
 
36
     */
 
37
    p->heap.base = apr_bucket_alloc(p->heap.alloc_len, p->list);
 
38
    memcpy(p->heap.base, p->base, p->heap.alloc_len);
 
39
    p->base = NULL;
 
40
    p->pool = NULL;
 
41
 
 
42
    return APR_SUCCESS;
 
43
}
 
44
 
 
45
static apr_status_t pool_bucket_read(apr_bucket *b, const char **str, 
 
46
                                     apr_size_t *len, apr_read_type_e block)
 
47
{
 
48
    apr_bucket_pool *p = b->data;
 
49
    const char *base = p->base;
 
50
 
 
51
    if (p->pool == NULL) {
 
52
        /*
 
53
         * pool has been cleaned up... masquerade as a heap bucket from now
 
54
         * on. subsequent bucket operations will use the heap bucket code.
 
55
         */
 
56
        b->type = &apr_bucket_type_heap;
 
57
        base = p->heap.base;
 
58
    }
 
59
    *str = base + b->start;
 
60
    *len = b->length;
 
61
    return APR_SUCCESS;
 
62
}
 
63
 
 
64
static void pool_bucket_destroy(void *data)
 
65
{
 
66
    apr_bucket_pool *p = data;
 
67
 
 
68
    /* If the pool is cleaned up before the last reference goes
 
69
     * away, the data is really now on the heap; heap_destroy() takes
 
70
     * over.  free() in heap_destroy() thinks it's freeing
 
71
     * an apr_bucket_heap, when in reality it's freeing the whole
 
72
     * apr_bucket_pool for us.
 
73
     */
 
74
    if (p->pool) {
 
75
        /* the shared resource is still in the pool
 
76
         * because the pool has not been cleaned up yet
 
77
         */
 
78
        if (apr_bucket_shared_destroy(p)) {
 
79
            apr_pool_cleanup_kill(p->pool, p, pool_bucket_cleanup);
 
80
            apr_bucket_free(p);
 
81
        }
 
82
    }
 
83
    else {
 
84
        /* the shared resource is no longer in the pool, it's
 
85
         * on the heap, but this reference still thinks it's a pool
 
86
         * bucket.  we should just go ahead and pass control to
 
87
         * heap_destroy() for it since it doesn't know any better.
 
88
         */
 
89
        apr_bucket_type_heap.destroy(p);
 
90
    }
 
91
}
 
92
 
 
93
APU_DECLARE(apr_bucket *) apr_bucket_pool_make(apr_bucket *b,
 
94
                      const char *buf, apr_size_t length, apr_pool_t *pool)
 
95
{
 
96
    apr_bucket_pool *p;
 
97
 
 
98
    p = apr_bucket_alloc(sizeof(*p), b->list);
 
99
 
 
100
    /* XXX: we lose the const qualifier here which indicates
 
101
     * there's something screwy with the API...
 
102
     */
 
103
    /* XXX: why is this?  buf is const, p->base is const... what's
 
104
     * the problem?  --jcw */
 
105
    p->base = (char *) buf;
 
106
    p->pool = pool;
 
107
    p->list = b->list;
 
108
 
 
109
    b = apr_bucket_shared_make(b, p, 0, length);
 
110
    b->type = &apr_bucket_type_pool;
 
111
 
 
112
    /* pre-initialize heap bucket member */
 
113
    p->heap.alloc_len = length;
 
114
    p->heap.base      = NULL;
 
115
    p->heap.free_func = apr_bucket_free;
 
116
 
 
117
    apr_pool_cleanup_register(p->pool, p, pool_bucket_cleanup,
 
118
                              apr_pool_cleanup_null);
 
119
    return b;
 
120
}
 
121
 
 
122
APU_DECLARE(apr_bucket *) apr_bucket_pool_create(const char *buf,
 
123
                                                 apr_size_t length,
 
124
                                                 apr_pool_t *pool,
 
125
                                                 apr_bucket_alloc_t *list)
 
126
{
 
127
    apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
 
128
 
 
129
    APR_BUCKET_INIT(b);
 
130
    b->free = apr_bucket_free;
 
131
    b->list = list;
 
132
    return apr_bucket_pool_make(b, buf, length, pool);
 
133
}
 
134
 
 
135
APU_DECLARE_DATA const apr_bucket_type_t apr_bucket_type_pool = {
 
136
    "POOL", 5, APR_BUCKET_DATA,
 
137
    pool_bucket_destroy,
 
138
    pool_bucket_read,
 
139
    apr_bucket_setaside_noop, /* don't need to setaside thanks to the cleanup*/
 
140
    apr_bucket_shared_split,
 
141
    apr_bucket_shared_copy
 
142
};