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

« back to all changes in this revision

Viewing changes to modules/cache/cache_cache.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
/* Licensed to the Apache Software Foundation (ASF) under one or more
 
2
 * contributor license agreements.  See the NOTICE file distributed with
 
3
 * this work for additional information regarding copyright ownership.
 
4
 * The ASF licenses this file to You under the Apache License, Version 2.0
 
5
 * (the "License"); you may not use this file except in compliance with
 
6
 * the License.  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_general.h"
 
18
 
 
19
#include "mod_cache.h"
 
20
#include "cache_hash.h"
 
21
#include "cache_pqueue.h"
 
22
#include "cache_cache.h"
 
23
 
 
24
#if APR_HAVE_STDLIB_H
 
25
#include <stdlib.h>
 
26
#endif
 
27
#if APR_HAVE_STRING_H
 
28
#include <string.h>
 
29
#endif
 
30
 
 
31
struct cache_cache_t  {
 
32
    int             max_entries;
 
33
    apr_size_t      max_size;
 
34
    apr_size_t      current_size;
 
35
    int             total_purges;
 
36
    long            queue_clock;
 
37
    cache_hash_t   *ht;
 
38
    cache_pqueue_t *pq;
 
39
    cache_pqueue_set_priority set_pri;
 
40
    cache_pqueue_get_priority get_pri;
 
41
    cache_cache_inc_frequency *inc_entry;
 
42
    cache_cache_get_size *size_entry;
 
43
    cache_cache_get_key *key_entry;
 
44
    cache_cache_free *free_entry;
 
45
};
 
46
 
 
47
CACHE_DECLARE(cache_cache_t *)cache_init(int max_entries,
 
48
                                         apr_size_t max_size,
 
49
                                         cache_pqueue_get_priority get_pri,
 
50
                                         cache_pqueue_set_priority set_pri,
 
51
                                         cache_pqueue_getpos get_pos,
 
52
                                         cache_pqueue_setpos set_pos,
 
53
                                         cache_cache_inc_frequency *inc_entry,
 
54
                                         cache_cache_get_size *size_entry,
 
55
                                         cache_cache_get_key* key_entry,
 
56
                                         cache_cache_free *free_entry)
 
57
{
 
58
    cache_cache_t *tmp;
 
59
    tmp = malloc(sizeof(cache_cache_t));
 
60
    tmp->max_entries = max_entries;
 
61
    tmp->max_size = max_size;
 
62
    tmp->current_size = 0;
 
63
    tmp->total_purges = 0;
 
64
    tmp->queue_clock = 0;
 
65
    tmp->get_pri = get_pri;
 
66
    tmp->set_pri = set_pri;
 
67
    tmp->inc_entry = inc_entry;
 
68
    tmp->size_entry = size_entry;
 
69
    tmp->key_entry = key_entry;
 
70
    tmp->free_entry = free_entry;
 
71
 
 
72
    tmp->ht = cache_hash_make(max_entries);
 
73
    tmp->pq = cache_pq_init(max_entries, get_pri, get_pos, set_pos);
 
74
 
 
75
    return tmp;
 
76
}
 
77
 
 
78
CACHE_DECLARE(void) cache_free(cache_cache_t *c)
 
79
{
 
80
    cache_pq_free(c->pq);
 
81
    cache_hash_free(c->ht);
 
82
    free(c);
 
83
}
 
84
 
 
85
 
 
86
CACHE_DECLARE(void*) cache_find(cache_cache_t* c, const char *key)
 
87
{
 
88
    void *e;
 
89
 
 
90
    e = cache_hash_get(c->ht, key, CACHE_HASH_KEY_STRING);
 
91
    if (!e)
 
92
        return NULL;
 
93
 
 
94
    return e;
 
95
}
 
96
 
 
97
CACHE_DECLARE(void) cache_update(cache_cache_t* c, void *entry)
 
98
{
 
99
    long old_priority;
 
100
    long new_priority;
 
101
 
 
102
    old_priority = c->set_pri(c->queue_clock, entry);
 
103
    c->inc_entry(entry);
 
104
    new_priority = c->set_pri(c->queue_clock, entry);
 
105
    cache_pq_change_priority(c->pq, old_priority, new_priority, entry);
 
106
}
 
107
 
 
108
CACHE_DECLARE(void) cache_insert(cache_cache_t* c, void *entry)
 
109
{
 
110
    void *ejected = NULL;
 
111
    long priority;
 
112
 
 
113
    c->set_pri(c->queue_clock, entry);
 
114
    /* FIX: check if priority of bottom item is greater than inserted one */
 
115
    while ((cache_pq_size(c->pq) >= c->max_entries) ||
 
116
            ((c->current_size + c->size_entry(entry)) > c->max_size)) {
 
117
 
 
118
        ejected = cache_pq_pop(c->pq);
 
119
        /* FIX: If ejected is NULL, we'll segfault here */
 
120
        priority = c->get_pri(ejected);
 
121
 
 
122
        if (c->queue_clock > priority)
 
123
            c->queue_clock = priority;
 
124
 
 
125
        cache_hash_set(c->ht,
 
126
                       c->key_entry(ejected),
 
127
                       CACHE_HASH_KEY_STRING,
 
128
                       NULL);
 
129
 
 
130
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, "Cache Purge of %s",c->key_entry(ejected));
 
131
        c->current_size -= c->size_entry(ejected);
 
132
        c->free_entry(ejected);
 
133
        c->total_purges++;
 
134
    }
 
135
    c->current_size += c->size_entry(entry);
 
136
 
 
137
    cache_pq_insert(c->pq, entry);
 
138
    cache_hash_set(c->ht, c->key_entry(entry), CACHE_HASH_KEY_STRING, entry);
 
139
}
 
140
 
 
141
CACHE_DECLARE(void *) cache_pop(cache_cache_t *c)
 
142
{
 
143
    void *entry;
 
144
 
 
145
    if (!c)
 
146
        return NULL;
 
147
 
 
148
    entry = cache_pq_pop(c->pq);
 
149
 
 
150
    if (!entry)
 
151
        return NULL;
 
152
 
 
153
    c->current_size -= c->size_entry(entry);
 
154
    cache_hash_set(c->ht, c->key_entry(entry), CACHE_HASH_KEY_STRING, NULL);
 
155
 
 
156
    return entry;
 
157
}
 
158
 
 
159
CACHE_DECLARE(apr_status_t) cache_remove(cache_cache_t *c, void *entry)
 
160
{
 
161
    apr_size_t entry_size = c->size_entry(entry);
 
162
    apr_status_t rc;
 
163
    rc = cache_pq_remove(c->pq, entry);
 
164
    if (rc != APR_SUCCESS)
 
165
        return rc;
 
166
 
 
167
    cache_hash_set(c->ht, c->key_entry(entry), CACHE_HASH_KEY_STRING, NULL);
 
168
    c->current_size -= entry_size;
 
169
 
 
170
    return APR_SUCCESS;
 
171
}