From b4723c1d05819d4e47fc59254f5ad8c9d6d62db3 Mon Sep 17 00:00:00 2001 From: James Bursa Date: Mon, 21 Jun 2004 15:09:59 +0000 Subject: [project @ 2004-06-21 15:09:58 by bursa] Merge memory cache into content module. svn path=/import/netsurf/; revision=986 --- content/content.c | 121 +++++++++++++++++++++++++++++++-------------------- content/content.h | 18 ++++---- content/fetchcache.c | 28 ++++-------- 3 files changed, 94 insertions(+), 73 deletions(-) (limited to 'content') diff --git a/content/content.c b/content/content.c index f8cbfbe82..8d92f187b 100644 --- a/content/content.c +++ b/content/content.c @@ -19,7 +19,9 @@ #include #include "netsurf/utils/config.h" #include "netsurf/content/content.h" +#include "netsurf/content/fetch.h" #include "netsurf/css/css.h" +#include "netsurf/desktop/options.h" #include "netsurf/render/html.h" #include "netsurf/render/textplain.h" #ifdef WITH_JPEG @@ -179,6 +181,7 @@ static const struct handler_entry handler_map[] = { #define HANDLER_MAP_COUNT (sizeof(handler_map) / sizeof(handler_map[0])) +static void content_destroy(struct content *c); static void content_stop_check(struct content *c); @@ -239,7 +242,7 @@ struct content * content_create(const char *url) c->width = 0; c->height = 0; c->available_width = 0; - c->cache = 0; + c->fresh = false; c->size = sizeof(struct content); c->title = 0; c->active = 0; @@ -252,8 +255,6 @@ struct content * content_create(const char *url) c->source_data = 0; c->source_size = 0; c->total_size = 0; - c->lock = 0; - c->destroy_pending = false; c->no_error_pages = false; c->error_count = 0; @@ -267,6 +268,29 @@ struct content * content_create(const char *url) } +/** + * Get a content from the memory cache. + * + * \param url URL of content + * \return content if found, or 0 + * + * Searches the list of contents for one corresponding to the given url, and + * which is fresh. + */ + +struct content * content_get(const char *url) +{ + struct content *c; + + for (c = content_list; c; c = c->next) { + if (c->fresh && strcmp(c->url, url) == 0) + return c; + } + + return 0; +} + + /** * Initialise the content for the specified type. * @@ -326,6 +350,7 @@ bool content_set_type(struct content *c, content_type type, * * \param status_message new textual status */ + void content_set_status(struct content *c, const char *status_message, ...) { va_list ap; @@ -446,24 +471,56 @@ void content_reformat(struct content *c, int width, int height) /** + * Clean unused contents from the content_list. + * * Destroys any contents in the content_list with no users or in - * CONTENT_STATUS_ERROR, and not with an active fetch or cached. + * CONTENT_STATUS_ERROR. Fresh contents in CONTENT_STATUS_DONE may be kept even + * with no users. + * + * Each content is also checked for stop requests. */ void content_clean(void) { - struct content *c, *next; + unsigned int size; + struct content *c, *next, *prev; + /* destroy unused stale contents and contents with errors */ for (c = content_list; c; c = next) { next = c->next; - if (((!c->user_list->next && !c->cache) || - c->status == CONTENT_STATUS_ERROR) && - !c->fetch) { - LOG(("%p %s", c, c->url)); - if (c->cache) - cache_destroy(c); - content_destroy(c); - } + + if (c->user_list->next && c->status != CONTENT_STATUS_ERROR) + /* content has users */ + continue; + + if (c->fresh && c->status == CONTENT_STATUS_DONE) + /* content is fresh */ + continue; + + /* content can be destroyed */ + content_destroy(c); + } + + /* check for pending stops */ + for (c = content_list; c; c = c->next) { + if (c->status == CONTENT_STATUS_READY) + content_stop_check(c); + } + + /* attempt to shrike the memory cache (unused fresh contents) */ + size = 0; + next = 0; + for (c = content_list; c; c = c->next) { + next = c; + size += c->size; + } + for (c = next; c && (unsigned int) option_memory_cache_size < size; + c = prev) { + prev = c->prev; + if (c->user_list->next) + continue; + size -= c->size; + content_destroy(c); } } @@ -479,13 +536,9 @@ void content_destroy(struct content *c) struct content_user *user, *next; assert(c); LOG(("content %p %s", c, c->url)); - assert(!c->fetch); - assert(!c->cache); - if (c->lock) { - c->destroy_pending = true; - return; - } + if (c->fetch) + fetch_abort(c->fetch); if (c->next) c->next->prev = c->prev; @@ -599,28 +652,6 @@ void content_remove_user(struct content *c, next = user->next; user->next = next->next; free(next); - - /* if there are now no users, stop any loading in progress - * and destroy content structure if not in state READY or DONE */ - if (c->user_list->next == 0) { - LOG(("no users for %p %s", c, c->url)); - if (c->fetch != 0) { - fetch_abort(c->fetch); - c->fetch = 0; - } - if (c->status < CONTENT_STATUS_READY) { - if (c->cache) - cache_destroy(c); - content_destroy(c); - } else { - if (c->cache) - cache_freeable(c); - else - content_destroy(c); - } - } else if (c->status == CONTENT_STATUS_READY) { - content_stop_check(c); - } } @@ -632,14 +663,11 @@ void content_broadcast(struct content *c, content_msg msg, union content_msg_data data) { struct content_user *user, *next; - c->lock++; for (user = c->user_list->next; user != 0; user = next) { next = user->next; /* user may be destroyed during callback */ if (user->callback != 0) user->callback(msg, c, user->p1, user->p2, data); } - if (--(c->lock) == 0 && c->destroy_pending) - content_destroy(c); } @@ -672,9 +700,8 @@ void content_stop(struct content *c, } user = user->next; + LOG(("%p %s: stop user %p %p %p", c, c->url, callback, p1, p2)); user->stop = true; - - content_stop_check(c); } @@ -694,6 +721,8 @@ void content_stop_check(struct content *c) if (!user->stop) return; + LOG(("%p %s", c, c->url)); + /* all users have requested stop */ assert(handler_map[c->type].stop); handler_map[c->type].stop(c); diff --git a/content/content.h b/content/content.h index 478e16b9e..16ad6f764 100644 --- a/content/content.h +++ b/content/content.h @@ -92,11 +92,8 @@ #ifndef _NETSURF_DESKTOP_CONTENT_H_ #define _NETSURF_DESKTOP_CONTENT_H_ -#include "libxml/HTMLparser.h" #include "netsurf/utils/config.h" -#include "netsurf/content/cache.h" #include "netsurf/content/content_type.h" -#include "netsurf/content/fetch.h" #include "netsurf/css/css.h" #include "netsurf/render/box.h" #include "netsurf/render/font.h" @@ -121,6 +118,9 @@ #endif +struct fetch; + + /** Used in callbacks to indicate what has occurred. */ typedef enum { CONTENT_MSG_LOADING, /**< fetching or converting */ @@ -211,8 +211,12 @@ struct content { #endif } data; - struct cache_entry *cache; /**< Used by cache, 0 if not cached. */ - unsigned long size; /**< Estimated size of all data + /** This content may be given to new users. Indicates that the content + * was fetched using a simple GET, has not expired, and may be + * shared between users. */ + bool fresh; + + unsigned int size; /**< Estimated size of all data associated with this content. */ char *title; /**< Title for browser window. */ unsigned int active; /**< Number of child fetches or @@ -225,8 +229,6 @@ struct content { unsigned long source_size; /**< Amount of data fetched so far. */ unsigned long total_size; /**< Total data size, 0 if unknown. */ - int lock; /**< Content in use, do not destroy. */ - bool destroy_pending; /**< Destroy when lock returns to 0. */ bool no_error_pages; /**< Used by fetchcache(). */ /** Array of first n rendering errors or warnings. */ @@ -250,6 +252,7 @@ struct browser_window; content_type content_lookup(const char *mime_type); struct content * content_create(const char *url); +struct content * content_get(const char *url); bool content_set_type(struct content *c, content_type type, const char *mime_type, const char *params[]); void content_set_status(struct content *c, const char *status_message, ...); @@ -257,7 +260,6 @@ bool content_process_data(struct content *c, char *data, unsigned int size); void content_convert(struct content *c, int width, int height); void content_reformat(struct content *c, int width, int height); void content_clean(void); -void content_destroy(struct content *c); void content_reset(struct content *c); void content_redraw(struct content *c, int x, int y, int width, int height, diff --git a/content/fetchcache.c b/content/fetchcache.c index 1ddd2fe7a..3015f1314 100644 --- a/content/fetchcache.c +++ b/content/fetchcache.c @@ -18,7 +18,6 @@ #include #include #include "netsurf/utils/config.h" -#include "netsurf/content/cache.h" #include "netsurf/content/content.h" #include "netsurf/content/fetchcache.h" #include "netsurf/content/fetch.h" @@ -83,7 +82,7 @@ struct content * fetchcache(const char *url, LOG(("url %s", url1)); if (!post_urlenc && !post_multipart) { - c = cache_get(url1); + c = content_get(url1); if (c) { free(url1); content_add_user(c, callback, p1, p2); @@ -99,7 +98,7 @@ struct content * fetchcache(const char *url, content_add_user(c, callback, p1, p2); if (!post_urlenc && !post_multipart) - cache_put(c); + c->fresh = true; c->width = width; c->height = height; @@ -112,7 +111,7 @@ struct content * fetchcache(const char *url, /** * Start fetching and converting a content. * - * \param url address to fetch + * \param content content to fetch, as returned by fetchcache() * \param referer referring URL, or 0 * \param callback function to call when anything interesting happens to * the new content @@ -204,8 +203,6 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size) unsigned int i; union content_msg_data msg_data; - c->lock++; - switch (msg) { case FETCH_TYPE: c->total_size = size; @@ -217,10 +214,10 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size) for (i = 0; params[i]; i++) free(params[i]); free(params); - if (!res) + if (!res) { fetch_abort(c->fetch); - if (c->cache && c->type == CONTENT_OTHER) - cache_destroy(c); + c->fetch = 0; + } break; case FETCH_DATA: @@ -236,8 +233,10 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size) messages_get("Received"), human_friendly_bytesize(c->source_size + size)); content_broadcast(c, CONTENT_MSG_STATUS, msg_data); - if (!content_process_data(c, data, size)) + if (!content_process_data(c, data, size)) { fetch_abort(c->fetch); + c->fetch = 0; + } break; case FETCH_FINISHED: @@ -252,8 +251,6 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size) case FETCH_ERROR: LOG(("FETCH_ERROR, '%s'", data)); c->fetch = 0; - if (c->cache) - cache_destroy(c); if (c->no_error_pages) { c->status = CONTENT_STATUS_ERROR; msg_data.error = data; @@ -279,9 +276,6 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size) msg_data.error = messages_get("BadRedirect"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); } - if (c->cache) - cache_destroy(c); - content_destroy(c); break; #ifdef WITH_AUTH case FETCH_AUTH: @@ -290,15 +284,11 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size) c->fetch = 0; msg_data.auth_realm = data; content_broadcast(c, CONTENT_MSG_AUTH, msg_data); - if (c->cache) - cache_destroy(c); break; #endif default: assert(0); } - - c->lock--; } -- cgit v1.2.3