Make high level cache, low level cache and image cache all be initialised from passed parameters
Calculate all cache sizes from single memory cache size option and sanity check have a single global struct to hold all parameters instead of several individual variables svn path=/trunk/netsurf/; revision=12784
This commit is contained in:
parent
cbeffd4c5f
commit
2d33a8f85a
|
@ -42,7 +42,7 @@ typedef struct hlcache_retrieval_ctx hlcache_retrieval_ctx;
|
|||
struct hlcache_retrieval_ctx {
|
||||
struct hlcache_retrieval_ctx *r_prev; /**< Previous retrieval context in the ring */
|
||||
struct hlcache_retrieval_ctx *r_next; /**< Next retrieval context in the ring */
|
||||
|
||||
|
||||
llcache_handle *llcache; /**< Low-level cache handle */
|
||||
|
||||
hlcache_handle *handle; /**< High-level handle for object */
|
||||
|
@ -70,7 +70,7 @@ struct hlcache_entry {
|
|||
hlcache_entry *prev; /**< Previous sibling */
|
||||
};
|
||||
|
||||
/** Current state of the cache.
|
||||
/** Current state of the cache.
|
||||
*
|
||||
* Global state of the cache.
|
||||
*/
|
||||
|
@ -84,6 +84,8 @@ struct hlcache_s {
|
|||
hlcache_retrieval_ctx *retrieval_ctx_ring;
|
||||
|
||||
/* statsistics */
|
||||
unsigned int hit_count;
|
||||
unsigned int miss_count;
|
||||
};
|
||||
|
||||
/** high level cache state */
|
||||
|
@ -96,7 +98,7 @@ static nserror hlcache_llcache_callback(llcache_handle *handle,
|
|||
const llcache_event *event, void *pw);
|
||||
static nserror hlcache_migrate_ctx(hlcache_retrieval_ctx *ctx,
|
||||
lwc_string *effective_type);
|
||||
static bool hlcache_type_is_acceptable(lwc_string *mime_type,
|
||||
static bool hlcache_type_is_acceptable(lwc_string *mime_type,
|
||||
content_type accepted_types, content_type *computed_type);
|
||||
static nserror hlcache_find_content(hlcache_retrieval_ctx *ctx,
|
||||
lwc_string *effective_type);
|
||||
|
@ -117,8 +119,9 @@ hlcache_initialise(const struct hlcache_parameters *hlcache_parameters)
|
|||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
ret = llcache_initialise(hlcache_parameters->cb,
|
||||
hlcache_parameters->cb_ctx);
|
||||
ret = llcache_initialise(hlcache_parameters->cb,
|
||||
hlcache_parameters->cb_ctx,
|
||||
hlcache_parameters->limit);
|
||||
if (ret != NSERROR_OK) {
|
||||
free(hlcache);
|
||||
hlcache = NULL;
|
||||
|
@ -126,10 +129,10 @@ hlcache_initialise(const struct hlcache_parameters *hlcache_parameters)
|
|||
}
|
||||
|
||||
hlcache->params = *hlcache_parameters;
|
||||
|
||||
|
||||
/* Schedule the cache cleanup */
|
||||
schedule(hlcache->params.bg_clean_time / 10, hlcache_clean, NULL);
|
||||
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
|
@ -146,22 +149,22 @@ void hlcache_finalise(void)
|
|||
uint32_t num_contents, prev_contents;
|
||||
hlcache_entry *entry;
|
||||
hlcache_retrieval_ctx *ctx, *next;
|
||||
|
||||
|
||||
/* Obtain initial count of contents remaining */
|
||||
for (num_contents = 0, entry = hlcache->content_list;
|
||||
for (num_contents = 0, entry = hlcache->content_list;
|
||||
entry != NULL; entry = entry->next) {
|
||||
num_contents++;
|
||||
}
|
||||
|
||||
LOG(("%d contents remain before cache drain", num_contents));
|
||||
|
||||
|
||||
/* Drain cache */
|
||||
do {
|
||||
prev_contents = num_contents;
|
||||
|
||||
hlcache_clean(NULL);
|
||||
|
||||
for (num_contents = 0, entry = hlcache->content_list;
|
||||
for (num_contents = 0, entry = hlcache->content_list;
|
||||
entry != NULL; entry = entry->next) {
|
||||
num_contents++;
|
||||
}
|
||||
|
@ -172,7 +175,7 @@ void hlcache_finalise(void)
|
|||
hlcache_handle entry_handle = { entry, NULL, NULL };
|
||||
|
||||
if (entry->content != NULL) {
|
||||
LOG((" %p : %s (%d users)", entry,
|
||||
LOG((" %p : %s (%d users)", entry,
|
||||
content_get_url(&entry_handle), content_count_users(entry->content)));
|
||||
} else {
|
||||
LOG((" %p", entry));
|
||||
|
@ -203,9 +206,13 @@ void hlcache_finalise(void)
|
|||
hlcache->retrieval_ctx_ring = NULL;
|
||||
}
|
||||
|
||||
LOG(("hit/miss %d/%d", hlcache->hit_count, hlcache->miss_count));
|
||||
|
||||
free(hlcache);
|
||||
hlcache = NULL;
|
||||
|
||||
LOG(("Finalising low-level cache"));
|
||||
llcache_finalise();
|
||||
}
|
||||
|
||||
/* See hlcache.h for documentation */
|
||||
|
@ -221,7 +228,7 @@ nserror hlcache_poll(void)
|
|||
nserror hlcache_handle_retrieve(const char *url, uint32_t flags,
|
||||
const char *referer, llcache_post_data *post,
|
||||
hlcache_handle_callback cb, void *pw,
|
||||
hlcache_child_context *child,
|
||||
hlcache_child_context *child,
|
||||
content_type accepted_types, hlcache_handle **result)
|
||||
{
|
||||
hlcache_retrieval_ctx *ctx;
|
||||
|
@ -257,8 +264,8 @@ nserror hlcache_handle_retrieve(const char *url, uint32_t flags,
|
|||
ctx->handle->cb = cb;
|
||||
ctx->handle->pw = pw;
|
||||
|
||||
error = llcache_handle_retrieve(url, flags, referer, post,
|
||||
hlcache_llcache_callback, ctx,
|
||||
error = llcache_handle_retrieve(url, flags, referer, post,
|
||||
hlcache_llcache_callback, ctx,
|
||||
&ctx->llcache);
|
||||
if (error != NSERROR_OK) {
|
||||
free((char *) ctx->child.charset);
|
||||
|
@ -266,9 +273,9 @@ nserror hlcache_handle_retrieve(const char *url, uint32_t flags,
|
|||
free(ctx);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
RING_INSERT(hlcache->retrieval_ctx_ring, ctx);
|
||||
|
||||
|
||||
*result = ctx->handle;
|
||||
|
||||
return NSERROR_OK;
|
||||
|
@ -278,14 +285,14 @@ nserror hlcache_handle_retrieve(const char *url, uint32_t flags,
|
|||
nserror hlcache_handle_release(hlcache_handle *handle)
|
||||
{
|
||||
if (handle->entry != NULL) {
|
||||
content_remove_user(handle->entry->content,
|
||||
content_remove_user(handle->entry->content,
|
||||
hlcache_content_callback, handle);
|
||||
} else {
|
||||
RING_ITERATE_START(struct hlcache_retrieval_ctx,
|
||||
hlcache->retrieval_ctx_ring,
|
||||
ictx) {
|
||||
if (ictx->handle == handle) {
|
||||
/* This is the nascent context for us,
|
||||
/* This is the nascent context for us,
|
||||
* so abort the fetch */
|
||||
llcache_handle_abort(ictx->llcache);
|
||||
llcache_handle_release(ictx->llcache);
|
||||
|
@ -295,7 +302,7 @@ nserror hlcache_handle_release(hlcache_handle *handle)
|
|||
free((char *) ictx->child.charset);
|
||||
free(ictx);
|
||||
/* And stop */
|
||||
RING_ITERATE_STOP(hlcache->retrieval_ctx_ring,
|
||||
RING_ITERATE_STOP(hlcache->retrieval_ctx_ring,
|
||||
ictx);
|
||||
}
|
||||
} RING_ITERATE_END(hlcache->retrieval_ctx_ring, ictx);
|
||||
|
@ -325,18 +332,18 @@ nserror hlcache_handle_abort(hlcache_handle *handle)
|
|||
{
|
||||
struct hlcache_entry *entry = handle->entry;
|
||||
struct content *c;
|
||||
|
||||
|
||||
if (entry == NULL) {
|
||||
/* This handle is not yet associated with a cache entry.
|
||||
* The implication is that the fetch for the handle has
|
||||
* not progressed to the point where the entry can be
|
||||
* created. */
|
||||
|
||||
|
||||
RING_ITERATE_START(struct hlcache_retrieval_ctx,
|
||||
hlcache->retrieval_ctx_ring,
|
||||
ictx) {
|
||||
if (ictx->handle == handle) {
|
||||
/* This is the nascent context for us,
|
||||
/* This is the nascent context for us,
|
||||
* so abort the fetch */
|
||||
llcache_handle_abort(ictx->llcache);
|
||||
llcache_handle_release(ictx->llcache);
|
||||
|
@ -346,39 +353,39 @@ nserror hlcache_handle_abort(hlcache_handle *handle)
|
|||
free((char *) ictx->child.charset);
|
||||
free(ictx);
|
||||
/* And stop */
|
||||
RING_ITERATE_STOP(hlcache->retrieval_ctx_ring,
|
||||
RING_ITERATE_STOP(hlcache->retrieval_ctx_ring,
|
||||
ictx);
|
||||
}
|
||||
} RING_ITERATE_END(hlcache->retrieval_ctx_ring, ictx);
|
||||
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
c = entry->content;
|
||||
|
||||
|
||||
if (content_count_users(c) > 1) {
|
||||
/* We are not the only user of 'c' so clone it. */
|
||||
struct content *clone = content_clone(c);
|
||||
|
||||
|
||||
if (clone == NULL)
|
||||
return NSERROR_NOMEM;
|
||||
|
||||
|
||||
entry = calloc(sizeof(struct hlcache_entry), 1);
|
||||
|
||||
|
||||
if (entry == NULL) {
|
||||
content_destroy(clone);
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
if (content_add_user(clone,
|
||||
|
||||
if (content_add_user(clone,
|
||||
hlcache_content_callback, handle) == false) {
|
||||
content_destroy(clone);
|
||||
free(entry);
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
|
||||
content_remove_user(c, hlcache_content_callback, handle);
|
||||
|
||||
|
||||
entry->content = clone;
|
||||
handle->entry = entry;
|
||||
entry->prev = NULL;
|
||||
|
@ -386,10 +393,10 @@ nserror hlcache_handle_abort(hlcache_handle *handle)
|
|||
if (hlcache->content_list != NULL)
|
||||
hlcache->content_list->prev = entry;
|
||||
hlcache->content_list = entry;
|
||||
|
||||
|
||||
c = clone;
|
||||
}
|
||||
|
||||
|
||||
return content_abort(c);
|
||||
}
|
||||
|
||||
|
@ -426,17 +433,17 @@ void hlcache_clean(void *ignored)
|
|||
if (entry->content == NULL)
|
||||
continue;
|
||||
|
||||
if (content__get_status(entry->content) ==
|
||||
if (content__get_status(entry->content) ==
|
||||
CONTENT_STATUS_LOADING)
|
||||
continue;
|
||||
|
||||
if (content_count_users(entry->content) != 0)
|
||||
continue;
|
||||
|
||||
/** \todo This is over-zealous: all unused contents
|
||||
* will be immediately destroyed. Ideally, we want to
|
||||
* purge all unused contents that are using stale
|
||||
* source data, and enough fresh contents such that
|
||||
/** \todo This is over-zealous: all unused contents
|
||||
* will be immediately destroyed. Ideally, we want to
|
||||
* purge all unused contents that are using stale
|
||||
* source data, and enough fresh contents such that
|
||||
* the cache fits in the configured cache size limit.
|
||||
*/
|
||||
|
||||
|
@ -455,10 +462,10 @@ void hlcache_clean(void *ignored)
|
|||
/* Destroy entry */
|
||||
free(entry);
|
||||
}
|
||||
|
||||
|
||||
/* Attempt to clean the llcache */
|
||||
llcache_clean();
|
||||
|
||||
|
||||
/* Re-schedule ourselves */
|
||||
schedule(hlcache->params.bg_clean_time / 10, hlcache_clean, NULL);
|
||||
}
|
||||
|
@ -483,11 +490,11 @@ nserror hlcache_llcache_callback(llcache_handle *handle,
|
|||
switch (event->type) {
|
||||
case LLCACHE_EVENT_HAD_HEADERS:
|
||||
error = mimesniff_compute_effective_type(handle, NULL, 0,
|
||||
ctx->flags & HLCACHE_RETRIEVE_SNIFF_TYPE,
|
||||
ctx->flags & HLCACHE_RETRIEVE_SNIFF_TYPE,
|
||||
&effective_type);
|
||||
if (error == NSERROR_OK || error == NSERROR_NOT_FOUND) {
|
||||
/* If the sniffer was successful or failed to find
|
||||
* a Content-Type header when sniffing was
|
||||
/* If the sniffer was successful or failed to find
|
||||
* a Content-Type header when sniffing was
|
||||
* prohibited, we must migrate the retrieval context. */
|
||||
error = hlcache_migrate_ctx(ctx, effective_type);
|
||||
|
||||
|
@ -495,7 +502,7 @@ nserror hlcache_llcache_callback(llcache_handle *handle,
|
|||
lwc_string_unref(effective_type);
|
||||
}
|
||||
|
||||
/* No need to report that we need data:
|
||||
/* No need to report that we need data:
|
||||
* we'll get some anyway if there is any */
|
||||
if (error == NSERROR_NEED_DATA)
|
||||
error = NSERROR_OK;
|
||||
|
@ -504,7 +511,7 @@ nserror hlcache_llcache_callback(llcache_handle *handle,
|
|||
|
||||
break;
|
||||
case LLCACHE_EVENT_HAD_DATA:
|
||||
error = mimesniff_compute_effective_type(handle,
|
||||
error = mimesniff_compute_effective_type(handle,
|
||||
event->data.data.buf, event->data.data.len,
|
||||
ctx->flags & HLCACHE_RETRIEVE_SNIFF_TYPE,
|
||||
&effective_type);
|
||||
|
@ -549,7 +556,7 @@ nserror hlcache_llcache_callback(llcache_handle *handle,
|
|||
hlevent.data.error = event->data.msg;
|
||||
|
||||
ctx->handle->cb(ctx->handle, &hlevent, ctx->handle->pw);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LLCACHE_EVENT_PROGRESS:
|
||||
break;
|
||||
|
@ -563,11 +570,11 @@ nserror hlcache_llcache_callback(llcache_handle *handle,
|
|||
*
|
||||
* \param ctx Context to migrate
|
||||
* \param effective_type The effective MIME type of the content, or NULL
|
||||
* \return NSERROR_OK on success,
|
||||
* \return NSERROR_OK on success,
|
||||
* NSERROR_NEED_DATA on success where data is needed,
|
||||
* appropriate error otherwise
|
||||
*/
|
||||
nserror hlcache_migrate_ctx(hlcache_retrieval_ctx *ctx,
|
||||
nserror hlcache_migrate_ctx(hlcache_retrieval_ctx *ctx,
|
||||
lwc_string *effective_type)
|
||||
{
|
||||
content_type type = CONTENT_NONE;
|
||||
|
@ -575,8 +582,8 @@ nserror hlcache_migrate_ctx(hlcache_retrieval_ctx *ctx,
|
|||
|
||||
/* Unlink the context to prevent recursion */
|
||||
RING_REMOVE(hlcache->retrieval_ctx_ring, ctx);
|
||||
|
||||
if (effective_type != NULL &&
|
||||
|
||||
if (effective_type != NULL &&
|
||||
hlcache_type_is_acceptable(effective_type,
|
||||
ctx->accepted_types, &type)) {
|
||||
error = hlcache_find_content(ctx, effective_type);
|
||||
|
@ -586,13 +593,13 @@ nserror hlcache_migrate_ctx(hlcache_retrieval_ctx *ctx,
|
|||
hlevent.type = CONTENT_MSG_ERROR;
|
||||
hlevent.data.error = messages_get("MiscError");
|
||||
|
||||
ctx->handle->cb(ctx->handle, &hlevent,
|
||||
ctx->handle->cb(ctx->handle, &hlevent,
|
||||
ctx->handle->pw);
|
||||
|
||||
|
||||
llcache_handle_abort(ctx->llcache);
|
||||
llcache_handle_release(ctx->llcache);
|
||||
}
|
||||
} else if (type == CONTENT_NONE &&
|
||||
} else if (type == CONTENT_NONE &&
|
||||
(ctx->flags & HLCACHE_RETRIEVE_MAY_DOWNLOAD)) {
|
||||
/* Unknown type, and we can download, so convert */
|
||||
llcache_handle_force_stream(ctx->llcache);
|
||||
|
@ -620,7 +627,7 @@ nserror hlcache_migrate_ctx(hlcache_retrieval_ctx *ctx,
|
|||
hlevent.type = CONTENT_MSG_ERROR;
|
||||
hlevent.data.error = messages_get("BadType");
|
||||
|
||||
ctx->handle->cb(ctx->handle, &hlevent,
|
||||
ctx->handle->cb(ctx->handle, &hlevent,
|
||||
ctx->handle->pw);
|
||||
}
|
||||
}
|
||||
|
@ -657,7 +664,7 @@ bool hlcache_type_is_acceptable(lwc_string *mime_type,
|
|||
*
|
||||
* \param ctx High-level cache retrieval context
|
||||
* \param effective_type Effective MIME type of content
|
||||
* \return NSERROR_OK on success,
|
||||
* \return NSERROR_OK on success,
|
||||
* NSERROR_NEED_DATA on success where data is needed,
|
||||
* appropriate error otherwise
|
||||
*
|
||||
|
@ -694,11 +701,11 @@ nserror hlcache_find_content(hlcache_retrieval_ctx *ctx,
|
|||
ctx->child.quirks) == false)
|
||||
continue;
|
||||
|
||||
/* Ensure that content uses same low-level object as
|
||||
/* Ensure that content uses same low-level object as
|
||||
* low-level handle */
|
||||
entry_llcache = content_get_llcache_handle(entry->content);
|
||||
|
||||
if (llcache_handle_references_same_object(entry_llcache,
|
||||
if (llcache_handle_references_same_object(entry_llcache,
|
||||
ctx->llcache))
|
||||
break;
|
||||
}
|
||||
|
@ -710,7 +717,7 @@ nserror hlcache_find_content(hlcache_retrieval_ctx *ctx,
|
|||
return NSERROR_NOMEM;
|
||||
|
||||
/* Create content using llhandle */
|
||||
entry->content = content_factory_create_content(ctx->llcache,
|
||||
entry->content = content_factory_create_content(ctx->llcache,
|
||||
ctx->child.charset, ctx->child.quirks,
|
||||
effective_type);
|
||||
if (entry->content == NULL) {
|
||||
|
@ -727,13 +734,16 @@ nserror hlcache_find_content(hlcache_retrieval_ctx *ctx,
|
|||
|
||||
/* Signal to caller that we created a content */
|
||||
error = NSERROR_NEED_DATA;
|
||||
|
||||
hlcache->miss_count++;
|
||||
} else {
|
||||
/* Found a suitable content: no longer need low-level handle */
|
||||
llcache_handle_release(ctx->llcache);
|
||||
llcache_handle_release(ctx->llcache);
|
||||
hlcache->hit_count++;
|
||||
}
|
||||
|
||||
/* Associate handle with content */
|
||||
if (content_add_user(entry->content,
|
||||
if (content_add_user(entry->content,
|
||||
hlcache_content_callback, ctx->handle) == false)
|
||||
return NSERROR_NOMEM;
|
||||
|
||||
|
@ -753,7 +763,7 @@ nserror hlcache_find_content(hlcache_retrieval_ctx *ctx,
|
|||
|
||||
if (ctx->handle->cb != NULL) {
|
||||
event.type = CONTENT_MSG_READY;
|
||||
ctx->handle->cb(ctx->handle, &event,
|
||||
ctx->handle->cb(ctx->handle, &event,
|
||||
ctx->handle->pw);
|
||||
}
|
||||
} else if (status == CONTENT_STATUS_DONE) {
|
||||
|
@ -762,13 +772,13 @@ nserror hlcache_find_content(hlcache_retrieval_ctx *ctx,
|
|||
|
||||
if (ctx->handle->cb != NULL) {
|
||||
event.type = CONTENT_MSG_READY;
|
||||
ctx->handle->cb(ctx->handle, &event,
|
||||
ctx->handle->cb(ctx->handle, &event,
|
||||
ctx->handle->pw);
|
||||
}
|
||||
|
||||
if (ctx->handle->cb != NULL) {
|
||||
event.type = CONTENT_MSG_DONE;
|
||||
ctx->handle->cb(ctx->handle, &event,
|
||||
ctx->handle->cb(ctx->handle, &event,
|
||||
ctx->handle->pw);
|
||||
}
|
||||
}
|
||||
|
@ -785,7 +795,7 @@ nserror hlcache_find_content(hlcache_retrieval_ctx *ctx,
|
|||
* \param data Data for message
|
||||
* \param pw Pointer to private data (hlcache_handle)
|
||||
*/
|
||||
void hlcache_content_callback(struct content *c, content_msg msg,
|
||||
void hlcache_content_callback(struct content *c, content_msg msg,
|
||||
union content_msg_data data, void *pw)
|
||||
{
|
||||
hlcache_handle *handle = pw;
|
||||
|
@ -801,4 +811,3 @@ void hlcache_content_callback(struct content *c, content_msg msg,
|
|||
if (error != NSERROR_OK)
|
||||
LOG(("Error in callback: %d", error));
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include "content/fetch.h"
|
||||
#include "content/llcache.h"
|
||||
#include "content/urldb.h"
|
||||
#include "desktop/options.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/messages.h"
|
||||
#include "utils/url.h"
|
||||
|
@ -142,15 +141,23 @@ struct llcache_object {
|
|||
size_t num_headers; /**< Number of fetch headers */
|
||||
};
|
||||
|
||||
/** Handler for fetch-related queries */
|
||||
static llcache_query_callback query_cb;
|
||||
/** Data for fetch-related query handler */
|
||||
static void *query_cb_pw;
|
||||
struct llcache_s {
|
||||
/** Handler for fetch-related queries */
|
||||
llcache_query_callback query_cb;
|
||||
/** Data for fetch-related query handler */
|
||||
void *query_cb_pw;
|
||||
|
||||
/** Head of the low-level cached object list */
|
||||
static llcache_object *llcache_cached_objects;
|
||||
/** Head of the low-level uncached object list */
|
||||
static llcache_object *llcache_uncached_objects;
|
||||
/** Head of the low-level cached object list */
|
||||
llcache_object *cached_objects;
|
||||
|
||||
/** Head of the low-level uncached object list */
|
||||
llcache_object *uncached_objects;
|
||||
|
||||
uint32_t limit;
|
||||
};
|
||||
|
||||
/** low level cache state */
|
||||
static struct llcache_s *llcache = NULL;
|
||||
|
||||
static nserror llcache_object_user_new(llcache_handle_callback cb, void *pw,
|
||||
llcache_object_user **user);
|
||||
|
@ -246,10 +253,19 @@ static inline void llcache_invalidate_cache_control_data(llcache_object *object)
|
|||
******************************************************************************/
|
||||
|
||||
/* See llcache.h for documentation */
|
||||
nserror llcache_initialise(llcache_query_callback cb, void *pw)
|
||||
nserror
|
||||
llcache_initialise(llcache_query_callback cb, void *pw, uint32_t llcache_limit)
|
||||
{
|
||||
query_cb = cb;
|
||||
query_cb_pw = pw;
|
||||
llcache = calloc(1, sizeof(struct llcache_s));
|
||||
if (llcache == NULL) {
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
llcache->query_cb = cb;
|
||||
llcache->query_cb_pw = pw;
|
||||
llcache->limit = llcache_limit;
|
||||
|
||||
LOG(("llcache initialised with a limit of %d bytes", llcache_limit));
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
@ -260,7 +276,7 @@ void llcache_finalise(void)
|
|||
llcache_object *object, *next;
|
||||
|
||||
/* Clean uncached objects */
|
||||
for (object = llcache_uncached_objects; object != NULL; object = next) {
|
||||
for (object = llcache->uncached_objects; object != NULL; object = next) {
|
||||
llcache_object_user *user, *next_user;
|
||||
|
||||
next = object->next;
|
||||
|
@ -281,7 +297,7 @@ void llcache_finalise(void)
|
|||
}
|
||||
|
||||
/* Clean cached objects */
|
||||
for (object = llcache_cached_objects; object != NULL; object = next) {
|
||||
for (object = llcache->cached_objects; object != NULL; object = next) {
|
||||
llcache_object_user *user, *next_user;
|
||||
|
||||
next = object->next;
|
||||
|
@ -300,6 +316,9 @@ void llcache_finalise(void)
|
|||
|
||||
llcache_object_destroy(object);
|
||||
}
|
||||
|
||||
free(llcache);
|
||||
llcache = NULL;
|
||||
}
|
||||
|
||||
/* See llcache.h for documentation */
|
||||
|
@ -310,12 +329,12 @@ nserror llcache_poll(void)
|
|||
fetch_poll();
|
||||
|
||||
/* Catch new users up with state of objects */
|
||||
for (object = llcache_cached_objects; object != NULL;
|
||||
for (object = llcache->cached_objects; object != NULL;
|
||||
object = object->next) {
|
||||
llcache_object_notify_users(object);
|
||||
}
|
||||
|
||||
for (object = llcache_uncached_objects; object != NULL;
|
||||
for (object = llcache->uncached_objects; object != NULL;
|
||||
object = object->next) {
|
||||
llcache_object_notify_users(object);
|
||||
}
|
||||
|
@ -453,7 +472,7 @@ nserror llcache_handle_abort(llcache_handle *handle)
|
|||
|
||||
/* Add new object to uncached list */
|
||||
llcache_object_add_to_list(newobject,
|
||||
&llcache_uncached_objects);
|
||||
&llcache->uncached_objects);
|
||||
} else {
|
||||
/* We're the only user, so abort any fetch in progress */
|
||||
if (object->fetch.fetch != NULL) {
|
||||
|
@ -481,10 +500,10 @@ nserror llcache_handle_force_stream(llcache_handle *handle)
|
|||
return NSERROR_OK;
|
||||
|
||||
/* Forcibly uncache this object */
|
||||
if (llcache_object_in_list(object, llcache_cached_objects)) {
|
||||
if (llcache_object_in_list(object, llcache->cached_objects)) {
|
||||
llcache_object_remove_from_list(object,
|
||||
&llcache_cached_objects);
|
||||
llcache_object_add_to_list(object, &llcache_uncached_objects);
|
||||
&llcache->cached_objects);
|
||||
llcache_object_add_to_list(object, &llcache->uncached_objects);
|
||||
}
|
||||
|
||||
object->fetch.flags |= LLCACHE_RETRIEVE_STREAM_DATA;
|
||||
|
@ -717,7 +736,7 @@ nserror llcache_object_retrieve(const char *url, uint32_t flags,
|
|||
}
|
||||
|
||||
/* Add new object to uncached list */
|
||||
llcache_object_add_to_list(obj, &llcache_uncached_objects);
|
||||
llcache_object_add_to_list(obj, &llcache->uncached_objects);
|
||||
} else {
|
||||
error = llcache_object_retrieve_from_cache(defragmented_url, flags, referer,
|
||||
post, redirect_count, &obj);
|
||||
|
@ -765,7 +784,7 @@ nserror llcache_object_retrieve_from_cache(const char *url, uint32_t flags,
|
|||
#endif
|
||||
|
||||
/* Search for the most recently fetched matching object */
|
||||
for (obj = llcache_cached_objects; obj != NULL; obj = obj->next) {
|
||||
for (obj = llcache->cached_objects; obj != NULL; obj = obj->next) {
|
||||
bool match;
|
||||
|
||||
if ((newest == NULL ||
|
||||
|
@ -821,7 +840,7 @@ nserror llcache_object_retrieve_from_cache(const char *url, uint32_t flags,
|
|||
}
|
||||
|
||||
/* Add new object to cache */
|
||||
llcache_object_add_to_list(obj, &llcache_cached_objects);
|
||||
llcache_object_add_to_list(obj, &llcache->cached_objects);
|
||||
} else {
|
||||
/* No object found; create a new one */
|
||||
/* Create new object */
|
||||
|
@ -842,7 +861,7 @@ nserror llcache_object_retrieve_from_cache(const char *url, uint32_t flags,
|
|||
}
|
||||
|
||||
/* Add new object to cache */
|
||||
llcache_object_add_to_list(obj, &llcache_cached_objects);
|
||||
llcache_object_add_to_list(obj, &llcache->cached_objects);
|
||||
}
|
||||
|
||||
*result = obj;
|
||||
|
@ -1643,7 +1662,7 @@ void llcache_clean(void)
|
|||
*/
|
||||
|
||||
/* 1) Uncacheable objects with no users or fetches */
|
||||
for (object = llcache_uncached_objects; object != NULL; object = next) {
|
||||
for (object = llcache->uncached_objects; object != NULL; object = next) {
|
||||
next = object->next;
|
||||
|
||||
/* The candidate count of uncacheable objects is always 0 */
|
||||
|
@ -1654,7 +1673,7 @@ void llcache_clean(void)
|
|||
LOG(("Found victim %p", object));
|
||||
#endif
|
||||
llcache_object_remove_from_list(object,
|
||||
&llcache_uncached_objects);
|
||||
&llcache->uncached_objects);
|
||||
llcache_object_destroy(object);
|
||||
} else {
|
||||
llcache_size += object->source_len + sizeof(*object);
|
||||
|
@ -1662,7 +1681,7 @@ void llcache_clean(void)
|
|||
}
|
||||
|
||||
/* 2) Stale cacheable objects with no users or pending fetches */
|
||||
for (object = llcache_cached_objects; object != NULL; object = next) {
|
||||
for (object = llcache->cached_objects; object != NULL; object = next) {
|
||||
next = object->next;
|
||||
|
||||
if (object->users == NULL && object->candidate_count == 0 &&
|
||||
|
@ -1673,17 +1692,17 @@ void llcache_clean(void)
|
|||
LOG(("Found victim %p", object));
|
||||
#endif
|
||||
llcache_object_remove_from_list(object,
|
||||
&llcache_cached_objects);
|
||||
&llcache->cached_objects);
|
||||
llcache_object_destroy(object);
|
||||
} else {
|
||||
llcache_size += object->source_len + sizeof(*object);
|
||||
}
|
||||
}
|
||||
|
||||
if ((uint32_t) option_memory_cache_size < llcache_size) {
|
||||
if (llcache->limit < llcache_size) {
|
||||
/* 3) Fresh cacheable objects with
|
||||
* no users or pending fetches */
|
||||
for (object = llcache_cached_objects; object != NULL;
|
||||
for (object = llcache->cached_objects; object != NULL;
|
||||
object = next) {
|
||||
next = object->next;
|
||||
|
||||
|
@ -1699,7 +1718,7 @@ void llcache_clean(void)
|
|||
object->source_len + sizeof(*object);
|
||||
|
||||
llcache_object_remove_from_list(object,
|
||||
&llcache_cached_objects);
|
||||
&llcache->cached_objects);
|
||||
llcache_object_destroy(object);
|
||||
}
|
||||
}
|
||||
|
@ -2459,7 +2478,7 @@ nserror llcache_fetch_auth(llcache_object *object, const char *realm)
|
|||
/* No authentication details, or tried what we had, so ask */
|
||||
object->fetch.tried_with_auth = false;
|
||||
|
||||
if (query_cb != NULL) {
|
||||
if (llcache->query_cb != NULL) {
|
||||
llcache_query query;
|
||||
|
||||
/* Emit query for authentication details */
|
||||
|
@ -2469,7 +2488,7 @@ nserror llcache_fetch_auth(llcache_object *object, const char *realm)
|
|||
|
||||
object->fetch.outstanding_query = true;
|
||||
|
||||
error = query_cb(&query, query_cb_pw,
|
||||
error = llcache->query_cb(&query, llcache->query_cb_pw,
|
||||
llcache_query_handle_response, object);
|
||||
} else {
|
||||
llcache_event event;
|
||||
|
@ -2513,7 +2532,7 @@ nserror llcache_fetch_cert_error(llcache_object *object,
|
|||
/* Invalidate cache-control data */
|
||||
llcache_invalidate_cache_control_data(object);
|
||||
|
||||
if (query_cb != NULL) {
|
||||
if (llcache->query_cb != NULL) {
|
||||
llcache_query query;
|
||||
|
||||
/* Emit query for TLS */
|
||||
|
@ -2524,7 +2543,7 @@ nserror llcache_fetch_cert_error(llcache_object *object,
|
|||
|
||||
object->fetch.outstanding_query = true;
|
||||
|
||||
error = query_cb(&query, query_cb_pw,
|
||||
error = llcache->query_cb(&query, llcache->query_cb_pw,
|
||||
llcache_query_handle_response, object);
|
||||
} else {
|
||||
llcache_event event;
|
||||
|
|
|
@ -156,7 +156,7 @@ typedef nserror (*llcache_query_callback)(const llcache_query *query, void *pw,
|
|||
* \param pw Pointer to query handler data
|
||||
* \return NSERROR_OK on success, appropriate error otherwise.
|
||||
*/
|
||||
nserror llcache_initialise(llcache_query_callback cb, void *pw);
|
||||
nserror llcache_initialise(llcache_query_callback cb, void *pw, uint32_t llcache_limit);
|
||||
|
||||
/**
|
||||
* Finalise the low-level cache
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
/* the time between cache clean runs in ms */
|
||||
#define IMAGE_CACHE_CLEAN_TIME (10 * 1000)
|
||||
|
||||
#define HL_CACHE_CLEAN_TIME (5 * 1000)
|
||||
#define HL_CACHE_CLEAN_TIME (2 * IMAGE_CACHE_CLEAN_TIME)
|
||||
|
||||
bool netsurf_quit = false;
|
||||
bool verbose_log = false;
|
||||
|
@ -109,6 +109,8 @@ static nserror netsurf_llcache_query_handler(const llcache_query *query,
|
|||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
#define MINIMUM_MEMORY_CACHE_SIZE (2 * 1024 * 1024)
|
||||
|
||||
/**
|
||||
* Initialise components used by gui NetSurf.
|
||||
*/
|
||||
|
@ -127,11 +129,9 @@ nserror netsurf_init(int *pargc,
|
|||
};
|
||||
struct image_cache_parameters image_cache_parameters = {
|
||||
.bg_clean_time = IMAGE_CACHE_CLEAN_TIME,
|
||||
.limit = (8 * 1024 * 1024),
|
||||
.hysteresis = (2 * 1024 * 1024),
|
||||
.speculative_small = SPECULATE_SMALL
|
||||
};
|
||||
|
||||
|
||||
#ifdef HAVE_SIGPIPE
|
||||
/* Ignore SIGPIPE - this is necessary as OpenSSL can generate these
|
||||
* and the default action is to terminate the app. There's no easy
|
||||
|
@ -169,6 +169,24 @@ nserror netsurf_init(int *pargc,
|
|||
|
||||
messages_load(messages);
|
||||
|
||||
/* set up cache limits based on the memory cache size option */
|
||||
hlcache_parameters.limit = option_memory_cache_size;
|
||||
|
||||
if (hlcache_parameters.limit < MINIMUM_MEMORY_CACHE_SIZE) {
|
||||
hlcache_parameters.limit = MINIMUM_MEMORY_CACHE_SIZE;
|
||||
LOG(("Setting minimum memory cache size to %d",
|
||||
hlcache_parameters.limit));
|
||||
}
|
||||
|
||||
/* image cache is 25% of total memory cache size */
|
||||
image_cache_parameters.limit = (hlcache_parameters.limit * 25) / 100;
|
||||
|
||||
/* image cache hysteresis is 20% of teh image cache size */
|
||||
image_cache_parameters.hysteresis = (image_cache_parameters.limit * 20) / 100;
|
||||
|
||||
/* account for image cache use from total */
|
||||
hlcache_parameters.limit -= image_cache_parameters.limit;
|
||||
|
||||
/* image handler bitmap cache */
|
||||
error = image_cache_init(&image_cache_parameters);
|
||||
if (error != NSERROR_OK)
|
||||
|
@ -244,9 +262,6 @@ void netsurf_exit(void)
|
|||
LOG(("Finalising high-level cache"));
|
||||
hlcache_finalise();
|
||||
|
||||
LOG(("Finalising low-level cache"));
|
||||
llcache_finalise();
|
||||
|
||||
LOG(("Closing fetches"));
|
||||
fetch_quit();
|
||||
|
||||
|
|
|
@ -89,20 +89,20 @@ struct image_cache_s {
|
|||
|
||||
/** Maximum count of bitmaps allocated at any one time */
|
||||
int max_bitmap_count;
|
||||
/** The size of the bitmaps when teh max count occoured */
|
||||
/** The size of the bitmaps when the max count occoured */
|
||||
size_t max_bitmap_count_size;
|
||||
|
||||
/** Bitmap was not available at plot time required conversion */
|
||||
int miss_count;
|
||||
size_t miss_size;
|
||||
uint64_t miss_size;
|
||||
/** Bitmap was available at plot time required no conversion */
|
||||
int hit_count;
|
||||
size_t hit_size;
|
||||
uint64_t hit_size;
|
||||
/** Bitmap was not available at plot time and required
|
||||
* conversion which failed.
|
||||
*/
|
||||
int fail_count;
|
||||
size_t fail_size;
|
||||
uint64_t fail_size;
|
||||
|
||||
/* Cache entry freed without ever being redrawn */
|
||||
int total_unrendered;
|
||||
|
@ -120,6 +120,7 @@ struct image_cache_s {
|
|||
unsigned int peak_conversions_size;
|
||||
};
|
||||
|
||||
/** image cache state */
|
||||
static struct image_cache_s *image_cache = NULL;
|
||||
|
||||
|
||||
|
@ -357,6 +358,9 @@ image_cache_init(const struct image_cache_parameters *image_cache_parameters)
|
|||
image_cache__background_update,
|
||||
image_cache);
|
||||
|
||||
LOG(("Image cache initilised with a limit of %d hysteresis of %d",
|
||||
image_cache->params.limit, image_cache->params.hysteresis));
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue