summaryrefslogtreecommitdiff
path: root/content
diff options
context:
space:
mode:
Diffstat (limited to 'content')
-rw-r--r--content/content.c121
-rw-r--r--content/content.h18
-rw-r--r--content/fetchcache.c28
3 files changed, 94 insertions, 73 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--;
}