mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-22 12:12:35 +03:00
[project @ 2004-01-26 14:16:23 by bursa]
Fix crashes related to content_destroy() by adding lock, implement no_error_pages. svn path=/import/netsurf/; revision=508
This commit is contained in:
parent
92941a762d
commit
658084359d
@ -213,6 +213,7 @@ void cache_shrink(void)
|
||||
LOG(("size %lu, removing %p '%s'", size, e->content, e->content->url));
|
||||
/* TODO: move to disc cache */
|
||||
size -= e->content->size;
|
||||
e->content->cache = 0;
|
||||
content_destroy(e->content);
|
||||
unused_list->prev = e->prev;
|
||||
e->prev->next = unused_list;
|
||||
|
@ -195,6 +195,8 @@ struct content * content_create(char *url)
|
||||
user_sentinel->p1 = user_sentinel->p2 = 0;
|
||||
user_sentinel->next = 0;
|
||||
c->user_list = user_sentinel;
|
||||
c->lock = 0;
|
||||
c->destroy_pending = false;
|
||||
return c;
|
||||
}
|
||||
|
||||
@ -326,8 +328,16 @@ void content_reformat(struct content *c, unsigned long width, unsigned long heig
|
||||
void content_destroy(struct content *c)
|
||||
{
|
||||
struct content_user *user, *next;
|
||||
assert(c != 0);
|
||||
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->type < HANDLER_MAP_COUNT)
|
||||
handler_map[c->type].destroy(c);
|
||||
for (user = c->user_list; user != 0; user = next) {
|
||||
@ -435,8 +445,10 @@ void content_remove_user(struct content *c,
|
||||
* 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)
|
||||
if (c->fetch != 0) {
|
||||
fetch_abort(c->fetch);
|
||||
c->fetch = 0;
|
||||
}
|
||||
if (c->status < CONTENT_STATUS_READY) {
|
||||
if (c->cache)
|
||||
cache_destroy(c);
|
||||
@ -444,6 +456,8 @@ void content_remove_user(struct content *c,
|
||||
} else {
|
||||
if (c->cache)
|
||||
cache_freeable(c);
|
||||
else
|
||||
content_destroy(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -457,11 +471,14 @@ void content_broadcast(struct content *c, content_msg msg, char *error)
|
||||
{
|
||||
struct content_user *user, *next;
|
||||
LOG(("content %s, message %i", c->url, msg));
|
||||
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, error);
|
||||
}
|
||||
if (--(c->lock) == 0 && c->destroy_pending)
|
||||
content_destroy(c);
|
||||
}
|
||||
|
||||
|
||||
|
@ -139,6 +139,10 @@ struct content {
|
||||
struct fetch *fetch; /**< Associated fetch, or 0. */
|
||||
unsigned long fetch_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(). */
|
||||
};
|
||||
|
||||
|
||||
|
@ -44,13 +44,28 @@ static void fetchcache_error_page(struct content *c, const char *error);
|
||||
*
|
||||
* If an error occurs immediately, 0 may be returned. Later errors will be
|
||||
* reported via the callback.
|
||||
*
|
||||
* \param url address to fetch
|
||||
* \param referer url of referring page, or 0 if none
|
||||
* \param callback function to call when anything interesting happens to
|
||||
* the new content
|
||||
* \param p1 user parameter for callback
|
||||
* \param p2 user parameter for callback
|
||||
* \param width available space
|
||||
* \param height available space
|
||||
* \param no_error_pages if an error occurs, send CONTENT_MSG_ERROR instead
|
||||
* of generating an error page
|
||||
* \param post_urlenc url encoded post data, or 0 if none
|
||||
* \param post_multipart multipart post data, or 0 if none
|
||||
* \param cookies send and accept cookies
|
||||
* \return a new content, or 0 if an error occurred and no_error_pages is true
|
||||
*/
|
||||
|
||||
struct content * fetchcache(const char *url0, char *referer,
|
||||
struct content * fetchcache(const char *url, char *referer,
|
||||
void (*callback)(content_msg msg, struct content *c, void *p1,
|
||||
void *p2, const char *error),
|
||||
void *p1, void *p2, unsigned long width, unsigned long height,
|
||||
bool only_2xx
|
||||
bool no_error_pages
|
||||
#ifdef WITH_POST
|
||||
, char *post_urlenc,
|
||||
struct form_successful_control *post_multipart
|
||||
@ -61,8 +76,8 @@ struct content * fetchcache(const char *url0, char *referer,
|
||||
)
|
||||
{
|
||||
struct content *c;
|
||||
char *url = xstrdup(url0);
|
||||
char *hash = strchr(url, '#');
|
||||
char *url1 = xstrdup(url);
|
||||
char *hash = strchr(url1, '#');
|
||||
const char *params[] = { 0 };
|
||||
char error_message[500];
|
||||
|
||||
@ -70,21 +85,21 @@ struct content * fetchcache(const char *url0, char *referer,
|
||||
if (hash != 0)
|
||||
*hash = 0;
|
||||
|
||||
LOG(("url %s", url));
|
||||
LOG(("url %s", url1));
|
||||
|
||||
#ifdef WITH_POST
|
||||
if (!post_urlenc && !post_multipart)
|
||||
#endif
|
||||
{
|
||||
c = cache_get(url);
|
||||
c = cache_get(url1);
|
||||
if (c != 0) {
|
||||
free(url);
|
||||
free(url1);
|
||||
content_add_user(c, callback, p1, p2);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
c = content_create(url);
|
||||
c = content_create(url1);
|
||||
content_add_user(c, callback, p1, p2);
|
||||
|
||||
#ifdef WITH_POST
|
||||
@ -95,7 +110,8 @@ struct content * fetchcache(const char *url0, char *referer,
|
||||
c->fetch_size = 0;
|
||||
c->width = width;
|
||||
c->height = height;
|
||||
c->fetch = fetch_start(url, referer, fetchcache_callback, c, only_2xx
|
||||
c->no_error_pages = no_error_pages;
|
||||
c->fetch = fetch_start(url1, referer, fetchcache_callback, c, no_error_pages
|
||||
#ifdef WITH_POST
|
||||
,post_urlenc, post_multipart
|
||||
#endif
|
||||
@ -107,11 +123,16 @@ struct content * fetchcache(const char *url0, char *referer,
|
||||
LOG(("warning: fetch_start failed"));
|
||||
if (c->cache)
|
||||
cache_destroy(c);
|
||||
if (no_error_pages) {
|
||||
content_destroy(c);
|
||||
free(url1);
|
||||
return 0;
|
||||
}
|
||||
snprintf(error_message, sizeof error_message,
|
||||
messages_get("InvalidURL"), url);
|
||||
messages_get("InvalidURL"), url1);
|
||||
fetchcache_error_page(c, error_message);
|
||||
}
|
||||
free(url);
|
||||
free(url1);
|
||||
return c;
|
||||
}
|
||||
|
||||
@ -130,6 +151,8 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size)
|
||||
char **params;
|
||||
unsigned int i;
|
||||
|
||||
c->lock++;
|
||||
|
||||
switch (msg) {
|
||||
case FETCH_TYPE:
|
||||
c->total_size = size;
|
||||
@ -167,11 +190,15 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size)
|
||||
case FETCH_ERROR:
|
||||
LOG(("FETCH_ERROR, '%s'", data));
|
||||
c->fetch = 0;
|
||||
/* content_broadcast(c, CONTENT_MSG_ERROR, data); */
|
||||
if (c->cache)
|
||||
cache_destroy(c);
|
||||
content_reset(c);
|
||||
fetchcache_error_page(c, data);
|
||||
if (c->no_error_pages) {
|
||||
content_broadcast(c, CONTENT_MSG_ERROR, data);
|
||||
content_destroy(c);
|
||||
} else {
|
||||
content_reset(c);
|
||||
fetchcache_error_page(c, data);
|
||||
}
|
||||
break;
|
||||
|
||||
case FETCH_REDIRECT:
|
||||
@ -202,6 +229,9 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size)
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (--(c->lock) == 0 && c->destroy_pending)
|
||||
content_destroy(c);
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@ struct content * fetchcache(const char *url, char *referer,
|
||||
void (*callback)(content_msg msg, struct content *c, void *p1,
|
||||
void *p2, const char *error),
|
||||
void *p1, void *p2, unsigned long width, unsigned long height,
|
||||
bool only_2xx
|
||||
bool no_error_pages
|
||||
#ifdef WITH_POST
|
||||
, char *post_urlenc,
|
||||
struct form_successful_control *post_multipart
|
||||
|
Loading…
Reference in New Issue
Block a user