summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--content/hlcache.c71
-rw-r--r--content/hlcache.h5
-rw-r--r--content/llcache.c42
-rw-r--r--content/llcache.h5
-rw-r--r--desktop/netsurf.c4
5 files changed, 122 insertions, 5 deletions
diff --git a/content/hlcache.c b/content/hlcache.c
index 49cceb0a2..1fd6fe4ad 100644
--- a/content/hlcache.c
+++ b/content/hlcache.c
@@ -88,6 +88,67 @@ static void hlcache_content_callback(struct content *c,
******************************************************************************/
/* See hlcache.h for documentation */
+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;
+ entry != NULL; entry = entry->next) {
+ num_contents++;
+ }
+
+ /* Drain cache */
+ do {
+ prev_contents = num_contents;
+
+ hlcache_clean();
+
+ for (num_contents = 0, entry = hlcache_content_list;
+ entry != NULL; entry = entry->next) {
+ num_contents++;
+ }
+ } while (num_contents > 0 && num_contents != prev_contents);
+
+ LOG(("%d contents remaining:", num_contents));
+ for (entry = hlcache_content_list; entry != NULL; entry = entry->next) {
+ hlcache_handle entry_handle = { entry, NULL, NULL };
+
+ if (entry->content != NULL) {
+ LOG((" %p : %s", entry,
+ content_get_url(&entry_handle)));
+ } else {
+ LOG((" %p", entry));
+ }
+ }
+
+ /* Clean up retrieval contexts */
+ if (hlcache_retrieval_ctx_ring != NULL) {
+ do {
+ ctx = hlcache_retrieval_ctx_ring;
+ next = ctx->r_next;
+
+ if (ctx->llcache != NULL)
+ llcache_handle_release(ctx->llcache);
+
+ if (ctx->handle != NULL)
+ free(ctx->handle);
+
+ if (ctx->child.charset != NULL)
+ free((char *) ctx->child.charset);
+
+ free(ctx);
+
+ ctx = next;
+ } while (ctx != hlcache_retrieval_ctx_ring);
+
+ hlcache_retrieval_ctx_ring = NULL;
+ }
+}
+
+/* See hlcache.h for documentation */
nserror hlcache_poll(void)
{
llcache_poll();
@@ -304,11 +365,11 @@ void hlcache_clean(void)
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 the cache fits in the
- * configured cache size limit.
+ /** \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.
*/
/* Remove entry from cache */
diff --git a/content/hlcache.h b/content/hlcache.h
index afc755e42..5ed37203d 100644
--- a/content/hlcache.h
+++ b/content/hlcache.h
@@ -64,6 +64,11 @@ enum hlcache_retrieve_flag {
};
/**
+ * Finalise the high-level cache, destroying any remaining contents
+ */
+void hlcache_finalise(void);
+
+/**
* Drive the low-level cache poll loop, and attempt to clean the cache.
* No guarantee is made about what, if any, cache cleaning will occur.
*
diff --git a/content/llcache.c b/content/llcache.c
index d5b518403..33b447570 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -225,6 +225,48 @@ nserror llcache_initialise(llcache_query_callback cb, void *pw)
}
/* See llcache.h for documentation */
+void llcache_finalise(void)
+{
+ llcache_object *object, *next;
+
+ /* Clean uncached objects */
+ for (object = llcache_uncached_objects; object != NULL; object = next) {
+ llcache_object_user *user, *next_user;
+
+ next = object->next;
+
+ for (user = object->users; user != NULL; user = next_user) {
+ next_user = user->next;
+
+ free(user);
+ }
+
+ /* Fetch system has already been destroyed */
+ object->fetch.fetch = NULL;
+
+ llcache_object_destroy(object);
+ }
+
+ /* Clean cached objects */
+ for (object = llcache_cached_objects; object != NULL; object = next) {
+ llcache_object_user *user, *next_user;
+
+ next = object->next;
+
+ for (user = object->users; user != NULL; user = next_user) {
+ next_user = user->next;
+
+ free(user);
+ }
+
+ /* Fetch system has already been destroyed */
+ object->fetch.fetch = NULL;
+
+ llcache_object_destroy(object);
+ }
+}
+
+/* See llcache.h for documentation */
nserror llcache_poll(void)
{
llcache_object *object;
diff --git a/content/llcache.h b/content/llcache.h
index 3a1e32ca9..d7958b056 100644
--- a/content/llcache.h
+++ b/content/llcache.h
@@ -161,6 +161,11 @@ typedef nserror (*llcache_query_callback)(const llcache_query *query, void *pw,
nserror llcache_initialise(llcache_query_callback cb, void *pw);
/**
+ * Finalise the low-level cache
+ */
+void llcache_finalise(void);
+
+/**
* Cause the low-level cache to emit any pending notifications
* and attempt to clean the cache. No guarantee is made about
* what, if any, cache cleaning will occur.
diff --git a/desktop/netsurf.c b/desktop/netsurf.c
index 2ce1012c2..b25209c4f 100644
--- a/desktop/netsurf.c
+++ b/desktop/netsurf.c
@@ -187,6 +187,10 @@ void netsurf_exit(void)
utf8_finalise();
LOG(("Destroying URLdb"));
urldb_destroy();
+ LOG(("Finalising high-level cache"));
+ hlcache_finalise();
+ LOG(("Finalising low-level cache"));
+ llcache_finalise();
LOG(("Exited successfully"));
}