diff options
-rw-r--r-- | content/content.c | 121 | ||||
-rw-r--r-- | content/content.h | 18 | ||||
-rw-r--r-- | content/fetchcache.c | 28 | ||||
-rw-r--r-- | debug/netsurfd.c | 5 | ||||
-rw-r--r-- | desktop/browser.h | 1 | ||||
-rw-r--r-- | desktop/netsurf.c | 3 | ||||
-rw-r--r-- | desktop/options.c | 8 | ||||
-rw-r--r-- | desktop/options.h | 1 | ||||
-rw-r--r-- | makefile | 6 | ||||
-rw-r--r-- | render/html.c | 13 | ||||
-rw-r--r-- | riscos/debugwin.c | 29 | ||||
-rw-r--r-- | riscos/window.c | 4 |
12 files changed, 136 insertions, 101 deletions
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 <string.h> #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; @@ -268,6 +269,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. * * \param c content structure @@ -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 <sys/types.h> #include <regex.h> #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--; } diff --git a/debug/netsurfd.c b/debug/netsurfd.c index b2b618bce..c539e2df0 100644 --- a/debug/netsurfd.c +++ b/debug/netsurfd.c @@ -10,7 +10,6 @@ #include <string.h> #include "netsurf/utils/config.h" #include "netsurf/content/fetch.h" -#include "netsurf/content/cache.h" #include "netsurf/content/content.h" #include "netsurf/content/fetchcache.h" #include "netsurf/desktop/options.h" @@ -45,7 +44,6 @@ int main(int argc, char *argv[]) struct content *c; fetch_init(); - cache_init(); fetchcache_init(); url_init(); save_complete_init(); @@ -70,7 +68,6 @@ int main(int argc, char *argv[]) destroyed = 1; puts("=== FAILURE, dumping cache"); } - cache_dump(); if (!destroyed) { /*while (1) schedule_run();*/ @@ -85,10 +82,10 @@ int main(int argc, char *argv[]) content_remove_user(c, callback, 0, 0); c = 0; } + content_clean(); } /* options_write("options"); */ - cache_quit(); fetch_quit(); return 0; diff --git a/desktop/browser.h b/desktop/browser.h index 9ebcd11fd..34f759102 100644 --- a/desktop/browser.h +++ b/desktop/browser.h @@ -21,6 +21,7 @@ struct box; struct history; +struct form_successful_control; /** Browser window data. */ struct browser_window diff --git a/desktop/netsurf.c b/desktop/netsurf.c index d04d35621..55020354f 100644 --- a/desktop/netsurf.c +++ b/desktop/netsurf.c @@ -11,7 +11,6 @@ #include <stdlib.h> #include <sys/utsname.h> #include "netsurf/utils/config.h" -#include "netsurf/content/cache.h" #include "netsurf/content/fetch.h" #include "netsurf/content/fetchcache.h" #include "netsurf/desktop/options.h" @@ -72,7 +71,6 @@ void netsurf_init(int argc, char** argv) gui_init(argc, argv); setlocale(LC_ALL, ""); fetch_init(); - cache_init(); fetchcache_init(); url_init(); } @@ -96,7 +94,6 @@ void netsurf_poll(void) void netsurf_exit(void) { - cache_quit(); fetch_quit(); gui_quit(); } diff --git a/desktop/options.c b/desktop/options.c index 1748fc6b1..6b8975f5d 100644 --- a/desktop/options.c +++ b/desktop/options.c @@ -41,8 +41,10 @@ int option_font_size = 100; int option_font_min_size = 70; /** Accept-Language header. */ char *option_accept_language = 0; -/** Strict verification of SSL sertificates */ +/** Enable verification of SSL certificates. */ bool option_ssl_verify_certificates = true; +/** Preferred maximum size of memory cache / bytes. */ +int option_memory_cache_size = 2 * 1024 * 1024; EXTRA_OPTION_DEFINE @@ -59,6 +61,7 @@ struct { { "font_min_size", OPTION_INTEGER, &option_font_min_size }, { "accept_language", OPTION_STRING, &option_accept_language }, { "ssl_verify_certificates", OPTION_BOOL, &option_ssl_verify_certificates }, + { "memory_cache_size", OPTION_STRING, &option_memory_cache_size }, EXTRA_OPTION_TABLE }; @@ -133,6 +136,9 @@ void options_read(const char *path) option_font_min_size = 10; if (500 < option_font_min_size) option_font_min_size = 500; + + if (option_memory_cache_size < 0) + option_memory_cache_size = 0; } diff --git a/desktop/options.h b/desktop/options.h index efec32f33..a4f0de038 100644 --- a/desktop/options.h +++ b/desktop/options.h @@ -31,6 +31,7 @@ extern int option_font_size; extern int option_font_min_size; extern char *option_accept_language; extern bool option_ssl_verify_certificates; +extern int option_memory_cache_size; void options_read(const char *path); void options_write(const char *path); @@ -16,7 +16,7 @@ # "riscos", "riscos_small", and "riscos_debug" can be compiled under RISC OS, # or cross-compiled using gccsdk. -OBJECTS_COMMON = cache.o content.o fetch.o fetchcache.o # content/ +OBJECTS_COMMON = content.o fetch.o fetchcache.o # content/ OBJECTS_COMMON += css.o css_enum.o parser.o ruleset.o scanner.o # css/ OBJECTS_COMMON += box.o form.o html.o layout.o textplain.o # render/ OBJECTS_COMMON += messages.o pool.o translit.o url.o utils.o # utils/ @@ -24,7 +24,7 @@ OBJECTS_COMMON += imagemap.o loginlist.o options.o # desktop/ OBJECTS_RISCOS = $(OBJECTS_COMMON) OBJECTS_RISCOS += browser.o netsurf.o version.o # desktop/ -OBJECTS_RISCOS += 401login.o about.o constdata.o debugwin.o \ +OBJECTS_RISCOS += 401login.o constdata.o debugwin.o \ dialog.o download.o draw.o filetype.o font.o gif.o \ gifread.o gui.o help.o history.o htmlinstance.o \ htmlredraw.o jpeg.o menus.o mouseactions.o plugin.o \ @@ -40,7 +40,7 @@ OBJECTS_DEBUG += gif.o gifread.o jpeg.o png.o save_complete.o schedule.o \ OBJECTS_DEBUGRO = $(OBJECTS_COMMON) OBJECTS_DEBUGRO += netsurfd.o # debug/ OBJECTS_DEBUGRO += version.o # desktop/ -OBJECTS_DEBUGRO += about.o constdata.o draw.o filetype.o font.o \ +OBJECTS_DEBUGRO += constdata.o draw.o filetype.o font.o \ gif.o gifread.o jpeg.o png.o save_complete.o schedule.o \ sprite.o theme.o toolbar.o wimp.o # riscos/ diff --git a/render/html.c b/render/html.c index a96869313..6a63bfdda 100644 --- a/render/html.c +++ b/render/html.c @@ -840,14 +840,13 @@ void html_destroy(struct content *c) /* Free stylesheets */ if (c->data.html.stylesheet_count) { - content_remove_user(c->data.html.stylesheet_content[0], - html_convert_css_callback, c, 0); - if (c->data.html.stylesheet_content[1]) - content_destroy(c->data.html.stylesheet_content[1]); - for (i = 2; i != c->data.html.stylesheet_count; i++) + for (i = 0; i != c->data.html.stylesheet_count; i++) { if (c->data.html.stylesheet_content[i]) - content_remove_user(c->data.html.stylesheet_content[i], - html_convert_css_callback, c, (void*)i); + content_remove_user(c->data.html. + stylesheet_content[i], + html_convert_css_callback, + c, (void *) i); + } } free(c->data.html.stylesheet_content); free(c->data.html.style); diff --git a/riscos/debugwin.c b/riscos/debugwin.c index b45eb5217..8f9496150 100644 --- a/riscos/debugwin.c +++ b/riscos/debugwin.c @@ -14,6 +14,8 @@ #include "netsurf/utils/log.h" #include "netsurf/utils/utils.h" +/** Update interval / cs. */ +#define DEBUGWIN_UPDATE 500 static void ro_gui_debugwin_resize(void); static void ro_gui_debugwin_update(void *p); @@ -24,13 +26,13 @@ void ro_gui_debugwin_open(void) { ro_gui_debugwin_resize(); ro_gui_dialog_open(dialog_debug); - schedule(100, ro_gui_debugwin_update, 0); + schedule(DEBUGWIN_UPDATE, ro_gui_debugwin_update, 0); } void ro_gui_debugwin_resize(void) { - unsigned int count = 1; + unsigned int count = 2; struct content *content; os_box box; os_error *error; @@ -61,7 +63,7 @@ void ro_gui_debugwin_update(void *p) error->errnum, error->errmess)); warn_user("WimpError", error->errmess); } - schedule(100, ro_gui_debugwin_update, 0); + schedule(DEBUGWIN_UPDATE, ro_gui_debugwin_update, 0); } @@ -105,17 +107,22 @@ void ro_gui_debugwin_redraw(wimp_draw *redraw) void ro_gui_debugwin_redraw_plot(wimp_draw *redraw) { - char size[20]; + char s[20]; int x0 = redraw->box.x0 - redraw->xscroll; int y0 = redraw->box.y1 - redraw->yscroll; int i = 1; int y; + unsigned int users; + unsigned int size = 0; struct content *content; + struct content_user *user; xwimp_set_font_colours(wimp_COLOUR_BLACK, wimp_COLOUR_LIGHT_GREY); xwimptextop_paint(0, "url", x0 + 4, y0 - 20); xwimptextop_paint(0, "type", x0 + 600, y0 - 20); + xwimptextop_paint(0, "fresh", x0 + 680, y0 - 20); xwimptextop_paint(0, "mime_type", x0 + 750, y0 - 20); + xwimptextop_paint(0, "users", x0 + 880, y0 - 20); xwimptextop_paint(0, "status", x0 + 950, y0 - 20); xwimptextop_paint(0, "size", x0 + 1100, y0 - 20); @@ -126,12 +133,22 @@ void ro_gui_debugwin_redraw_plot(wimp_draw *redraw) x0 + 580, y); xwimptextop_paint(0, content_type_name[content->type], x0 + 600, y); + xwimptextop_paint(0, content->fresh ? "" : "", + x0 + 710, y); if (content->mime_type) xwimptextop_paint(0, content->mime_type, x0 + 750, y); + users = 0; + for (user = content->user_list->next; user; user = user->next) + users++; + snprintf(s, sizeof s, "%u", users); + xwimptextop_paint(wimptextop_RJUSTIFY, s, x0 + 930, y); xwimptextop_paint(0, content_status_name[content->status], x0 + 950, y); - snprintf(size, sizeof size, "%lu", content->size); - xwimptextop_paint(0, size, x0 + 1100, y); + snprintf(s, sizeof s, "%u", content->size); + xwimptextop_paint(wimptextop_RJUSTIFY, s, x0 + 1190, y); + size += content->size; } + snprintf(s, sizeof s, "%u", size); + xwimptextop_paint(wimptextop_RJUSTIFY, s, x0 + 1190, y0 - i * 28 - 20); } diff --git a/riscos/window.c b/riscos/window.c index dbce523dc..738428314 100644 --- a/riscos/window.c +++ b/riscos/window.c @@ -885,10 +885,6 @@ bool ro_gui_window_keypress(gui_window *g, int key, bool toolbar) } return true; - case wimp_KEY_F10: /* Dump cache for debugging. */ - cache_dump(); - return true; - case wimp_KEY_F11: /* Toggle display of box outlines. */ gui_redraw_debug = !gui_redraw_debug; gui_window_redraw_window(g); |